1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; testing-case "float fold(float a) { return 1.2f * a * 2.3f; }" 4*9880d681SAndroid Build Coastguard Worker; 1.2f and 2.3f is supposed to be fold. 5*9880d681SAndroid Build Coastguard Workerdefine float @fold(float %a) { 6*9880d681SAndroid Build Coastguard Worker %mul = fmul fast float %a, 0x3FF3333340000000 7*9880d681SAndroid Build Coastguard Worker %mul1 = fmul fast float %mul, 0x4002666660000000 8*9880d681SAndroid Build Coastguard Worker ret float %mul1 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold( 10*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %a, 0x4006147AE0000000 11*9880d681SAndroid Build Coastguard Worker} 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker; Same testing-case as the one used in fold() except that the operators have 14*9880d681SAndroid Build Coastguard Worker; fixed FP mode. 15*9880d681SAndroid Build Coastguard Workerdefine float @notfold(float %a) { 16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @notfold( 17*9880d681SAndroid Build Coastguard Worker; CHECK: %mul = fmul fast float %a, 0x3FF3333340000000 18*9880d681SAndroid Build Coastguard Worker %mul = fmul fast float %a, 0x3FF3333340000000 19*9880d681SAndroid Build Coastguard Worker %mul1 = fmul float %mul, 0x4002666660000000 20*9880d681SAndroid Build Coastguard Worker ret float %mul1 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Workerdefine float @fold2(float %a) { 24*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold2( 25*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %a, 0x4006147AE0000000 26*9880d681SAndroid Build Coastguard Worker %mul = fmul float %a, 0x3FF3333340000000 27*9880d681SAndroid Build Coastguard Worker %mul1 = fmul fast float %mul, 0x4002666660000000 28*9880d681SAndroid Build Coastguard Worker ret float %mul1 29*9880d681SAndroid Build Coastguard Worker} 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker; C * f1 + f1 = (C+1) * f1 32*9880d681SAndroid Build Coastguard Workerdefine double @fold3(double %f1) { 33*9880d681SAndroid Build Coastguard Worker %t1 = fmul fast double 2.000000e+00, %f1 34*9880d681SAndroid Build Coastguard Worker %t2 = fadd fast double %f1, %t1 35*9880d681SAndroid Build Coastguard Worker ret double %t2 36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold3( 37*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast double %f1, 3.000000e+00 38*9880d681SAndroid Build Coastguard Worker} 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker; (C1 - X) + (C2 - Y) => (C1+C2) - (X + Y) 41*9880d681SAndroid Build Coastguard Workerdefine float @fold4(float %f1, float %f2) { 42*9880d681SAndroid Build Coastguard Worker %sub = fsub float 4.000000e+00, %f1 43*9880d681SAndroid Build Coastguard Worker %sub1 = fsub float 5.000000e+00, %f2 44*9880d681SAndroid Build Coastguard Worker %add = fadd fast float %sub, %sub1 45*9880d681SAndroid Build Coastguard Worker ret float %add 46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold4( 47*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = fadd fast float %f1, %f2 48*9880d681SAndroid Build Coastguard Worker; CHECK: fsub fast float 9.000000e+00, %1 49*9880d681SAndroid Build Coastguard Worker} 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker; (X + C1) + C2 => X + (C1 + C2) 52*9880d681SAndroid Build Coastguard Workerdefine float @fold5(float %f1, float %f2) { 53*9880d681SAndroid Build Coastguard Worker %add = fadd float %f1, 4.000000e+00 54*9880d681SAndroid Build Coastguard Worker %add1 = fadd fast float %add, 5.000000e+00 55*9880d681SAndroid Build Coastguard Worker ret float %add1 56*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold5( 57*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float %f1, 9.000000e+00 58*9880d681SAndroid Build Coastguard Worker} 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker; (X + X) + X => 3.0 * X 61*9880d681SAndroid Build Coastguard Workerdefine float @fold6(float %f1) { 62*9880d681SAndroid Build Coastguard Worker %t1 = fadd fast float %f1, %f1 63*9880d681SAndroid Build Coastguard Worker %t2 = fadd fast float %f1, %t1 64*9880d681SAndroid Build Coastguard Worker ret float %t2 65*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold6( 66*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %f1, 3.000000e+00 67*9880d681SAndroid Build Coastguard Worker} 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; C1 * X + (X + X) = (C1 + 2) * X 70*9880d681SAndroid Build Coastguard Workerdefine float @fold7(float %f1) { 71*9880d681SAndroid Build Coastguard Worker %t1 = fmul fast float %f1, 5.000000e+00 72*9880d681SAndroid Build Coastguard Worker %t2 = fadd fast float %f1, %f1 73*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %t1, %t2 74*9880d681SAndroid Build Coastguard Worker ret float %t3 75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold7( 76*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %f1, 7.000000e+00 77*9880d681SAndroid Build Coastguard Worker} 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker; (X + X) + (X + X) => 4.0 * X 80*9880d681SAndroid Build Coastguard Workerdefine float @fold8(float %f1) { 81*9880d681SAndroid Build Coastguard Worker %t1 = fadd fast float %f1, %f1 82*9880d681SAndroid Build Coastguard Worker %t2 = fadd fast float %f1, %f1 83*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %t1, %t2 84*9880d681SAndroid Build Coastguard Worker ret float %t3 85*9880d681SAndroid Build Coastguard Worker; CHECK: fold8 86*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %f1, 4.000000e+00 87*9880d681SAndroid Build Coastguard Worker} 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker; X - (X + Y) => 0 - Y 90*9880d681SAndroid Build Coastguard Workerdefine float @fold9(float %f1, float %f2) { 91*9880d681SAndroid Build Coastguard Worker %t1 = fadd float %f1, %f2 92*9880d681SAndroid Build Coastguard Worker %t3 = fsub fast float %f1, %t1 93*9880d681SAndroid Build Coastguard Worker ret float %t3 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold9( 96*9880d681SAndroid Build Coastguard Worker; CHECK: fsub fast float -0.000000e+00, %f2 97*9880d681SAndroid Build Coastguard Worker} 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Worker; Let C3 = C1 + C2. (f1 + C1) + (f2 + C2) => (f1 + f2) + C3 instead of 100*9880d681SAndroid Build Coastguard Worker; "(f1 + C3) + f2" or "(f2 + C3) + f1". Placing constant-addend at the 101*9880d681SAndroid Build Coastguard Worker; top of resulting simplified expression tree may potentially reveal some 102*9880d681SAndroid Build Coastguard Worker; optimization opportunities in the super-expression trees. 103*9880d681SAndroid Build Coastguard Worker; 104*9880d681SAndroid Build Coastguard Workerdefine float @fold10(float %f1, float %f2) { 105*9880d681SAndroid Build Coastguard Worker %t1 = fadd fast float 2.000000e+00, %f1 106*9880d681SAndroid Build Coastguard Worker %t2 = fsub fast float %f2, 3.000000e+00 107*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %t1, %t2 108*9880d681SAndroid Build Coastguard Worker ret float %t3 109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fold10( 110*9880d681SAndroid Build Coastguard Worker; CHECK: %t3 = fadd fast float %t2, -1.000000e+00 111*9880d681SAndroid Build Coastguard Worker; CHECK: ret float %t3 112*9880d681SAndroid Build Coastguard Worker} 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker; once cause Crash/miscompilation 115*9880d681SAndroid Build Coastguard Workerdefine float @fail1(float %f1, float %f2) { 116*9880d681SAndroid Build Coastguard Worker %conv3 = fadd fast float %f1, -1.000000e+00 117*9880d681SAndroid Build Coastguard Worker %add = fadd fast float %conv3, %conv3 118*9880d681SAndroid Build Coastguard Worker %add2 = fadd fast float %add, %conv3 119*9880d681SAndroid Build Coastguard Worker ret float %add2 120*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fail1( 121*9880d681SAndroid Build Coastguard Worker; CHECK: ret 122*9880d681SAndroid Build Coastguard Worker} 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Workerdefine double @fail2(double %f1, double %f2) { 125*9880d681SAndroid Build Coastguard Worker %t1 = fsub fast double %f1, %f2 126*9880d681SAndroid Build Coastguard Worker %t2 = fadd fast double %f1, %f2 127*9880d681SAndroid Build Coastguard Worker %t3 = fsub fast double %t1, %t2 128*9880d681SAndroid Build Coastguard Worker ret double %t3 129*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fail2( 130*9880d681SAndroid Build Coastguard Worker; CHECK: ret 131*9880d681SAndroid Build Coastguard Worker} 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker; c1 * x - x => (c1 - 1.0) * x 134*9880d681SAndroid Build Coastguard Workerdefine float @fold13(float %x) { 135*9880d681SAndroid Build Coastguard Worker %mul = fmul fast float %x, 7.000000e+00 136*9880d681SAndroid Build Coastguard Worker %sub = fsub fast float %mul, %x 137*9880d681SAndroid Build Coastguard Worker ret float %sub 138*9880d681SAndroid Build Coastguard Worker; CHECK: fold13 139*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %x, 6.000000e+00 140*9880d681SAndroid Build Coastguard Worker; CHECK: ret 141*9880d681SAndroid Build Coastguard Worker} 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker; -x + y => y - x 144*9880d681SAndroid Build Coastguard Workerdefine float @fold14(float %x, float %y) { 145*9880d681SAndroid Build Coastguard Worker %neg = fsub fast float -0.0, %x 146*9880d681SAndroid Build Coastguard Worker %add = fadd fast float %neg, %y 147*9880d681SAndroid Build Coastguard Worker ret float %add 148*9880d681SAndroid Build Coastguard Worker; CHECK: fold14 149*9880d681SAndroid Build Coastguard Worker; CHECK: fsub fast float %y, %x 150*9880d681SAndroid Build Coastguard Worker; CHECK: ret 151*9880d681SAndroid Build Coastguard Worker} 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker; x + -y => x - y 154*9880d681SAndroid Build Coastguard Workerdefine float @fold15(float %x, float %y) { 155*9880d681SAndroid Build Coastguard Worker %neg = fsub fast float -0.0, %y 156*9880d681SAndroid Build Coastguard Worker %add = fadd fast float %x, %neg 157*9880d681SAndroid Build Coastguard Worker ret float %add 158*9880d681SAndroid Build Coastguard Worker; CHECK: fold15 159*9880d681SAndroid Build Coastguard Worker; CHECK: fsub fast float %x, %y 160*9880d681SAndroid Build Coastguard Worker; CHECK: ret 161*9880d681SAndroid Build Coastguard Worker} 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Worker; (select X+Y, X-Y) => X + (select Y, -Y) 164*9880d681SAndroid Build Coastguard Workerdefine float @fold16(float %x, float %y) { 165*9880d681SAndroid Build Coastguard Worker %cmp = fcmp ogt float %x, %y 166*9880d681SAndroid Build Coastguard Worker %plus = fadd fast float %x, %y 167*9880d681SAndroid Build Coastguard Worker %minus = fsub fast float %x, %y 168*9880d681SAndroid Build Coastguard Worker %r = select i1 %cmp, float %plus, float %minus 169*9880d681SAndroid Build Coastguard Worker ret float %r 170*9880d681SAndroid Build Coastguard Worker; CHECK: fold16 171*9880d681SAndroid Build Coastguard Worker; CHECK: fsub fast float 172*9880d681SAndroid Build Coastguard Worker; CHECK: select 173*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float 174*9880d681SAndroid Build Coastguard Worker; CHECK: ret 175*9880d681SAndroid Build Coastguard Worker} 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker; ========================================================================= 180*9880d681SAndroid Build Coastguard Worker; 181*9880d681SAndroid Build Coastguard Worker; Testing-cases about fmul begin 182*9880d681SAndroid Build Coastguard Worker; 183*9880d681SAndroid Build Coastguard Worker; ========================================================================= 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Worker; ((X*C1) + C2) * C3 => (X * (C1*C3)) + (C2*C3) (i.e. distribution) 186*9880d681SAndroid Build Coastguard Workerdefine float @fmul_distribute1(float %f1) { 187*9880d681SAndroid Build Coastguard Worker %t1 = fmul float %f1, 6.0e+3 188*9880d681SAndroid Build Coastguard Worker %t2 = fadd float %t1, 2.0e+3 189*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast float %t2, 5.0e+3 190*9880d681SAndroid Build Coastguard Worker ret float %t3 191*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul_distribute1( 192*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = fmul fast float %f1, 3.000000e+07 193*9880d681SAndroid Build Coastguard Worker; CHECK: %t3 = fadd fast float %1, 1.000000e+07 194*9880d681SAndroid Build Coastguard Worker} 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker; (X/C1 + C2) * C3 => X/(C1/C3) + C2*C3 197*9880d681SAndroid Build Coastguard Workerdefine double @fmul_distribute2(double %f1, double %f2) { 198*9880d681SAndroid Build Coastguard Worker %t1 = fdiv double %f1, 3.0e+0 199*9880d681SAndroid Build Coastguard Worker %t2 = fadd double %t1, 5.0e+1 200*9880d681SAndroid Build Coastguard Worker ; 0x10000000000000 = DBL_MIN 201*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast double %t2, 0x10000000000000 202*9880d681SAndroid Build Coastguard Worker ret double %t3 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul_distribute2( 205*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = fdiv fast double %f1, 0x7FE8000000000000 206*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast double %1, 0x69000000000000 207*9880d681SAndroid Build Coastguard Worker} 208*9880d681SAndroid Build Coastguard Worker 209*9880d681SAndroid Build Coastguard Worker; 5.0e-1 * DBL_MIN yields denormal, so "(f1*3.0 + 5.0e-1) * DBL_MIN" cannot 210*9880d681SAndroid Build Coastguard Worker; be simplified into f1 * (3.0*DBL_MIN) + (5.0e-1*DBL_MIN) 211*9880d681SAndroid Build Coastguard Workerdefine double @fmul_distribute3(double %f1) { 212*9880d681SAndroid Build Coastguard Worker %t1 = fdiv double %f1, 3.0e+0 213*9880d681SAndroid Build Coastguard Worker %t2 = fadd double %t1, 5.0e-1 214*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast double %t2, 0x10000000000000 215*9880d681SAndroid Build Coastguard Worker ret double %t3 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul_distribute3( 218*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast double %t2, 0x10000000000000 219*9880d681SAndroid Build Coastguard Worker} 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Worker; ((X*C1) + C2) * C3 => (X * (C1*C3)) + (C2*C3) (i.e. distribution) 222*9880d681SAndroid Build Coastguard Workerdefine float @fmul_distribute4(float %f1) { 223*9880d681SAndroid Build Coastguard Worker %t1 = fmul float %f1, 6.0e+3 224*9880d681SAndroid Build Coastguard Worker %t2 = fsub float 2.0e+3, %t1 225*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast float %t2, 5.0e+3 226*9880d681SAndroid Build Coastguard Worker ret float %t3 227*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul_distribute4( 228*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = fmul fast float %f1, 3.000000e+07 229*9880d681SAndroid Build Coastguard Worker; CHECK: %t3 = fsub fast float 1.000000e+07, %1 230*9880d681SAndroid Build Coastguard Worker} 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Worker; C1/X * C2 => (C1*C2) / X 233*9880d681SAndroid Build Coastguard Workerdefine float @fmul2(float %f1) { 234*9880d681SAndroid Build Coastguard Worker %t1 = fdiv float 2.0e+3, %f1 235*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast float %t1, 6.0e+3 236*9880d681SAndroid Build Coastguard Worker ret float %t3 237*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul2( 238*9880d681SAndroid Build Coastguard Worker; CHECK: fdiv fast float 1.200000e+07, %f1 239*9880d681SAndroid Build Coastguard Worker} 240*9880d681SAndroid Build Coastguard Worker 241*9880d681SAndroid Build Coastguard Worker; X/C1 * C2 => X * (C2/C1) is disabled if X/C1 has multiple uses 242*9880d681SAndroid Build Coastguard Worker@fmul2_external = external global float 243*9880d681SAndroid Build Coastguard Workerdefine float @fmul2_disable(float %f1) { 244*9880d681SAndroid Build Coastguard Worker %div = fdiv fast float 1.000000e+00, %f1 245*9880d681SAndroid Build Coastguard Worker store float %div, float* @fmul2_external 246*9880d681SAndroid Build Coastguard Worker %mul = fmul fast float %div, 2.000000e+00 247*9880d681SAndroid Build Coastguard Worker ret float %mul 248*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul2_disable 249*9880d681SAndroid Build Coastguard Worker; CHECK: store 250*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast 251*9880d681SAndroid Build Coastguard Worker} 252*9880d681SAndroid Build Coastguard Worker 253*9880d681SAndroid Build Coastguard Worker; X/C1 * C2 => X * (C2/C1) (if C2/C1 is normal Fp) 254*9880d681SAndroid Build Coastguard Workerdefine float @fmul3(float %f1, float %f2) { 255*9880d681SAndroid Build Coastguard Worker %t1 = fdiv float %f1, 2.0e+3 256*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast float %t1, 6.0e+3 257*9880d681SAndroid Build Coastguard Worker ret float %t3 258*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul3( 259*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %f1, 3.000000e+00 260*9880d681SAndroid Build Coastguard Worker} 261*9880d681SAndroid Build Coastguard Worker 262*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul3_vec(<4 x float> %f1, <4 x float> %f2) { 263*9880d681SAndroid Build Coastguard Worker %t1 = fdiv <4 x float> %f1, <float 2.0e+3, float 3.0e+3, float 2.0e+3, float 1.0e+3> 264*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast <4 x float> %t1, <float 6.0e+3, float 6.0e+3, float 2.0e+3, float 1.0e+3> 265*9880d681SAndroid Build Coastguard Worker ret <4 x float> %t3 266*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul3_vec( 267*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast <4 x float> %f1, <float 3.000000e+00, float 2.000000e+00, float 1.000000e+00, float 1.000000e+00> 268*9880d681SAndroid Build Coastguard Worker} 269*9880d681SAndroid Build Coastguard Worker 270*9880d681SAndroid Build Coastguard Worker; Make sure fmul with constant expression doesn't assert. 271*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul3_vec_constexpr(<4 x float> %f1, <4 x float> %f2) { 272*9880d681SAndroid Build Coastguard Worker %constExprMul = bitcast i128 trunc (i160 bitcast (<5 x float> <float 6.0e+3, float 6.0e+3, float 2.0e+3, float 1.0e+3, float undef> to i160) to i128) to <4 x float> 273*9880d681SAndroid Build Coastguard Worker %t1 = fdiv <4 x float> %f1, <float 2.0e+3, float 3.0e+3, float 2.0e+3, float 1.0e+3> 274*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast <4 x float> %t1, %constExprMul 275*9880d681SAndroid Build Coastguard Worker ret <4 x float> %t3 276*9880d681SAndroid Build Coastguard Worker} 277*9880d681SAndroid Build Coastguard Worker 278*9880d681SAndroid Build Coastguard Worker; Rule "X/C1 * C2 => X * (C2/C1) is not applicable if C2/C1 is either a special 279*9880d681SAndroid Build Coastguard Worker; value of a denormal. The 0x3810000000000000 here take value FLT_MIN 280*9880d681SAndroid Build Coastguard Worker; 281*9880d681SAndroid Build Coastguard Workerdefine float @fmul4(float %f1, float %f2) { 282*9880d681SAndroid Build Coastguard Worker %t1 = fdiv float %f1, 2.0e+3 283*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast float %t1, 0x3810000000000000 284*9880d681SAndroid Build Coastguard Worker ret float %t3 285*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul4( 286*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %t1, 0x3810000000000000 287*9880d681SAndroid Build Coastguard Worker} 288*9880d681SAndroid Build Coastguard Worker 289*9880d681SAndroid Build Coastguard Worker; X / C1 * C2 => X / (C2/C1) if C1/C2 is either a special value of a denormal, 290*9880d681SAndroid Build Coastguard Worker; and C2/C1 is a normal value. 291*9880d681SAndroid Build Coastguard Worker; 292*9880d681SAndroid Build Coastguard Workerdefine float @fmul5(float %f1, float %f2) { 293*9880d681SAndroid Build Coastguard Worker %t1 = fdiv float %f1, 3.0e+0 294*9880d681SAndroid Build Coastguard Worker %t3 = fmul fast float %t1, 0x3810000000000000 295*9880d681SAndroid Build Coastguard Worker ret float %t3 296*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul5( 297*9880d681SAndroid Build Coastguard Worker; CHECK: fdiv fast float %f1, 0x47E8000000000000 298*9880d681SAndroid Build Coastguard Worker} 299*9880d681SAndroid Build Coastguard Worker 300*9880d681SAndroid Build Coastguard Worker; (X*Y) * X => (X*X) * Y 301*9880d681SAndroid Build Coastguard Workerdefine float @fmul6(float %f1, float %f2) { 302*9880d681SAndroid Build Coastguard Worker %mul = fmul float %f1, %f2 303*9880d681SAndroid Build Coastguard Worker %mul1 = fmul fast float %mul, %f1 304*9880d681SAndroid Build Coastguard Worker ret float %mul1 305*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul6( 306*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %f1, %f1 307*9880d681SAndroid Build Coastguard Worker} 308*9880d681SAndroid Build Coastguard Worker 309*9880d681SAndroid Build Coastguard Worker; "(X*Y) * X => (X*X) * Y" is disabled if "X*Y" has multiple uses 310*9880d681SAndroid Build Coastguard Workerdefine float @fmul7(float %f1, float %f2) { 311*9880d681SAndroid Build Coastguard Worker %mul = fmul float %f1, %f2 312*9880d681SAndroid Build Coastguard Worker %mul1 = fmul fast float %mul, %f1 313*9880d681SAndroid Build Coastguard Worker %add = fadd float %mul1, %mul 314*9880d681SAndroid Build Coastguard Worker ret float %add 315*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fmul7( 316*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %mul, %f1 317*9880d681SAndroid Build Coastguard Worker} 318*9880d681SAndroid Build Coastguard Worker 319*9880d681SAndroid Build Coastguard Worker; ========================================================================= 320*9880d681SAndroid Build Coastguard Worker; 321*9880d681SAndroid Build Coastguard Worker; Testing-cases about negation 322*9880d681SAndroid Build Coastguard Worker; 323*9880d681SAndroid Build Coastguard Worker; ========================================================================= 324*9880d681SAndroid Build Coastguard Workerdefine float @fneg1(float %f1, float %f2) { 325*9880d681SAndroid Build Coastguard Worker %sub = fsub float -0.000000e+00, %f1 326*9880d681SAndroid Build Coastguard Worker %sub1 = fsub nsz float 0.000000e+00, %f2 327*9880d681SAndroid Build Coastguard Worker %mul = fmul float %sub, %sub1 328*9880d681SAndroid Build Coastguard Worker ret float %mul 329*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fneg1( 330*9880d681SAndroid Build Coastguard Worker; CHECK: fmul float %f1, %f2 331*9880d681SAndroid Build Coastguard Worker} 332*9880d681SAndroid Build Coastguard Worker 333*9880d681SAndroid Build Coastguard Workerdefine float @fneg2(float %x) { 334*9880d681SAndroid Build Coastguard Worker %sub = fsub nsz float 0.0, %x 335*9880d681SAndroid Build Coastguard Worker ret float %sub 336*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fneg2( 337*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fsub nsz float -0.000000e+00, %x 338*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 339*9880d681SAndroid Build Coastguard Worker} 340*9880d681SAndroid Build Coastguard Worker 341*9880d681SAndroid Build Coastguard Worker; ========================================================================= 342*9880d681SAndroid Build Coastguard Worker; 343*9880d681SAndroid Build Coastguard Worker; Testing-cases about div 344*9880d681SAndroid Build Coastguard Worker; 345*9880d681SAndroid Build Coastguard Worker; ========================================================================= 346*9880d681SAndroid Build Coastguard Worker 347*9880d681SAndroid Build Coastguard Worker; X/C1 / C2 => X * (1/(C2*C1)) 348*9880d681SAndroid Build Coastguard Workerdefine float @fdiv1(float %x) { 349*9880d681SAndroid Build Coastguard Worker %div = fdiv float %x, 0x3FF3333340000000 350*9880d681SAndroid Build Coastguard Worker %div1 = fdiv fast float %div, 0x4002666660000000 351*9880d681SAndroid Build Coastguard Worker ret float %div1 352*9880d681SAndroid Build Coastguard Worker; 0x3FF3333340000000 = 1.2f 353*9880d681SAndroid Build Coastguard Worker; 0x4002666660000000 = 2.3f 354*9880d681SAndroid Build Coastguard Worker; 0x3FD7303B60000000 = 0.36231884057971014492 355*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv1( 356*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %x, 0x3FD7303B60000000 357*9880d681SAndroid Build Coastguard Worker} 358*9880d681SAndroid Build Coastguard Worker 359*9880d681SAndroid Build Coastguard Worker; X*C1 / C2 => X * (C1/C2) 360*9880d681SAndroid Build Coastguard Workerdefine float @fdiv2(float %x) { 361*9880d681SAndroid Build Coastguard Worker %mul = fmul float %x, 0x3FF3333340000000 362*9880d681SAndroid Build Coastguard Worker %div1 = fdiv fast float %mul, 0x4002666660000000 363*9880d681SAndroid Build Coastguard Worker ret float %div1 364*9880d681SAndroid Build Coastguard Worker 365*9880d681SAndroid Build Coastguard Worker; 0x3FF3333340000000 = 1.2f 366*9880d681SAndroid Build Coastguard Worker; 0x4002666660000000 = 2.3f 367*9880d681SAndroid Build Coastguard Worker; 0x3FE0B21660000000 = 0.52173918485641479492 368*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv2( 369*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %x, 0x3FE0B21660000000 370*9880d681SAndroid Build Coastguard Worker} 371*9880d681SAndroid Build Coastguard Worker 372*9880d681SAndroid Build Coastguard Workerdefine <2 x float> @fdiv2_vec(<2 x float> %x) { 373*9880d681SAndroid Build Coastguard Worker %mul = fmul <2 x float> %x, <float 6.0, float 9.0> 374*9880d681SAndroid Build Coastguard Worker %div1 = fdiv fast <2 x float> %mul, <float 2.0, float 3.0> 375*9880d681SAndroid Build Coastguard Worker ret <2 x float> %div1 376*9880d681SAndroid Build Coastguard Worker 377*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv2_vec( 378*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast <2 x float> %x, <float 3.000000e+00, float 3.000000e+00> 379*9880d681SAndroid Build Coastguard Worker} 380*9880d681SAndroid Build Coastguard Worker 381*9880d681SAndroid Build Coastguard Worker; "X/C1 / C2 => X * (1/(C2*C1))" is disabled (for now) is C2/C1 is a denormal 382*9880d681SAndroid Build Coastguard Worker; 383*9880d681SAndroid Build Coastguard Workerdefine float @fdiv3(float %x) { 384*9880d681SAndroid Build Coastguard Worker %div = fdiv float %x, 0x47EFFFFFE0000000 385*9880d681SAndroid Build Coastguard Worker %div1 = fdiv fast float %div, 0x4002666660000000 386*9880d681SAndroid Build Coastguard Worker ret float %div1 387*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv3( 388*9880d681SAndroid Build Coastguard Worker; CHECK: fdiv float %x, 0x47EFFFFFE0000000 389*9880d681SAndroid Build Coastguard Worker} 390*9880d681SAndroid Build Coastguard Worker 391*9880d681SAndroid Build Coastguard Worker; "X*C1 / C2 => X * (C1/C2)" is disabled if C1/C2 is a denormal 392*9880d681SAndroid Build Coastguard Workerdefine float @fdiv4(float %x) { 393*9880d681SAndroid Build Coastguard Worker %mul = fmul float %x, 0x47EFFFFFE0000000 394*9880d681SAndroid Build Coastguard Worker %div = fdiv float %mul, 0x3FC99999A0000000 395*9880d681SAndroid Build Coastguard Worker ret float %div 396*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv4( 397*9880d681SAndroid Build Coastguard Worker; CHECK: fmul float %x, 0x47EFFFFFE0000000 398*9880d681SAndroid Build Coastguard Worker} 399*9880d681SAndroid Build Coastguard Worker 400*9880d681SAndroid Build Coastguard Worker; (X/Y)/Z = > X/(Y*Z) 401*9880d681SAndroid Build Coastguard Workerdefine float @fdiv5(float %f1, float %f2, float %f3) { 402*9880d681SAndroid Build Coastguard Worker %t1 = fdiv float %f1, %f2 403*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float %t1, %f3 404*9880d681SAndroid Build Coastguard Worker ret float %t2 405*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv5( 406*9880d681SAndroid Build Coastguard Worker; CHECK: fmul float %f2, %f3 407*9880d681SAndroid Build Coastguard Worker} 408*9880d681SAndroid Build Coastguard Worker 409*9880d681SAndroid Build Coastguard Worker; Z/(X/Y) = > (Z*Y)/X 410*9880d681SAndroid Build Coastguard Workerdefine float @fdiv6(float %f1, float %f2, float %f3) { 411*9880d681SAndroid Build Coastguard Worker %t1 = fdiv float %f1, %f2 412*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float %f3, %t1 413*9880d681SAndroid Build Coastguard Worker ret float %t2 414*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv6( 415*9880d681SAndroid Build Coastguard Worker; CHECK: fmul float %f3, %f2 416*9880d681SAndroid Build Coastguard Worker} 417*9880d681SAndroid Build Coastguard Worker 418*9880d681SAndroid Build Coastguard Worker; C1/(X*C2) => (C1/C2) / X 419*9880d681SAndroid Build Coastguard Workerdefine float @fdiv7(float %x) { 420*9880d681SAndroid Build Coastguard Worker %t1 = fmul float %x, 3.0e0 421*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float 15.0e0, %t1 422*9880d681SAndroid Build Coastguard Worker ret float %t2 423*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv7( 424*9880d681SAndroid Build Coastguard Worker; CHECK: fdiv fast float 5.000000e+00, %x 425*9880d681SAndroid Build Coastguard Worker} 426*9880d681SAndroid Build Coastguard Worker 427*9880d681SAndroid Build Coastguard Worker; C1/(X/C2) => (C1*C2) / X 428*9880d681SAndroid Build Coastguard Workerdefine float @fdiv8(float %x) { 429*9880d681SAndroid Build Coastguard Worker %t1 = fdiv float %x, 3.0e0 430*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float 15.0e0, %t1 431*9880d681SAndroid Build Coastguard Worker ret float %t2 432*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv8( 433*9880d681SAndroid Build Coastguard Worker; CHECK: fdiv fast float 4.500000e+01, %x 434*9880d681SAndroid Build Coastguard Worker} 435*9880d681SAndroid Build Coastguard Worker 436*9880d681SAndroid Build Coastguard Worker; C1/(C2/X) => (C1/C2) * X 437*9880d681SAndroid Build Coastguard Workerdefine float @fdiv9(float %x) { 438*9880d681SAndroid Build Coastguard Worker %t1 = fdiv float 3.0e0, %x 439*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float 15.0e0, %t1 440*9880d681SAndroid Build Coastguard Worker ret float %t2 441*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fdiv9( 442*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %x, 5.000000e+00 443*9880d681SAndroid Build Coastguard Worker} 444*9880d681SAndroid Build Coastguard Worker 445*9880d681SAndroid Build Coastguard Worker; ========================================================================= 446*9880d681SAndroid Build Coastguard Worker; 447*9880d681SAndroid Build Coastguard Worker; Testing-cases about factorization 448*9880d681SAndroid Build Coastguard Worker; 449*9880d681SAndroid Build Coastguard Worker; ========================================================================= 450*9880d681SAndroid Build Coastguard Worker; x*z + y*z => (x+y) * z 451*9880d681SAndroid Build Coastguard Workerdefine float @fact_mul1(float %x, float %y, float %z) { 452*9880d681SAndroid Build Coastguard Worker %t1 = fmul fast float %x, %z 453*9880d681SAndroid Build Coastguard Worker %t2 = fmul fast float %y, %z 454*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %t1, %t2 455*9880d681SAndroid Build Coastguard Worker ret float %t3 456*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fact_mul1( 457*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %1, %z 458*9880d681SAndroid Build Coastguard Worker} 459*9880d681SAndroid Build Coastguard Worker 460*9880d681SAndroid Build Coastguard Worker; z*x + y*z => (x+y) * z 461*9880d681SAndroid Build Coastguard Workerdefine float @fact_mul2(float %x, float %y, float %z) { 462*9880d681SAndroid Build Coastguard Worker %t1 = fmul fast float %z, %x 463*9880d681SAndroid Build Coastguard Worker %t2 = fmul fast float %y, %z 464*9880d681SAndroid Build Coastguard Worker %t3 = fsub fast float %t1, %t2 465*9880d681SAndroid Build Coastguard Worker ret float %t3 466*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fact_mul2( 467*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %1, %z 468*9880d681SAndroid Build Coastguard Worker} 469*9880d681SAndroid Build Coastguard Worker 470*9880d681SAndroid Build Coastguard Worker; z*x - z*y => (x-y) * z 471*9880d681SAndroid Build Coastguard Workerdefine float @fact_mul3(float %x, float %y, float %z) { 472*9880d681SAndroid Build Coastguard Worker %t2 = fmul fast float %z, %y 473*9880d681SAndroid Build Coastguard Worker %t1 = fmul fast float %z, %x 474*9880d681SAndroid Build Coastguard Worker %t3 = fsub fast float %t1, %t2 475*9880d681SAndroid Build Coastguard Worker ret float %t3 476*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fact_mul3( 477*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %1, %z 478*9880d681SAndroid Build Coastguard Worker} 479*9880d681SAndroid Build Coastguard Worker 480*9880d681SAndroid Build Coastguard Worker; x*z - z*y => (x-y) * z 481*9880d681SAndroid Build Coastguard Workerdefine float @fact_mul4(float %x, float %y, float %z) { 482*9880d681SAndroid Build Coastguard Worker %t1 = fmul fast float %x, %z 483*9880d681SAndroid Build Coastguard Worker %t2 = fmul fast float %z, %y 484*9880d681SAndroid Build Coastguard Worker %t3 = fsub fast float %t1, %t2 485*9880d681SAndroid Build Coastguard Worker ret float %t3 486*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fact_mul4( 487*9880d681SAndroid Build Coastguard Worker; CHECK: fmul fast float %1, %z 488*9880d681SAndroid Build Coastguard Worker} 489*9880d681SAndroid Build Coastguard Worker 490*9880d681SAndroid Build Coastguard Worker; x/y + x/z, no xform 491*9880d681SAndroid Build Coastguard Workerdefine float @fact_div1(float %x, float %y, float %z) { 492*9880d681SAndroid Build Coastguard Worker %t1 = fdiv fast float %x, %y 493*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float %x, %z 494*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %t1, %t2 495*9880d681SAndroid Build Coastguard Worker ret float %t3 496*9880d681SAndroid Build Coastguard Worker; CHECK: fact_div1 497*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float %t1, %t2 498*9880d681SAndroid Build Coastguard Worker} 499*9880d681SAndroid Build Coastguard Worker 500*9880d681SAndroid Build Coastguard Worker; x/y + z/x; no xform 501*9880d681SAndroid Build Coastguard Workerdefine float @fact_div2(float %x, float %y, float %z) { 502*9880d681SAndroid Build Coastguard Worker %t1 = fdiv fast float %x, %y 503*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float %z, %x 504*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %t1, %t2 505*9880d681SAndroid Build Coastguard Worker ret float %t3 506*9880d681SAndroid Build Coastguard Worker; CHECK: fact_div2 507*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float %t1, %t2 508*9880d681SAndroid Build Coastguard Worker} 509*9880d681SAndroid Build Coastguard Worker 510*9880d681SAndroid Build Coastguard Worker; y/x + z/x => (y+z)/x 511*9880d681SAndroid Build Coastguard Workerdefine float @fact_div3(float %x, float %y, float %z) { 512*9880d681SAndroid Build Coastguard Worker %t1 = fdiv fast float %y, %x 513*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float %z, %x 514*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %t1, %t2 515*9880d681SAndroid Build Coastguard Worker ret float %t3 516*9880d681SAndroid Build Coastguard Worker; CHECK: fact_div3 517*9880d681SAndroid Build Coastguard Worker; CHECK: fdiv fast float %1, %x 518*9880d681SAndroid Build Coastguard Worker} 519*9880d681SAndroid Build Coastguard Worker 520*9880d681SAndroid Build Coastguard Worker; y/x - z/x => (y-z)/x 521*9880d681SAndroid Build Coastguard Workerdefine float @fact_div4(float %x, float %y, float %z) { 522*9880d681SAndroid Build Coastguard Worker %t1 = fdiv fast float %y, %x 523*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float %z, %x 524*9880d681SAndroid Build Coastguard Worker %t3 = fsub fast float %t1, %t2 525*9880d681SAndroid Build Coastguard Worker ret float %t3 526*9880d681SAndroid Build Coastguard Worker; CHECK: fact_div4 527*9880d681SAndroid Build Coastguard Worker; CHECK: fdiv fast float %1, %x 528*9880d681SAndroid Build Coastguard Worker} 529*9880d681SAndroid Build Coastguard Worker 530*9880d681SAndroid Build Coastguard Worker; y/x - z/x => (y-z)/x is disabled if y-z is denormal. 531*9880d681SAndroid Build Coastguard Workerdefine float @fact_div5(float %x) { 532*9880d681SAndroid Build Coastguard Worker %t1 = fdiv fast float 0x3810000000000000, %x 533*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float 0x3800000000000000, %x 534*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %t1, %t2 535*9880d681SAndroid Build Coastguard Worker ret float %t3 536*9880d681SAndroid Build Coastguard Worker; CHECK: fact_div5 537*9880d681SAndroid Build Coastguard Worker; CHECK: fdiv fast float 0x3818000000000000, %x 538*9880d681SAndroid Build Coastguard Worker} 539*9880d681SAndroid Build Coastguard Worker 540*9880d681SAndroid Build Coastguard Worker; y/x - z/x => (y-z)/x is disabled if y-z is denormal. 541*9880d681SAndroid Build Coastguard Workerdefine float @fact_div6(float %x) { 542*9880d681SAndroid Build Coastguard Worker %t1 = fdiv fast float 0x3810000000000000, %x 543*9880d681SAndroid Build Coastguard Worker %t2 = fdiv fast float 0x3800000000000000, %x 544*9880d681SAndroid Build Coastguard Worker %t3 = fsub fast float %t1, %t2 545*9880d681SAndroid Build Coastguard Worker ret float %t3 546*9880d681SAndroid Build Coastguard Worker; CHECK: fact_div6 547*9880d681SAndroid Build Coastguard Worker; CHECK: %t3 = fsub fast float %t1, %t2 548*9880d681SAndroid Build Coastguard Worker} 549*9880d681SAndroid Build Coastguard Worker 550*9880d681SAndroid Build Coastguard Worker; ========================================================================= 551*9880d681SAndroid Build Coastguard Worker; 552*9880d681SAndroid Build Coastguard Worker; Test-cases for square root 553*9880d681SAndroid Build Coastguard Worker; 554*9880d681SAndroid Build Coastguard Worker; ========================================================================= 555*9880d681SAndroid Build Coastguard Worker 556*9880d681SAndroid Build Coastguard Worker; A squared factor fed into a square root intrinsic should be hoisted out 557*9880d681SAndroid Build Coastguard Worker; as a fabs() value. 558*9880d681SAndroid Build Coastguard Worker 559*9880d681SAndroid Build Coastguard Workerdeclare double @llvm.sqrt.f64(double) 560*9880d681SAndroid Build Coastguard Worker 561*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_arg_squared(double %x) { 562*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %x, %x 563*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul) 564*9880d681SAndroid Build Coastguard Worker ret double %sqrt 565*9880d681SAndroid Build Coastguard Worker 566*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_arg_squared( 567*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast double @llvm.fabs.f64(double %x) 568*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %fabs 569*9880d681SAndroid Build Coastguard Worker} 570*9880d681SAndroid Build Coastguard Worker 571*9880d681SAndroid Build Coastguard Worker; Check all 6 combinations of a 3-way multiplication tree where 572*9880d681SAndroid Build Coastguard Worker; one factor is repeated. 573*9880d681SAndroid Build Coastguard Worker 574*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_three_args1(double %x, double %y) { 575*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %y, %x 576*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %mul, %x 577*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 578*9880d681SAndroid Build Coastguard Worker ret double %sqrt 579*9880d681SAndroid Build Coastguard Worker 580*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_three_args1( 581*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast double @llvm.fabs.f64(double %x) 582*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %sqrt1 = call fast double @llvm.sqrt.f64(double %y) 583*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %1 = fmul fast double %fabs, %sqrt1 584*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %1 585*9880d681SAndroid Build Coastguard Worker} 586*9880d681SAndroid Build Coastguard Worker 587*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_three_args2(double %x, double %y) { 588*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %x, %y 589*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %mul, %x 590*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 591*9880d681SAndroid Build Coastguard Worker ret double %sqrt 592*9880d681SAndroid Build Coastguard Worker 593*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_three_args2( 594*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast double @llvm.fabs.f64(double %x) 595*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %sqrt1 = call fast double @llvm.sqrt.f64(double %y) 596*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %1 = fmul fast double %fabs, %sqrt1 597*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %1 598*9880d681SAndroid Build Coastguard Worker} 599*9880d681SAndroid Build Coastguard Worker 600*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_three_args3(double %x, double %y) { 601*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %x, %x 602*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %mul, %y 603*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 604*9880d681SAndroid Build Coastguard Worker ret double %sqrt 605*9880d681SAndroid Build Coastguard Worker 606*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_three_args3( 607*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast double @llvm.fabs.f64(double %x) 608*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %sqrt1 = call fast double @llvm.sqrt.f64(double %y) 609*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %1 = fmul fast double %fabs, %sqrt1 610*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %1 611*9880d681SAndroid Build Coastguard Worker} 612*9880d681SAndroid Build Coastguard Worker 613*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_three_args4(double %x, double %y) { 614*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %y, %x 615*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %x, %mul 616*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 617*9880d681SAndroid Build Coastguard Worker ret double %sqrt 618*9880d681SAndroid Build Coastguard Worker 619*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_three_args4( 620*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast double @llvm.fabs.f64(double %x) 621*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %sqrt1 = call fast double @llvm.sqrt.f64(double %y) 622*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %1 = fmul fast double %fabs, %sqrt1 623*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %1 624*9880d681SAndroid Build Coastguard Worker} 625*9880d681SAndroid Build Coastguard Worker 626*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_three_args5(double %x, double %y) { 627*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %x, %y 628*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %x, %mul 629*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 630*9880d681SAndroid Build Coastguard Worker ret double %sqrt 631*9880d681SAndroid Build Coastguard Worker 632*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_three_args5( 633*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast double @llvm.fabs.f64(double %x) 634*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %sqrt1 = call fast double @llvm.sqrt.f64(double %y) 635*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %1 = fmul fast double %fabs, %sqrt1 636*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %1 637*9880d681SAndroid Build Coastguard Worker} 638*9880d681SAndroid Build Coastguard Worker 639*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_three_args6(double %x, double %y) { 640*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %x, %x 641*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %y, %mul 642*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 643*9880d681SAndroid Build Coastguard Worker ret double %sqrt 644*9880d681SAndroid Build Coastguard Worker 645*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_three_args6( 646*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast double @llvm.fabs.f64(double %x) 647*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %sqrt1 = call fast double @llvm.sqrt.f64(double %y) 648*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %1 = fmul fast double %fabs, %sqrt1 649*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %1 650*9880d681SAndroid Build Coastguard Worker} 651*9880d681SAndroid Build Coastguard Worker 652*9880d681SAndroid Build Coastguard Worker; If any operation is not 'fast', we can't simplify. 653*9880d681SAndroid Build Coastguard Worker 654*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_not_so_fast(double %x, double %y) { 655*9880d681SAndroid Build Coastguard Worker %mul = fmul double %x, %x 656*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %mul, %y 657*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 658*9880d681SAndroid Build Coastguard Worker ret double %sqrt 659*9880d681SAndroid Build Coastguard Worker 660*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_not_so_fast( 661*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %mul = fmul double %x, %x 662*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %mul2 = fmul fast double %mul, %y 663*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 664*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %sqrt 665*9880d681SAndroid Build Coastguard Worker} 666*9880d681SAndroid Build Coastguard Worker 667*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_arg_4th(double %x) { 668*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %x, %x 669*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %mul, %mul 670*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul2) 671*9880d681SAndroid Build Coastguard Worker ret double %sqrt 672*9880d681SAndroid Build Coastguard Worker 673*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_arg_4th( 674*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %mul = fmul fast double %x, %x 675*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %mul 676*9880d681SAndroid Build Coastguard Worker} 677*9880d681SAndroid Build Coastguard Worker 678*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_intrinsic_arg_5th(double %x) { 679*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %x, %x 680*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast double %mul, %x 681*9880d681SAndroid Build Coastguard Worker %mul3 = fmul fast double %mul2, %mul 682*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @llvm.sqrt.f64(double %mul3) 683*9880d681SAndroid Build Coastguard Worker ret double %sqrt 684*9880d681SAndroid Build Coastguard Worker 685*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_intrinsic_arg_5th( 686*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %mul = fmul fast double %x, %x 687*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %sqrt1 = call fast double @llvm.sqrt.f64(double %x) 688*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %1 = fmul fast double %mul, %sqrt1 689*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %1 690*9880d681SAndroid Build Coastguard Worker} 691*9880d681SAndroid Build Coastguard Worker 692*9880d681SAndroid Build Coastguard Worker; Check that square root calls have the same behavior. 693*9880d681SAndroid Build Coastguard Worker 694*9880d681SAndroid Build Coastguard Workerdeclare float @sqrtf(float) 695*9880d681SAndroid Build Coastguard Workerdeclare double @sqrt(double) 696*9880d681SAndroid Build Coastguard Workerdeclare fp128 @sqrtl(fp128) 697*9880d681SAndroid Build Coastguard Worker 698*9880d681SAndroid Build Coastguard Workerdefine float @sqrt_call_squared_f32(float %x) { 699*9880d681SAndroid Build Coastguard Worker %mul = fmul fast float %x, %x 700*9880d681SAndroid Build Coastguard Worker %sqrt = call fast float @sqrtf(float %mul) 701*9880d681SAndroid Build Coastguard Worker ret float %sqrt 702*9880d681SAndroid Build Coastguard Worker 703*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_call_squared_f32( 704*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast float @llvm.fabs.f32(float %x) 705*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float %fabs 706*9880d681SAndroid Build Coastguard Worker} 707*9880d681SAndroid Build Coastguard Worker 708*9880d681SAndroid Build Coastguard Workerdefine double @sqrt_call_squared_f64(double %x) { 709*9880d681SAndroid Build Coastguard Worker %mul = fmul fast double %x, %x 710*9880d681SAndroid Build Coastguard Worker %sqrt = call fast double @sqrt(double %mul) 711*9880d681SAndroid Build Coastguard Worker ret double %sqrt 712*9880d681SAndroid Build Coastguard Worker 713*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_call_squared_f64( 714*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast double @llvm.fabs.f64(double %x) 715*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret double %fabs 716*9880d681SAndroid Build Coastguard Worker} 717*9880d681SAndroid Build Coastguard Worker 718*9880d681SAndroid Build Coastguard Workerdefine fp128 @sqrt_call_squared_f128(fp128 %x) { 719*9880d681SAndroid Build Coastguard Worker %mul = fmul fast fp128 %x, %x 720*9880d681SAndroid Build Coastguard Worker %sqrt = call fast fp128 @sqrtl(fp128 %mul) 721*9880d681SAndroid Build Coastguard Worker ret fp128 %sqrt 722*9880d681SAndroid Build Coastguard Worker 723*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: sqrt_call_squared_f128( 724*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %fabs = call fast fp128 @llvm.fabs.f128(fp128 %x) 725*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret fp128 %fabs 726*9880d681SAndroid Build Coastguard Worker} 727*9880d681SAndroid Build Coastguard Worker 728*9880d681SAndroid Build Coastguard Worker; ========================================================================= 729*9880d681SAndroid Build Coastguard Worker; 730*9880d681SAndroid Build Coastguard Worker; Test-cases for fmin / fmax 731*9880d681SAndroid Build Coastguard Worker; 732*9880d681SAndroid Build Coastguard Worker; ========================================================================= 733*9880d681SAndroid Build Coastguard Worker 734*9880d681SAndroid Build Coastguard Workerdeclare double @fmax(double, double) 735*9880d681SAndroid Build Coastguard Workerdeclare double @fmin(double, double) 736*9880d681SAndroid Build Coastguard Workerdeclare float @fmaxf(float, float) 737*9880d681SAndroid Build Coastguard Workerdeclare float @fminf(float, float) 738*9880d681SAndroid Build Coastguard Workerdeclare fp128 @fmaxl(fp128, fp128) 739*9880d681SAndroid Build Coastguard Workerdeclare fp128 @fminl(fp128, fp128) 740*9880d681SAndroid Build Coastguard Worker 741*9880d681SAndroid Build Coastguard Worker; No NaNs is the minimum requirement to replace these calls. 742*9880d681SAndroid Build Coastguard Worker; This should always be set when unsafe-fp-math is true, but 743*9880d681SAndroid Build Coastguard Worker; alternate the attributes for additional test coverage. 744*9880d681SAndroid Build Coastguard Worker; 'nsz' is implied by the definition of fmax or fmin itself. 745*9880d681SAndroid Build Coastguard Worker 746*9880d681SAndroid Build Coastguard Worker; Shrink and remove the call. 747*9880d681SAndroid Build Coastguard Workerdefine float @max1(float %a, float %b) { 748*9880d681SAndroid Build Coastguard Worker %c = fpext float %a to double 749*9880d681SAndroid Build Coastguard Worker %d = fpext float %b to double 750*9880d681SAndroid Build Coastguard Worker %e = call fast double @fmax(double %c, double %d) 751*9880d681SAndroid Build Coastguard Worker %f = fptrunc double %e to float 752*9880d681SAndroid Build Coastguard Worker ret float %f 753*9880d681SAndroid Build Coastguard Worker 754*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: max1( 755*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp fast ogt float %a, %b 756*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: select {{.*}} float %a, float %b 757*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 758*9880d681SAndroid Build Coastguard Worker} 759*9880d681SAndroid Build Coastguard Worker 760*9880d681SAndroid Build Coastguard Workerdefine float @max2(float %a, float %b) { 761*9880d681SAndroid Build Coastguard Worker %c = call nnan float @fmaxf(float %a, float %b) 762*9880d681SAndroid Build Coastguard Worker ret float %c 763*9880d681SAndroid Build Coastguard Worker 764*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: max2( 765*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp nnan nsz ogt float %a, %b 766*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: select {{.*}} float %a, float %b 767*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 768*9880d681SAndroid Build Coastguard Worker} 769*9880d681SAndroid Build Coastguard Worker 770*9880d681SAndroid Build Coastguard Worker 771*9880d681SAndroid Build Coastguard Workerdefine double @max3(double %a, double %b) { 772*9880d681SAndroid Build Coastguard Worker %c = call fast double @fmax(double %a, double %b) 773*9880d681SAndroid Build Coastguard Worker ret double %c 774*9880d681SAndroid Build Coastguard Worker 775*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: max3( 776*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp fast ogt double %a, %b 777*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: select {{.*}} double %a, double %b 778*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 779*9880d681SAndroid Build Coastguard Worker} 780*9880d681SAndroid Build Coastguard Worker 781*9880d681SAndroid Build Coastguard Workerdefine fp128 @max4(fp128 %a, fp128 %b) { 782*9880d681SAndroid Build Coastguard Worker %c = call nnan fp128 @fmaxl(fp128 %a, fp128 %b) 783*9880d681SAndroid Build Coastguard Worker ret fp128 %c 784*9880d681SAndroid Build Coastguard Worker 785*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: max4( 786*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp nnan nsz ogt fp128 %a, %b 787*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: select {{.*}} fp128 %a, fp128 %b 788*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 789*9880d681SAndroid Build Coastguard Worker} 790*9880d681SAndroid Build Coastguard Worker 791*9880d681SAndroid Build Coastguard Worker; Shrink and remove the call. 792*9880d681SAndroid Build Coastguard Workerdefine float @min1(float %a, float %b) { 793*9880d681SAndroid Build Coastguard Worker %c = fpext float %a to double 794*9880d681SAndroid Build Coastguard Worker %d = fpext float %b to double 795*9880d681SAndroid Build Coastguard Worker %e = call nnan double @fmin(double %c, double %d) 796*9880d681SAndroid Build Coastguard Worker %f = fptrunc double %e to float 797*9880d681SAndroid Build Coastguard Worker ret float %f 798*9880d681SAndroid Build Coastguard Worker 799*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: min1( 800*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp nnan nsz olt float %a, %b 801*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: select {{.*}} float %a, float %b 802*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 803*9880d681SAndroid Build Coastguard Worker} 804*9880d681SAndroid Build Coastguard Worker 805*9880d681SAndroid Build Coastguard Workerdefine float @min2(float %a, float %b) { 806*9880d681SAndroid Build Coastguard Worker %c = call fast float @fminf(float %a, float %b) 807*9880d681SAndroid Build Coastguard Worker ret float %c 808*9880d681SAndroid Build Coastguard Worker 809*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: min2( 810*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp fast olt float %a, %b 811*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: select {{.*}} float %a, float %b 812*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 813*9880d681SAndroid Build Coastguard Worker} 814*9880d681SAndroid Build Coastguard Worker 815*9880d681SAndroid Build Coastguard Workerdefine double @min3(double %a, double %b) { 816*9880d681SAndroid Build Coastguard Worker %c = call nnan double @fmin(double %a, double %b) 817*9880d681SAndroid Build Coastguard Worker ret double %c 818*9880d681SAndroid Build Coastguard Worker 819*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: min3( 820*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp nnan nsz olt double %a, %b 821*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: select {{.*}} double %a, double %b 822*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 823*9880d681SAndroid Build Coastguard Worker} 824*9880d681SAndroid Build Coastguard Worker 825*9880d681SAndroid Build Coastguard Workerdefine fp128 @min4(fp128 %a, fp128 %b) { 826*9880d681SAndroid Build Coastguard Worker %c = call fast fp128 @fminl(fp128 %a, fp128 %b) 827*9880d681SAndroid Build Coastguard Worker ret fp128 %c 828*9880d681SAndroid Build Coastguard Worker 829*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: min4( 830*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp fast olt fp128 %a, %b 831*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: select {{.*}} fp128 %a, fp128 %b 832*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 833*9880d681SAndroid Build Coastguard Worker} 834