max instruction optimized out after shader code compiling

I am puzzled about the intelligence of shader compiling.
here is my shader snippet, it is used to compute anistropic specular lighting.
Sorry , there are too many parentheses ,but just Focus on the last 2 lines.
The line that begins with " half s_den" contains 2 “max” instructions. They have the same parameter (0.001) each.

half len=max(0.001,length(((L)+(V))));
half3 H=((((L)+(V)))/(len));
half NoV=max(0.001,dot(V,N));
half NoH=dot(H,N);
half HoT=dot(H,Tangent);
half HoB=dot(H,Binormal);
half2 beta=half2(((HoT)/(RoughnessX)),((HoB)/(RoughnessY)));
(beta)*=(beta);
half s_den=max(0.001,((((((314.15926)*(RoughnessX)))*(RoughnessY)))*(max(0.001,sqrt(((NoL)*(NoV)))))));
half aniso=((exp((((-(((beta.x)+(beta.y)))))/(max(0.01,((0.5)+(((0.5)*(NoH+0.3)))))))))/(s_den));

Click the “compile and show code” button , I find the compiled gles3 code ralated to the “max” line.

u_xlat16_27 = sqrt(u_xlat16_27);
u_xlat16_15.x = u_xlat16_27 * u_xlat16_15.x;
u_xlat16_15.x = max(u_xlat16_15.x, 0.00100000005);
u_xlat16_3.x = u_xlat16_3.x / u_xlat16_15.x;

the variable “u_xlat16_27” that computed by “sqrt” funcion, is supposed to excute a “max” instruction, before the subsequent multiply by “u_xlat16_15.x”.
however , it seems that unity compiler omits the second “max” funcion.
the result on the mobile shows wrong rendering.

then ,after making some tries, I find out assigning slightly different values to “max” function works fine sometimes.

half s_den=max(0.001,((((((314.15926)*(RoughnessX)))*(RoughnessY)))*(max(0.0011,sqrt(((NoL)*(NoV)))))));

the following code is the compiled gles3 snippet.

u_xlat16_27 = sqrt(u_xlat16_27);
u_xlat16_27 = max(u_xlat16_27, 0.00109999999);
u_xlat16_15.x = u_xlat16_27 * u_xlat16_15.x;
u_xlat16_15.x = max(u_xlat16_15.x, 0.00100000005);
u_xlat16_3.x = u_xlat16_3.x / u_xlat16_15.x;

here , we see there are 2 “max” instructions in the gles3 code, and the mobile result is correct.

How can I avoid the problem alike happening.
Is there some compiling regulations to follow.
my unity is 2018.4.5f1.
thanks ~

Hi!
Please submit a bug report, we’ll take a look :slight_smile:

I think “sometimes” is the key here, this looks to be more of a precision loss problem depending on the order of operations. Check if your code works with full precision instead of half.