Value *V1 = Ops.back();
Ops.pop_back();
Value *V2 = EmitAddTreeOfValues(I, Ops);
- return CreateAdd(V2, V1, "tmp", I, I);
+ return CreateAdd(V2, V1, "reass.add", I, I);
}
/// If V is an expression tree that is a multiplication sequence,
RedoInsts.insert(VI);
// Create the multiply.
- Instruction *V2 = CreateMul(V, MaxOccVal, "tmp", I, I);
+ Instruction *V2 = CreateMul(V, MaxOccVal, "reass.mul", I, I);
// Rerun associate on the multiply in case the inner expression turned into
// a multiply. We want to make sure that we keep things in canonical form.
; With reassociation, constant folding can eliminate the 12 and -12 constants.
define float @test1(float %arg) {
-; CHECK-LABEL: @test1
-; CHECK-NEXT: fsub fast float -0.000000e+00, %arg
-; CHECK-NEXT: ret float
-
- %tmp1 = fsub fast float -1.200000e+01, %arg
- %tmp2 = fadd fast float %tmp1, 1.200000e+01
- ret float %tmp2
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[ARG_NEG:%.*]] = fsub fast float -0.000000e+00, %arg
+; CHECK-NEXT: ret float [[ARG_NEG]]
+;
+ %t1 = fsub fast float -1.200000e+01, %arg
+ %t2 = fadd fast float %t1, 1.200000e+01
+ ret float %t2
}
define float @test2(float %reg109, float %reg1111) {
-; CHECK-LABEL: @test2
-; CHECK-NEXT: fadd float %reg109, -3.000000e+01
-; CHECK-NEXT: fadd float %reg115, %reg1111
-; CHECK-NEXT: fadd float %reg116, 3.000000e+01
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: [[REG115:%.*]] = fadd float %reg109, -3.000000e+01
+; CHECK-NEXT: [[REG116:%.*]] = fadd float [[REG115]], %reg1111
+; CHECK-NEXT: [[REG117:%.*]] = fadd float [[REG116]], 3.000000e+01
+; CHECK-NEXT: ret float [[REG117]]
+;
%reg115 = fadd float %reg109, -3.000000e+01
%reg116 = fadd float %reg115, %reg1111
%reg117 = fadd float %reg116, 3.000000e+01
}
define float @test3(float %reg109, float %reg1111) {
-; CHECK-LABEL: @test3
-; CHECK-NEXT: %reg117 = fadd fast float %reg109, %reg1111
-; CHECK-NEXT: ret float %reg117
-
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: [[REG117:%.*]] = fadd fast float %reg109, %reg1111
+; CHECK-NEXT: ret float [[REG117]]
+;
%reg115 = fadd fast float %reg109, -3.000000e+01
%reg116 = fadd fast float %reg115, %reg1111
%reg117 = fadd fast float %reg116, 3.000000e+01
@ff = external global float
define void @test4() {
-; CHECK-LABEL: @test4
-; CHECK: fadd fast float
-; CHECK: fadd fast float
-; CHECK-NOT: fadd fast float
-; CHECK: ret void
-
+; CHECK-LABEL: @test4(
+; CHECK-NEXT: [[A:%.*]] = load float, float* @fa, align 4
+; CHECK-NEXT: [[B:%.*]] = load float, float* @fb, align 4
+; CHECK-NEXT: [[C:%.*]] = load float, float* @fc, align 4
+; CHECK-NEXT: [[T1:%.*]] = fadd fast float [[B]], [[A]]
+; CHECK-NEXT: [[T2:%.*]] = fadd fast float [[T1]], [[C]]
+; CHECK-NEXT: store float [[T2]], float* @fe, align 4
+; CHECK-NEXT: store float [[T2]], float* @ff, align 4
+; CHECK-NEXT: ret void
+;
%A = load float, float* @fa
%B = load float, float* @fb
%C = load float, float* @fc
}
define void @test5() {
-; CHECK-LABEL: @test5
-; CHECK: fadd fast float
-; CHECK: fadd fast float
-; CHECK-NOT: fadd
-; CHECK: ret void
-
+; CHECK-LABEL: @test5(
+; CHECK-NEXT: [[A:%.*]] = load float, float* @fa, align 4
+; CHECK-NEXT: [[B:%.*]] = load float, float* @fb, align 4
+; CHECK-NEXT: [[C:%.*]] = load float, float* @fc, align 4
+; CHECK-NEXT: [[T1:%.*]] = fadd fast float [[B]], [[A]]
+; CHECK-NEXT: [[T2:%.*]] = fadd fast float [[T1]], [[C]]
+; CHECK-NEXT: store float [[T2]], float* @fe, align 4
+; CHECK-NEXT: store float [[T2]], float* @ff, align 4
+; CHECK-NEXT: ret void
+;
%A = load float, float* @fa
%B = load float, float* @fb
%C = load float, float* @fc
}
define void @test6() {
-; CHECK-LABEL: @test6
-; CHECK: fadd fast float
-; CHECK: fadd fast float
-; CHECK-NOT: fadd
-; CHECK: ret void
-
+; CHECK-LABEL: @test6(
+; CHECK-NEXT: [[A:%.*]] = load float, float* @fa, align 4
+; CHECK-NEXT: [[B:%.*]] = load float, float* @fb, align 4
+; CHECK-NEXT: [[C:%.*]] = load float, float* @fc, align 4
+; CHECK-NEXT: [[T1:%.*]] = fadd fast float [[B]], [[A]]
+; CHECK-NEXT: [[T2:%.*]] = fadd fast float [[T1]], [[C]]
+; CHECK-NEXT: store float [[T2]], float* @fe, align 4
+; CHECK-NEXT: store float [[T2]], float* @ff, align 4
+; CHECK-NEXT: ret void
+;
%A = load float, float* @fa
%B = load float, float* @fb
%C = load float, float* @fc
}
define float @test7(float %A, float %B, float %C) {
-; CHECK-LABEL: @test7
-; CHECK-NEXT: fadd fast float %C, %B
-; CHECK-NEXT: fmul fast float %A, %A
-; CHECK-NEXT: fmul fast float %tmp3, %tmp2
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test7(
+; CHECK-NEXT: [[REASS_ADD1:%.*]] = fadd fast float %C, %B
+; CHECK-NEXT: [[REASS_MUL2:%.*]] = fmul fast float %A, %A
+; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast float [[REASS_MUL:%.*]]2, [[REASS_ADD1]]
+; CHECK-NEXT: ret float [[REASS_MUL]]
+;
%aa = fmul fast float %A, %A
%aab = fmul fast float %aa, %B
%ac = fmul fast float %A, %C
}
define float @test8(float %X, float %Y, float %Z) {
-; CHECK-LABEL: @test8
-; CHECK-NEXT: fmul fast float %Y, %X
-; CHECK-NEXT: fsub fast float %Z
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test8(
+; CHECK-NEXT: [[A:%.*]] = fmul fast float %Y, %X
+; CHECK-NEXT: [[C:%.*]] = fsub fast float %Z, [[A]]
+; CHECK-NEXT: ret float [[C]]
+;
%A = fsub fast float 0.0, %X
%B = fmul fast float %A, %Y
; (-X)*Y + Z -> Z-X*Y
}
define float @test9(float %X) {
-; CHECK-LABEL: @test9
-; CHECK-NEXT: fmul fast float %X, 9.400000e+01
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test9(
+; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float %X, 9.400000e+01
+; CHECK-NEXT: ret float [[FACTOR]]
+;
%Y = fmul fast float %X, 4.700000e+01
%Z = fadd fast float %Y, %Y
ret float %Z
}
define float @test10(float %X) {
-; CHECK-LABEL: @test10
-; CHECK-NEXT: fmul fast float %X, 3.000000e+00
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test10(
+; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float %X, 3.000000e+00
+; CHECK-NEXT: ret float [[FACTOR]]
+;
%Y = fadd fast float %X ,%X
%Z = fadd fast float %Y, %X
ret float %Z
}
define float @test11(float %W) {
-; CHECK-LABEL: test11
-; CHECK-NEXT: fmul fast float %W, 3.810000e+02
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test11(
+; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float %W, 3.810000e+02
+; CHECK-NEXT: ret float [[FACTOR]]
+;
%X = fmul fast float %W, 127.0
%Y = fadd fast float %X ,%X
%Z = fadd fast float %Y, %X
}
define float @test12(float %X) {
-; CHECK-LABEL: @test12
-; CHECK-NEXT: fmul fast float %X, -3.000000e+00
-; CHECK-NEXT: fadd fast float %factor, 6.000000e+00
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test12(
+; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float %X, -3.000000e+00
+; CHECK-NEXT: [[Z:%.*]] = fadd fast float [[FACTOR]], 6.000000e+00
+; CHECK-NEXT: ret float [[Z]]
+;
%A = fsub fast float 1.000000e+00, %X
%B = fsub fast float 2.000000e+00, %X
%C = fsub fast float 3.000000e+00, %X
}
define float @test13(float %X1, float %X2, float %X3) {
-; CHECK-LABEL: @test13
-; CHECK-NEXT: fsub fast float %X3, %X2
-; CHECK-NEXT: fmul fast float {{.*}}, %X1
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test13(
+; CHECK-NEXT: [[REASS_ADD:%.*]] = fsub fast float %X3, %X2
+; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast float [[REASS_ADD]], %X1
+; CHECK-NEXT: ret float [[REASS_MUL]]
+;
%A = fsub fast float 0.000000e+00, %X1
%B = fmul fast float %A, %X2 ; -X1*X2
%C = fmul fast float %X1, %X3 ; X1*X3
}
define float @test14(float %X1, float %X2) {
-; CHECK-LABEL: @test14
-; CHECK-NEXT: fsub fast float %X1, %X2
-; CHECK-NEXT: fmul fast float %1, 4.700000e+01
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test14(
+; CHECK-NEXT: [[TMP1:%.*]] = fsub fast float %X1, %X2
+; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float [[TMP1]], 4.700000e+01
+; CHECK-NEXT: ret float [[TMP2]]
+;
%B = fmul fast float %X1, 47. ; X1*47
%C = fmul fast float %X2, -47. ; X2*-47
%D = fadd fast float %B, %C ; X1*47 + X2*-47 -> 47*(X1-X2)
}
define float @test15(float %arg) {
-; CHECK-LABEL: test15
-; CHECK-NEXT: fmul fast float %arg, 1.440000e+02
-; CHECK-NEXT: ret float %tmp2
-
- %tmp1 = fmul fast float 1.200000e+01, %arg
- %tmp2 = fmul fast float %tmp1, 1.200000e+01
- ret float %tmp2
+; CHECK-LABEL: @test15(
+; CHECK-NEXT: [[T2:%.*]] = fmul fast float %arg, 1.440000e+02
+; CHECK-NEXT: ret float [[T2]]
+;
+ %t1 = fmul fast float 1.200000e+01, %arg
+ %t2 = fmul fast float %t1, 1.200000e+01
+ ret float %t2
}
; (b+(a+1234))+-a -> b+1234
define float @test16(float %b, float %a) {
-; CHECK-LABEL: @test16
-; CHECK-NEXT: fadd fast float %b, 1.234000e+03
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: [[TMP1:%.*]] = fadd fast float %b, 1.234000e+03
+; CHECK-NEXT: ret float [[TMP1]]
+;
%1 = fadd fast float %a, 1234.0
%2 = fadd fast float %b, %1
%3 = fsub fast float 0.0, %a
; Test that we can turn things like X*-(Y*Z) -> X*-1*Y*Z.
define float @test17(float %a, float %b, float %z) {
-; CHECK-LABEL: test17
-; CHECK-NEXT: fmul fast float %a, 1.234500e+04
-; CHECK-NEXT: fmul fast float %e, %b
-; CHECK-NEXT: fmul fast float %f, %z
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: [[E:%.*]] = fmul fast float %a, 1.234500e+04
+; CHECK-NEXT: [[F:%.*]] = fmul fast float [[E]], %b
+; CHECK-NEXT: [[G:%.*]] = fmul fast float [[F]], %z
+; CHECK-NEXT: ret float [[G]]
+;
%c = fsub fast float 0.000000e+00, %z
%d = fmul fast float %a, %b
%e = fmul fast float %c, %d
}
define float @test18(float %a, float %b, float %z) {
-; CHECK-LABEL: test18
-; CHECK-NEXT: fmul fast float %a, 4.000000e+01
-; CHECK-NEXT: fmul fast float %e, %z
-; CHECK-NEXT: ret float
-
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: [[E:%.*]] = fmul fast float %a, 4.000000e+01
+; CHECK-NEXT: [[F:%.*]] = fmul fast float [[E]], %z
+; CHECK-NEXT: ret float [[F]]
+;
%d = fmul fast float %z, 4.000000e+01
%c = fsub fast float 0.000000e+00, %d
%e = fmul fast float %a, %c
; With sub reassociation, constant folding can eliminate the 12 and -12 constants.
define float @test19(float %A, float %B) {
-; CHECK-LABEL: @test19
-; CHECK-NEXT: fsub fast float %A, %B
-; CHECK-NEXT: ret float
+; CHECK-LABEL: @test19(
+; CHECK-NEXT: [[Z:%.*]] = fsub fast float %A, %B
+; CHECK-NEXT: ret float [[Z]]
+;
%X = fadd fast float -1.200000e+01, %A
%Y = fsub fast float %X, %B
%Z = fadd fast float %Y, 1.200000e+01
; With sub reassociation, constant folding can eliminate the uses of %a.
define float @test20(float %a, float %b, float %c) nounwind {
-; CHECK-LABEL: @test20
-; CHECK-NEXT: fsub fast float -0.000000e+00, %b
-; CHECK-NEXT: fsub fast float %b.neg, %c
-; CHECK-NEXT: ret float
-
; FIXME: Should be able to generate the below, which may expose more
; opportunites for FAdd reassociation.
; %sum = fadd fast float %c, %b
-; %tmp7 = fsub fast float 0, %sum
-
- %tmp3 = fsub fast float %a, %b
- %tmp5 = fsub fast float %tmp3, %c
- %tmp7 = fsub fast float %tmp5, %a
- ret float %tmp7
+; %t7 = fsub fast float 0, %sum
+; CHECK-LABEL: @test20(
+; CHECK-NEXT: [[B_NEG:%.*]] = fsub fast float -0.000000e+00, %b
+; CHECK-NEXT: [[T7:%.*]] = fsub fast float [[B_NEG]], %c
+; CHECK-NEXT: ret float [[T7]]
+;
+ %t3 = fsub fast float %a, %b
+ %t5 = fsub fast float %t3, %c
+ %t7 = fsub fast float %t5, %a
+ ret float %t7
}
declare void @use(float)
define void @test1(float %x, float %y) {
-; CHECK-LABEL: test1
-; CHECK: fmul fast float %y, %x
-; CHECK: fmul fast float %y, %x
-; CHECK: fsub fast float %1, %2
-; CHECK: call void @use(float %{{.*}})
-; CHECK: call void @use(float %{{.*}})
-
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float %y, %x
+; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float %y, %x
+; CHECK-NEXT: [[TMP3:%.*]] = fsub fast float [[TMP1]], [[TMP2]]
+; CHECK-NEXT: call void @use(float [[TMP1]])
+; CHECK-NEXT: call void @use(float [[TMP3]])
+; CHECK-NEXT: ret void
+;
%1 = fmul fast float %x, %y
%2 = fmul fast float %y, %x
%3 = fsub fast float %1, %2
}
define float @test2(float %x, float %y) {
-; CHECK-LABEL: test2
-; CHECK-NEXT: fmul fast float %y, %x
-; CHECK-NEXT: fmul fast float %y, %x
-; CHECK-NEXT: fsub fast float %1, %2
-; CHECK-NEXT: ret float %3
-
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float %y, %x
+; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float %y, %x
+; CHECK-NEXT: [[TMP3:%.*]] = fsub fast float [[TMP1]], [[TMP2]]
+; CHECK-NEXT: ret float [[TMP3]]
+;
%1 = fmul fast float %x, %y
%2 = fmul fast float %y, %x
%3 = fsub fast float %1, %2
}
define float @test3(float %x, float %y) {
-; CHECK-LABEL: test3
-; CHECK-NEXT: %factor = fmul fast float %x, 2.000000e+00
-; CHECK-NEXT: %tmp1 = fmul fast float %factor, %y
-; CHECK-NEXT: ret float %tmp1
-
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float %x, 2.000000e+00
+; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast float [[FACTOR]], %y
+; CHECK-NEXT: ret float [[REASS_MUL]]
+;
%1 = fmul fast float %x, %y
%2 = fmul fast float %y, %x
%3 = fadd fast float %1, %2
ret float %3
}
+
; RUN: opt < %s -reassociate -S | FileCheck %s
-define float @fmultistep1(float %a, float %b, float %c) {
; Check that a*a*b+a*a*c is turned into a*(a*(b+c)).
-; CHECK-LABEL: @fmultistep1
-; CHECK-NEXT: [[TMP1:%tmp.*]] = fadd fast float %c, %b
-; CHECK-NEXT: [[TMP2:%tmp.*]] = fmul fast float %a, %a
-; CHECK-NEXT: fmul fast float [[TMP2]], [[TMP1]]
-; CHECK-NEXT: ret float
+define float @fmultistep1(float %a, float %b, float %c) {
+; CHECK-LABEL: @fmultistep1(
+; CHECK-NEXT: [[REASS_ADD1:%.*]] = fadd fast float %c, %b
+; CHECK-NEXT: [[REASS_MUL2:%.*]] = fmul fast float %a, %a
+; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast float [[REASS_MUL:%.*]]2, [[REASS_ADD1]]
+; CHECK-NEXT: ret float [[REASS_MUL]]
+;
%t0 = fmul fast float %a, %b
%t1 = fmul fast float %a, %t0 ; a*(a*b)
%t2 = fmul fast float %a, %c
ret float %t4
}
-define float @fmultistep2(float %a, float %b, float %c, float %d) {
; Check that a*b+a*c+d is turned into a*(b+c)+d.
-; CHECK-LABEL: @fmultistep2
-; CHECK-NEXT: fadd fast float %c, %b
-; CHECK-NEXT: fmul fast float %tmp, %a
-; CHECK-NEXT: fadd fast float %tmp1, %d
-; CHECK-NEXT: ret float
+define float @fmultistep2(float %a, float %b, float %c, float %d) {
+; CHECK-LABEL: @fmultistep2(
+; CHECK-NEXT: [[REASS_ADD:%.*]] = fadd fast float %c, %b
+; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast float [[REASS_ADD]], %a
+; CHECK-NEXT: [[T3:%.*]] = fadd fast float [[REASS_MUL]], %d
+; CHECK-NEXT: ret float [[T3]]
+;
%t0 = fmul fast float %a, %b
%t1 = fmul fast float %a, %c
%t2 = fadd fast float %t1, %d ; a*c+d
%t3 = fadd fast float %t0, %t2 ; a*b+(a*c+d)
ret float %t3
}
+
; RUN: opt -reassociate %s -S | FileCheck %s
define float @foo(float %a,float %b, float %c) {
-; CHECK: %mul3 = fmul float %a, %b
-; CHECK-NEXT: fmul fast float %c, 2.000000e+00
-; CHECK-NEXT: fadd fast float %factor, %b
-; CHECK-NEXT: fmul fast float %tmp1, %a
-; CHECK-NEXT: fadd fast float %tmp2, %mul3
-; CHECK-NEXT: ret float
+; CHECK-LABEL: @foo(
+; CHECK-NEXT: [[MUL3:%.*]] = fmul float %a, %b
+; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float %c, 2.000000e+00
+; CHECK-NEXT: [[REASS_ADD1:%.*]] = fadd fast float [[FACTOR]], %b
+; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast float [[REASS_ADD1]], %a
+; CHECK-NEXT: [[ADD3:%.*]] = fadd fast float [[REASS_MUL]], [[MUL3]]
+; CHECK-NEXT: ret float [[ADD3]]
+;
%mul1 = fmul fast float %a, %c
%mul2 = fmul fast float %a, %b
%mul3 = fmul float %a, %b
define i32 @test1(i32 %a, i32 %b) {
; CHECK-LABEL: @test1(
-; CHECK: mul i32 %a, %a
-; CHECK-NEXT: mul i32 %a, 2
-; CHECK-NEXT: add
-; CHECK-NEXT: mul
-; CHECK-NEXT: add
-; CHECK-NEXT: ret
-
-entry:
- %tmp.2 = mul i32 %a, %a
- %tmp.5 = shl i32 %a, 1
- %tmp.6 = mul i32 %tmp.5, %b
- %tmp.10 = mul i32 %b, %b
- %tmp.7 = add i32 %tmp.6, %tmp.2
- %tmp.11 = add i32 %tmp.7, %tmp.10
- ret i32 %tmp.11
+; CHECK-NEXT: [[T2:%.*]] = mul i32 %a, %a
+; CHECK-NEXT: [[T6:%.*]] = mul i32 %a, 2
+; CHECK-NEXT: [[REASS_ADD:%.*]] = add i32 [[T6]], %b
+; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 [[REASS_ADD]], %b
+; CHECK-NEXT: [[T11:%.*]] = add i32 [[REASS_MUL]], [[T2]]
+; CHECK-NEXT: ret i32 [[T11]]
+;
+ %t2 = mul i32 %a, %a
+ %t5 = shl i32 %a, 1
+ %t6 = mul i32 %t5, %b
+ %t8 = mul i32 %b, %b
+ %t7 = add i32 %t6, %t2
+ %t11 = add i32 %t7, %t8
+ ret i32 %t11
}
define i32 @test2(i32 %t) {
; CHECK-LABEL: @test2(
-; CHECK: mul
-; CHECK-NEXT: add
-; CHECK-NEXT: ret
-
-entry:
- %a = mul i32 %t, 6
- %b = mul i32 %t, 36
- %c = add i32 %b, 15
- %d = add i32 %c, %a
- ret i32 %d
+; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 %t, 42
+; CHECK-NEXT: [[D:%.*]] = add i32 [[REASS_MUL]], 15
+; CHECK-NEXT: ret i32 [[D]]
+;
+ %a = mul i32 %t, 6
+ %b = mul i32 %t, 36
+ %c = add i32 %b, 15
+ %d = add i32 %c, %a
+ ret i32 %d
}
-define i32 @test3(i32 %x) {
; (x^8)
+define i32 @test3(i32 %x) {
; CHECK-LABEL: @test3(
-; CHECK: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: ret
-
-entry:
+; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
+; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
+; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP2]]
+; CHECK-NEXT: ret i32 [[TMP3]]
+;
%a = mul i32 %x, %x
%b = mul i32 %a, %x
%c = mul i32 %b, %x
ret i32 %g
}
-define i32 @test4(i32 %x) {
; (x^7)
+define i32 @test4(i32 %x) {
; CHECK-LABEL: @test4(
-; CHECK: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: ret
-
-entry:
+; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
+; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], %x
+; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[TMP2]], %x
+; CHECK-NEXT: [[F:%.*]] = mul i32 [[TMP3]], [[TMP2]]
+; CHECK-NEXT: ret i32 [[F]]
+;
%a = mul i32 %x, %x
%b = mul i32 %a, %x
%c = mul i32 %b, %x
ret i32 %f
}
-define i32 @test5(i32 %x, i32 %y) {
; (x^4) * (y^2)
+define i32 @test5(i32 %x, i32 %y) {
; CHECK-LABEL: @test5(
-; CHECK: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: ret
-
-entry:
+; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
+; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], %y
+; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP2]]
+; CHECK-NEXT: ret i32 [[TMP3]]
+;
%a = mul i32 %x, %y
%b = mul i32 %a, %y
%c = mul i32 %b, %x
ret i32 %e
}
-define i32 @test6(i32 %x, i32 %y, i32 %z) {
; (x^5) * (y^3) * z
+define i32 @test6(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @test6(
-; CHECK: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: ret
-
-entry:
+; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
+; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], %y
+; CHECK-NEXT: [[F:%.*]] = mul i32 %y, %x
+; CHECK-NEXT: [[G:%.*]] = mul i32 [[F]], [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[G]], [[TMP2]]
+; CHECK-NEXT: [[H:%.*]] = mul i32 [[TMP3]], %z
+; CHECK-NEXT: ret i32 [[H]]
+;
%a = mul i32 %x, %y
%b = mul i32 %a, %x
%c = mul i32 %b, %y
ret i32 %h
}
-define i32 @test7(i32 %x, i32 %y, i32 %z) {
; (x^4) * (y^3) * (z^2)
+define i32 @test7(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @test7(
-; CHECK: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: mul
-; CHECK-NEXT: ret
-
-entry:
+; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
+; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], %y
+; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[TMP2]], %z
+; CHECK-NEXT: [[TMP4:%.*]] = mul i32 [[TMP3]], %y
+; CHECK-NEXT: [[H:%.*]] = mul i32 [[TMP4]], [[TMP3]]
+; CHECK-NEXT: ret i32 [[H]]
+;
%a = mul i32 %y, %x
%b = mul i32 %a, %z
%c = mul i32 %b, %z
%h = mul i32 %g, %x
ret i32 %h
}
+
; RUN: opt < %s -reassociate -S | FileCheck %s
-define i64 @multistep1(i64 %a, i64 %b, i64 %c) {
; Check that a*a*b+a*a*c is turned into a*(a*(b+c)).
+
+define i64 @multistep1(i64 %a, i64 %b, i64 %c) {
; CHECK-LABEL: @multistep1(
+; CHECK-NEXT: [[REASS_ADD1:%.*]] = add i64 %c, %b
+; CHECK-NEXT: [[REASS_MUL2:%.*]] = mul i64 %a, %a
+; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i64 [[REASS_MUL:%.*]]2, [[REASS_ADD1]]
+; CHECK-NEXT: ret i64 [[REASS_MUL]]
+;
%t0 = mul i64 %a, %b
%t1 = mul i64 %a, %t0 ; a*(a*b)
%t2 = mul i64 %a, %c
%t3 = mul i64 %a, %t2 ; a*(a*c)
%t4 = add i64 %t1, %t3
-; CHECK-NEXT: [[TMP1:%tmp.*]] = add i64 %c, %b
-; CHECK-NEXT: [[TMP2:%tmp.*]] = mul i64 %a, %a
-; CHECK-NEXT: mul i64 [[TMP2]], [[TMP1]]
-; CHECK-NEXT: ret
ret i64 %t4
}
-define i64 @multistep2(i64 %a, i64 %b, i64 %c, i64 %d) {
; Check that a*b+a*c+d is turned into a*(b+c)+d.
+
+define i64 @multistep2(i64 %a, i64 %b, i64 %c, i64 %d) {
; CHECK-LABEL: @multistep2(
+; CHECK-NEXT: [[REASS_ADD:%.*]] = add i64 %c, %b
+; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i64 [[REASS_ADD]], %a
+; CHECK-NEXT: [[T3:%.*]] = add i64 [[REASS_MUL]], %d
+; CHECK-NEXT: ret i64 [[T3]]
+;
%t0 = mul i64 %a, %b
%t1 = mul i64 %a, %c
%t2 = add i64 %t1, %d ; a*c+d
%t3 = add i64 %t0, %t2 ; a*b+(a*c+d)
-; CHECK-NEXT: add i64 %c, %b
-; CHECK-NEXT: mul i64 %tmp{{.*}}, %a
-; CHECK-NEXT: add i64 %tmp{{.*}}, %d
-; CHECK-NEXT: ret
ret i64 %t3
}
+
; RUN: opt < %s -reassociate -S | FileCheck %s
-; CHECK-LABEL: faddsubAssoc1
-; CHECK: [[TMP1:%tmp.*]] = fmul fast half %a, 0xH4500
-; CHECK: [[TMP2:%tmp.*]] = fmul fast half %b, 0xH4500
-; CHECK: fsub fast half [[TMP2]], [[TMP1]]
-; CHECK: ret
+
; Input is A op (B op C)
+
define half @faddsubAssoc1(half %a, half %b) {
- %tmp1 = fmul fast half %b, 0xH4200 ; 3*b
- %tmp2 = fmul fast half %a, 0xH4500 ; 5*a
- %tmp3 = fmul fast half %b, 0xH4000 ; 2*b
- %tmp4 = fsub fast half %tmp2, %tmp1 ; 5 * a - 3 * b
- %tmp5 = fsub fast half %tmp3, %tmp4 ; 2 * b - ( 5 * a - 3 * b)
- ret half %tmp5 ; = 5 * (b - a)
+; CHECK-LABEL: @faddsubAssoc1(
+; CHECK-NEXT: [[T2_NEG:%.*]] = fmul fast half %a, 0xH4500
+; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast half %b, 0xH4500
+; CHECK-NEXT: [[T51:%.*]] = fsub fast half [[REASS_MUL]], [[T2_NEG]]
+; CHECK-NEXT: [[T5:%.*]] = fadd fast half [[REASS_MUL]], [[T2_NEG]]
+; CHECK-NEXT: ret half [[T51]]
+;
+ %t1 = fmul fast half %b, 0xH4200 ; 3*b
+ %t2 = fmul fast half %a, 0xH4500 ; 5*a
+ %t3 = fmul fast half %b, 0xH4000 ; 2*b
+ %t4 = fsub fast half %t2, %t1 ; 5 * a - 3 * b
+ %t5 = fsub fast half %t3, %t4 ; 2 * b - ( 5 * a - 3 * b)
+ ret half %t5 ; = 5 * (b - a)
}
-; CHECK-LABEL: faddsubAssoc2
-; CHECK: [[TMP1:%tmp.*]] = fmul fast half %a, 0xH4500
-; CHECK: [[TMP2:%tmp.*]] = fmul fast half %b, 0xH3C00
-; CHECK: fadd fast half [[TMP2]], [[TMP1]]
-; CHECK: ret
; Input is (A op B) op C
+
define half @faddsubAssoc2(half %a, half %b) {
- %tmp1 = fmul fast half %b, 0xH4200 ; 3*b
- %tmp2 = fmul fast half %a, 0xH4500 ; 5*a
- %tmp3 = fmul fast half %b, 0xH4000 ; 2*b
- %tmp4 = fadd fast half %tmp2, %tmp1 ; 5 * a + 3 * b
- %tmp5 = fsub fast half %tmp4, %tmp3 ; (5 * a + 3 * b) - (2 * b)
- ret half %tmp5 ; = 5 * a + b
+; CHECK-LABEL: @faddsubAssoc2(
+; CHECK-NEXT: [[T2:%.*]] = fmul fast half %a, 0xH4500
+; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast half %b, 0xH3C00
+; CHECK-NEXT: [[T5:%.*]] = fadd fast half [[REASS_MUL]], [[T2]]
+; CHECK-NEXT: ret half [[T5]]
+;
+ %t1 = fmul fast half %b, 0xH4200 ; 3*b
+ %t2 = fmul fast half %a, 0xH4500 ; 5*a
+ %t3 = fmul fast half %b, 0xH4000 ; 2*b
+ %t4 = fadd fast half %t2, %t1 ; 5 * a + 3 * b
+ %t5 = fsub fast half %t4, %t3 ; (5 * a + 3 * b) - (2 * b)
+ ret half %t5 ; = 5 * a + b
}
-; There should be exactly one shift and one add left.
; RUN: opt < %s -reassociate -instcombine -S | FileCheck %s
-define i32 @test1(i32 %X, i32 %Y) {
-; CHECK-LABEL: test1
-; CHECK-NEXT: %tmp = add i32 %Y, %X
-; CHECK-NEXT: %tmp1 = shl i32 %tmp, 1
-; CHECK-NEXT: ret i32 %tmp1
+; There should be exactly one shift and one add left.
- %tmp.2 = shl i32 %X, 1
- %tmp.6 = shl i32 %Y, 1
- %tmp.4 = add i32 %tmp.6, %tmp.2
- ret i32 %tmp.4
+define i32 @test1(i32 %X, i32 %Y) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: [[REASS_ADD:%.*]] = add i32 %Y, %X
+; CHECK-NEXT: [[REASS_MUL:%.*]] = shl i32 [[REASS_ADD]], 1
+; CHECK-NEXT: ret i32 [[REASS_MUL]]
+;
+ %t2 = shl i32 %X, 1
+ %t6 = shl i32 %Y, 1
+ %t4 = add i32 %t6, %t2
+ ret i32 %t4
}
+