1; RUN: opt < %s -reassociate -gvn -instcombine -S | FileCheck %s 2; RUN: opt < %s -passes='reassociate,gvn,instcombine' -S | FileCheck %s 3 4define 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 14define 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 31define 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 52define 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 73define 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 94define 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. 115define 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 131define 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 145define 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 154define 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 163define 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 173declare void @mumble(i32) 174 175define 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 190define 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 203define 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 216define 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