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