1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -reassociate -gvn -instcombine -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; With reassociation, constant folding can eliminate the 12 and -12 constants. 4*9880d681SAndroid Build Coastguard Workerdefine float @test1(float %arg) { 5*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1 6*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fsub fast float -0.000000e+00, %arg 7*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker %tmp1 = fsub fast float -1.200000e+01, %arg 10*9880d681SAndroid Build Coastguard Worker %tmp2 = fadd fast float %tmp1, 1.200000e+01 11*9880d681SAndroid Build Coastguard Worker ret float %tmp2 12*9880d681SAndroid Build Coastguard Worker} 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerdefine float @test2(float %reg109, float %reg1111) { 15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2 16*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fadd float %reg109, -3.000000e+01 17*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fadd float %reg115, %reg1111 18*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fadd float %reg116, 3.000000e+01 19*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker %reg115 = fadd float %reg109, -3.000000e+01 22*9880d681SAndroid Build Coastguard Worker %reg116 = fadd float %reg115, %reg1111 23*9880d681SAndroid Build Coastguard Worker %reg117 = fadd float %reg116, 3.000000e+01 24*9880d681SAndroid Build Coastguard Worker ret float %reg117 25*9880d681SAndroid Build Coastguard Worker} 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Workerdefine float @test3(float %reg109, float %reg1111) { 28*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3 29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %reg117 = fadd fast float %reg109, %reg1111 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float %reg117 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker %reg115 = fadd fast float %reg109, -3.000000e+01 33*9880d681SAndroid Build Coastguard Worker %reg116 = fadd fast float %reg115, %reg1111 34*9880d681SAndroid Build Coastguard Worker %reg117 = fadd fast float %reg116, 3.000000e+01 35*9880d681SAndroid Build Coastguard Worker ret float %reg117 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker@fe = external global float 39*9880d681SAndroid Build Coastguard Worker@fa = external global float 40*9880d681SAndroid Build Coastguard Worker@fb = external global float 41*9880d681SAndroid Build Coastguard Worker@fc = external global float 42*9880d681SAndroid Build Coastguard Worker@ff = external global float 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Workerdefine void @test4() { 45*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4 46*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float 47*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float 48*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fadd fast float 49*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker %A = load float, float* @fa 52*9880d681SAndroid Build Coastguard Worker %B = load float, float* @fb 53*9880d681SAndroid Build Coastguard Worker %C = load float, float* @fc 54*9880d681SAndroid Build Coastguard Worker %t1 = fadd fast float %A, %B 55*9880d681SAndroid Build Coastguard Worker %t2 = fadd fast float %t1, %C 56*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %C, %A 57*9880d681SAndroid Build Coastguard Worker %t4 = fadd fast float %t3, %B 58*9880d681SAndroid Build Coastguard Worker ; e = (a+b)+c; 59*9880d681SAndroid Build Coastguard Worker store float %t2, float* @fe 60*9880d681SAndroid Build Coastguard Worker ; f = (a+c)+b 61*9880d681SAndroid Build Coastguard Worker store float %t4, float* @ff 62*9880d681SAndroid Build Coastguard Worker ret void 63*9880d681SAndroid Build Coastguard Worker} 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Workerdefine void @test5() { 66*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5 67*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float 68*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float 69*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fadd 70*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker %A = load float, float* @fa 73*9880d681SAndroid Build Coastguard Worker %B = load float, float* @fb 74*9880d681SAndroid Build Coastguard Worker %C = load float, float* @fc 75*9880d681SAndroid Build Coastguard Worker %t1 = fadd fast float %A, %B 76*9880d681SAndroid Build Coastguard Worker %t2 = fadd fast float %t1, %C 77*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %C, %A 78*9880d681SAndroid Build Coastguard Worker %t4 = fadd fast float %t3, %B 79*9880d681SAndroid Build Coastguard Worker ; e = c+(a+b) 80*9880d681SAndroid Build Coastguard Worker store float %t2, float* @fe 81*9880d681SAndroid Build Coastguard Worker ; f = (c+a)+b 82*9880d681SAndroid Build Coastguard Worker store float %t4, float* @ff 83*9880d681SAndroid Build Coastguard Worker ret void 84*9880d681SAndroid Build Coastguard Worker} 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerdefine void @test6() { 87*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6 88*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float 89*9880d681SAndroid Build Coastguard Worker; CHECK: fadd fast float 90*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fadd 91*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker %A = load float, float* @fa 94*9880d681SAndroid Build Coastguard Worker %B = load float, float* @fb 95*9880d681SAndroid Build Coastguard Worker %C = load float, float* @fc 96*9880d681SAndroid Build Coastguard Worker %t1 = fadd fast float %B, %A 97*9880d681SAndroid Build Coastguard Worker %t2 = fadd fast float %t1, %C 98*9880d681SAndroid Build Coastguard Worker %t3 = fadd fast float %C, %A 99*9880d681SAndroid Build Coastguard Worker %t4 = fadd fast float %t3, %B 100*9880d681SAndroid Build Coastguard Worker ; e = c+(b+a) 101*9880d681SAndroid Build Coastguard Worker store float %t2, float* @fe 102*9880d681SAndroid Build Coastguard Worker ; f = (c+a)+b 103*9880d681SAndroid Build Coastguard Worker store float %t4, float* @ff 104*9880d681SAndroid Build Coastguard Worker ret void 105*9880d681SAndroid Build Coastguard Worker} 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Workerdefine float @test7(float %A, float %B, float %C) { 108*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7 109*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fadd fast float %C, %B 110*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %A, %A 111*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %tmp3, %tmp2 112*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker %aa = fmul fast float %A, %A 115*9880d681SAndroid Build Coastguard Worker %aab = fmul fast float %aa, %B 116*9880d681SAndroid Build Coastguard Worker %ac = fmul fast float %A, %C 117*9880d681SAndroid Build Coastguard Worker %aac = fmul fast float %ac, %A 118*9880d681SAndroid Build Coastguard Worker %r = fadd fast float %aab, %aac 119*9880d681SAndroid Build Coastguard Worker ret float %r 120*9880d681SAndroid Build Coastguard Worker} 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerdefine float @test8(float %X, float %Y, float %Z) { 123*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8 124*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %Y, %X 125*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fsub fast float %Z 126*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker %A = fsub fast float 0.0, %X 129*9880d681SAndroid Build Coastguard Worker %B = fmul fast float %A, %Y 130*9880d681SAndroid Build Coastguard Worker ; (-X)*Y + Z -> Z-X*Y 131*9880d681SAndroid Build Coastguard Worker %C = fadd fast float %B, %Z 132*9880d681SAndroid Build Coastguard Worker ret float %C 133*9880d681SAndroid Build Coastguard Worker} 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Workerdefine float @test9(float %X) { 136*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9 137*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %X, 9.400000e+01 138*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker %Y = fmul fast float %X, 4.700000e+01 141*9880d681SAndroid Build Coastguard Worker %Z = fadd fast float %Y, %Y 142*9880d681SAndroid Build Coastguard Worker ret float %Z 143*9880d681SAndroid Build Coastguard Worker} 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Workerdefine float @test10(float %X) { 146*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10 147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %X, 3.000000e+00 148*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker %Y = fadd fast float %X ,%X 151*9880d681SAndroid Build Coastguard Worker %Z = fadd fast float %Y, %X 152*9880d681SAndroid Build Coastguard Worker ret float %Z 153*9880d681SAndroid Build Coastguard Worker} 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Workerdefine float @test11(float %W) { 156*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test11 157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %W, 3.810000e+02 158*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker %X = fmul fast float %W, 127.0 161*9880d681SAndroid Build Coastguard Worker %Y = fadd fast float %X ,%X 162*9880d681SAndroid Build Coastguard Worker %Z = fadd fast float %Y, %X 163*9880d681SAndroid Build Coastguard Worker ret float %Z 164*9880d681SAndroid Build Coastguard Worker} 165*9880d681SAndroid Build Coastguard Worker 166*9880d681SAndroid Build Coastguard Workerdefine float @test12(float %X) { 167*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12 168*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %X, -3.000000e+00 169*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fadd fast float %factor, 6.000000e+00 170*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Worker %A = fsub fast float 1.000000e+00, %X 173*9880d681SAndroid Build Coastguard Worker %B = fsub fast float 2.000000e+00, %X 174*9880d681SAndroid Build Coastguard Worker %C = fsub fast float 3.000000e+00, %X 175*9880d681SAndroid Build Coastguard Worker %Y = fadd fast float %A ,%B 176*9880d681SAndroid Build Coastguard Worker %Z = fadd fast float %Y, %C 177*9880d681SAndroid Build Coastguard Worker ret float %Z 178*9880d681SAndroid Build Coastguard Worker} 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Workerdefine float @test13(float %X1, float %X2, float %X3) { 181*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13 182*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fsub fast float %X3, %X2 183*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float {{.*}}, %X1 184*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Worker %A = fsub fast float 0.000000e+00, %X1 187*9880d681SAndroid Build Coastguard Worker %B = fmul fast float %A, %X2 ; -X1*X2 188*9880d681SAndroid Build Coastguard Worker %C = fmul fast float %X1, %X3 ; X1*X3 189*9880d681SAndroid Build Coastguard Worker %D = fadd fast float %B, %C ; -X1*X2 + X1*X3 -> X1*(X3-X2) 190*9880d681SAndroid Build Coastguard Worker ret float %D 191*9880d681SAndroid Build Coastguard Worker} 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Workerdefine float @test14(float %X1, float %X2) { 194*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test14 195*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fsub fast float %X1, %X2 196*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %1, 4.700000e+01 197*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Worker %B = fmul fast float %X1, 47. ; X1*47 200*9880d681SAndroid Build Coastguard Worker %C = fmul fast float %X2, -47. ; X2*-47 201*9880d681SAndroid Build Coastguard Worker %D = fadd fast float %B, %C ; X1*47 + X2*-47 -> 47*(X1-X2) 202*9880d681SAndroid Build Coastguard Worker ret float %D 203*9880d681SAndroid Build Coastguard Worker} 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Workerdefine float @test15(float %arg) { 206*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test15 207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %arg, 1.440000e+02 208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float %tmp2 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker %tmp1 = fmul fast float 1.200000e+01, %arg 211*9880d681SAndroid Build Coastguard Worker %tmp2 = fmul fast float %tmp1, 1.200000e+01 212*9880d681SAndroid Build Coastguard Worker ret float %tmp2 213*9880d681SAndroid Build Coastguard Worker} 214*9880d681SAndroid Build Coastguard Worker 215*9880d681SAndroid Build Coastguard Worker; (b+(a+1234))+-a -> b+1234 216*9880d681SAndroid Build Coastguard Workerdefine float @test16(float %b, float %a) { 217*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test16 218*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fadd fast float %b, 1.234000e+03 219*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Worker %1 = fadd fast float %a, 1234.0 222*9880d681SAndroid Build Coastguard Worker %2 = fadd fast float %b, %1 223*9880d681SAndroid Build Coastguard Worker %3 = fsub fast float 0.0, %a 224*9880d681SAndroid Build Coastguard Worker %4 = fadd fast float %2, %3 225*9880d681SAndroid Build Coastguard Worker ret float %4 226*9880d681SAndroid Build Coastguard Worker} 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Worker; Test that we can turn things like X*-(Y*Z) -> X*-1*Y*Z. 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Workerdefine float @test17(float %a, float %b, float %z) { 231*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test17 232*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %a, 1.234500e+04 233*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %e, %b 234*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %f, %z 235*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Worker %c = fsub fast float 0.000000e+00, %z 238*9880d681SAndroid Build Coastguard Worker %d = fmul fast float %a, %b 239*9880d681SAndroid Build Coastguard Worker %e = fmul fast float %c, %d 240*9880d681SAndroid Build Coastguard Worker %f = fmul fast float %e, 1.234500e+04 241*9880d681SAndroid Build Coastguard Worker %g = fsub fast float 0.000000e+00, %f 242*9880d681SAndroid Build Coastguard Worker ret float %g 243*9880d681SAndroid Build Coastguard Worker} 244*9880d681SAndroid Build Coastguard Worker 245*9880d681SAndroid Build Coastguard Workerdefine float @test18(float %a, float %b, float %z) { 246*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test18 247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %a, 4.000000e+01 248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fmul fast float %e, %z 249*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 250*9880d681SAndroid Build Coastguard Worker 251*9880d681SAndroid Build Coastguard Worker %d = fmul fast float %z, 4.000000e+01 252*9880d681SAndroid Build Coastguard Worker %c = fsub fast float 0.000000e+00, %d 253*9880d681SAndroid Build Coastguard Worker %e = fmul fast float %a, %c 254*9880d681SAndroid Build Coastguard Worker %f = fsub fast float 0.000000e+00, %e 255*9880d681SAndroid Build Coastguard Worker ret float %f 256*9880d681SAndroid Build Coastguard Worker} 257*9880d681SAndroid Build Coastguard Worker 258*9880d681SAndroid Build Coastguard Worker; With sub reassociation, constant folding can eliminate the 12 and -12 constants. 259*9880d681SAndroid Build Coastguard Workerdefine float @test19(float %A, float %B) { 260*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test19 261*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fsub fast float %A, %B 262*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 263*9880d681SAndroid Build Coastguard Worker %X = fadd fast float -1.200000e+01, %A 264*9880d681SAndroid Build Coastguard Worker %Y = fsub fast float %X, %B 265*9880d681SAndroid Build Coastguard Worker %Z = fadd fast float %Y, 1.200000e+01 266*9880d681SAndroid Build Coastguard Worker ret float %Z 267*9880d681SAndroid Build Coastguard Worker} 268*9880d681SAndroid Build Coastguard Worker 269*9880d681SAndroid Build Coastguard Worker; With sub reassociation, constant folding can eliminate the uses of %a. 270*9880d681SAndroid Build Coastguard Workerdefine float @test20(float %a, float %b, float %c) nounwind { 271*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test20 272*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fsub fast float -0.000000e+00, %b 273*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fsub fast float %b.neg, %c 274*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret float 275*9880d681SAndroid Build Coastguard Worker 276*9880d681SAndroid Build Coastguard Worker; FIXME: Should be able to generate the below, which may expose more 277*9880d681SAndroid Build Coastguard Worker; opportunites for FAdd reassociation. 278*9880d681SAndroid Build Coastguard Worker; %sum = fadd fast float %c, %b 279*9880d681SAndroid Build Coastguard Worker; %tmp7 = fsub fast float 0, %sum 280*9880d681SAndroid Build Coastguard Worker 281*9880d681SAndroid Build Coastguard Worker %tmp3 = fsub fast float %a, %b 282*9880d681SAndroid Build Coastguard Worker %tmp5 = fsub fast float %tmp3, %c 283*9880d681SAndroid Build Coastguard Worker %tmp7 = fsub fast float %tmp5, %a 284*9880d681SAndroid Build Coastguard Worker ret float %tmp7 285*9880d681SAndroid Build Coastguard Worker} 286