1 ; RUN: opt < %s -reassociate -gvn -instcombine -S | FileCheck %s 2 ; RUN: opt < %s -passes='reassociate,gvn,instcombine' -S | FileCheck %s 3 4 define i32 @test1(i32 %arg) { 5 %tmp1 = sub i32 -12, %arg 6 %tmp2 = add i32 %tmp1, 12 7 ret i32 %tmp2 8 9 ; CHECK-LABEL: @test1 10 ; CHECK-NEXT: sub i32 0, %arg 11 ; CHECK-NEXT: ret i32 12 } 13 14 define i32 @test2(i32 %reg109, i32 %reg1111) { 15 %reg115 = add i32 %reg109, -30 16 %reg116 = add i32 %reg115, %reg1111 17 %reg117 = add i32 %reg116, 30 18 ret i32 %reg117 19 20 ; CHECK-LABEL: @test2 21 ; CHECK-NEXT: %reg117 = add i32 %reg1111, %reg109 22 ; CHECK-NEXT: ret i32 %reg117 23 } 24 25 @e = external global i32 26 @a = external global i32 27 @b = external global i32 28 @c = external global i32 29 @f = external global i32 30 31 define void @test3() { 32 %A = load i32, i32* @a 33 %B = load i32, i32* @b 34 %C = load i32, i32* @c 35 %t1 = add i32 %A, %B 36 %t2 = add i32 %t1, %C 37 %t3 = add i32 %C, %A 38 %t4 = add i32 %t3, %B 39 ; e = (a+b)+c; 40 store i32 %t2, i32* @e 41 ; f = (a+c)+b 42 store i32 %t4, i32* @f 43 ret void 44 45 ; CHECK-LABEL: @test3 46 ; CHECK: add i32 47 ; CHECK: add i32 48 ; CHECK-NOT: add i32 49 ; CHECK: ret void 50 } 51 52 define void @test4() { 53 %A = load i32, i32* @a 54 %B = load i32, i32* @b 55 %C = load i32, i32* @c 56 %t1 = add i32 %A, %B 57 %t2 = add i32 %t1, %C 58 %t3 = add i32 %C, %A 59 %t4 = add i32 %t3, %B 60 ; e = c+(a+b) 61 store i32 %t2, i32* @e 62 ; f = (c+a)+b 63 store i32 %t4, i32* @f 64 ret void 65 66 ; CHECK-LABEL: @test4 67 ; CHECK: add i32 68 ; CHECK: add i32 69 ; CHECK-NOT: add i32 70 ; CHECK: ret void 71 } 72 73 define void @test5() { 74 %A = load i32, i32* @a 75 %B = load i32, i32* @b 76 %C = load i32, i32* @c 77 %t1 = add i32 %B, %A 78 %t2 = add i32 %t1, %C 79 %t3 = add i32 %C, %A 80 %t4 = add i32 %t3, %B 81 ; e = c+(b+a) 82 store i32 %t2, i32* @e 83 ; f = (c+a)+b 84 store i32 %t4, i32* @f 85 ret void 86 87 ; CHECK-LABEL: @test5 88 ; CHECK: add i32 89 ; CHECK: add i32 90 ; CHECK-NOT: add i32 91 ; CHECK: ret void 92 } 93 94 define i32 @test6() { 95 %tmp.0 = load i32, i32* @a 96 %tmp.1 = load i32, i32* @b 97 ; (a+b) 98 %tmp.2 = add i32 %tmp.0, %tmp.1 99 %tmp.4 = load i32, i32* @c 100 ; (a+b)+c 101 %tmp.5 = add i32 %tmp.2, %tmp.4 102 ; (a+c) 103 %tmp.8 = add i32 %tmp.0, %tmp.4 104 ; (a+c)+b 105 %tmp.11 = add i32 %tmp.8, %tmp.1 106 ; X ^ X = 0 107 %RV = xor i32 %tmp.5, %tmp.11 108 ret i32 %RV 109 110 ; CHECK-LABEL: @test6 111 ; CHECK: ret i32 0 112 } 113 114 ; This should be one add and two multiplies. 115 define i32 @test7(i32 %A, i32 %B, i32 %C) { 116 ; A*A*B + A*C*A 117 %aa = mul i32 %A, %A 118 %aab = mul i32 %aa, %B 119 %ac = mul i32 %A, %C 120 %aac = mul i32 %ac, %A 121 %r = add i32 %aab, %aac 122 ret i32 %r 123 124 ; CHECK-LABEL: @test7 125 ; CHECK-NEXT: add i32 %C, %B 126 ; CHECK-NEXT: mul i32 127 ; CHECK-NEXT: mul i32 128 ; CHECK-NEXT: ret i32 129 } 130 131 define i32 @test8(i32 %X, i32 %Y, i32 %Z) { 132 %A = sub i32 0, %X 133 %B = mul i32 %A, %Y 134 ; (-X)*Y + Z -> Z-X*Y 135 %C = add i32 %B, %Z 136 ret i32 %C 137 138 ; CHECK-LABEL: @test8 139 ; CHECK-NEXT: %A = mul i32 %Y, %X 140 ; CHECK-NEXT: %C = sub i32 %Z, %A 141 ; CHECK-NEXT: ret i32 %C 142 } 143 144 ; PR5458 145 define i32 @test9(i32 %X) { 146 %Y = mul i32 %X, 47 147 %Z = add i32 %Y, %Y 148 ret i32 %Z 149 ; CHECK-LABEL: @test9 150 ; CHECK-NEXT: mul i32 %X, 94 151 ; CHECK-NEXT: ret i32 152 } 153 154 define i32 @test10(i32 %X) { 155 %Y = add i32 %X ,%X 156 %Z = add i32 %Y, %X 157 ret i32 %Z 158 ; CHECK-LABEL: @test10 159 ; CHECK-NEXT: mul i32 %X, 3 160 ; CHECK-NEXT: ret i32 161 } 162 163 define i32 @test11(i32 %W) { 164 %X = mul i32 %W, 127 165 %Y = add i32 %X ,%X 166 %Z = add i32 %Y, %X 167 ret i32 %Z 168 ; CHECK-LABEL: @test11 169 ; CHECK-NEXT: mul i32 %W, 381 170 ; CHECK-NEXT: ret i32 171 } 172 173 declare void @mumble(i32) 174 175 define i32 @test12(i32 %X) { 176 %X.neg = sub nsw nuw i32 0, %X 177 call void @mumble(i32 %X.neg) 178 %A = sub i32 1, %X 179 %B = sub i32 2, %X 180 %C = sub i32 3, %X 181 %Y = add i32 %A ,%B 182 %Z = add i32 %Y, %C 183 ret i32 %Z 184 ; CHECK-LABEL: @test12 185 ; CHECK: %[[mul:.*]] = mul i32 %X, -3 186 ; CHECK-NEXT: add i32 %[[mul]], 6 187 ; CHECK-NEXT: ret i32 188 } 189 190 define i32 @test13(i32 %X1, i32 %X2, i32 %X3) { 191 %A = sub i32 0, %X1 192 %B = mul i32 %A, %X2 ; -X1*X2 193 %C = mul i32 %X1, %X3 ; X1*X3 194 %D = add i32 %B, %C ; -X1*X2 + X1*X3 -> X1*(X3-X2) 195 ret i32 %D 196 ; CHECK-LABEL: @test13 197 ; CHECK-NEXT: sub i32 %X3, %X2 198 ; CHECK-NEXT: mul i32 {{.*}}, %X1 199 ; CHECK-NEXT: ret i32 200 } 201 202 ; PR5359 203 define i32 @test14(i32 %X1, i32 %X2) { 204 %B = mul i32 %X1, 47 ; X1*47 205 %C = mul i32 %X2, -47 ; X2*-47 206 %D = add i32 %B, %C ; X1*47 + X2*-47 -> 47*(X1-X2) 207 ret i32 %D 208 209 ; CHECK-LABEL: @test14 210 ; CHECK-NEXT: %[[SUB:.*]] = sub i32 %X1, %X2 211 ; CHECK-NEXT: mul i32 %[[SUB]], 47 212 ; CHECK-NEXT: ret i32 213 } 214 215 ; Do not reassociate expressions of type i1 216 define i32 @test15(i32 %X1, i32 %X2, i32 %X3) { 217 %A = icmp ne i32 %X1, 0 218 %B = icmp slt i32 %X2, %X3 219 %C = and i1 %A, %B 220 %D = select i1 %C, i32 %X1, i32 0 221 ret i32 %D 222 ; CHECK-LABEL: @test15 223 ; CHECK: and i1 %A, %B 224 } 225