canonicalize-neg-const.ll had some issues. The script somehow decided to delete half the run line and merge it with the example expression (which it also deleted most of).
298 lines
7.6 KiB
LLVM
298 lines
7.6 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -reassociate -gvn -instcombine -S | FileCheck %s
|
|
; RUN: opt < %s -passes='reassociate,gvn,instcombine' -S | FileCheck %s
|
|
|
|
define i32 @test1(i32 %arg) {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: [[ARG_NEG:%.*]] = sub i32 0, [[ARG:%.*]]
|
|
; CHECK-NEXT: ret i32 [[ARG_NEG]]
|
|
;
|
|
%tmp1 = sub i32 -12, %arg
|
|
%tmp2 = add i32 %tmp1, 12
|
|
ret i32 %tmp2
|
|
}
|
|
|
|
define i32 @test2(i32 %reg109, i32 %reg1111) {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: [[REG117:%.*]] = add i32 [[REG1111:%.*]], [[REG109:%.*]]
|
|
; CHECK-NEXT: ret i32 [[REG117]]
|
|
;
|
|
%reg115 = add i32 %reg109, -30
|
|
%reg116 = add i32 %reg115, %reg1111
|
|
%reg117 = add i32 %reg116, 30
|
|
ret i32 %reg117
|
|
}
|
|
|
|
@e = external global i32
|
|
@a = external global i32
|
|
@b = external global i32
|
|
@c = external global i32
|
|
@f = external global i32
|
|
|
|
define void @test3() {
|
|
; CHECK-LABEL: @test3(
|
|
; CHECK-NEXT: [[A:%.*]] = load i32, ptr @a, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = load i32, ptr @b, align 4
|
|
; CHECK-NEXT: [[C:%.*]] = load i32, ptr @c, align 4
|
|
; CHECK-NEXT: [[T1:%.*]] = add i32 [[B]], [[A]]
|
|
; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[C]]
|
|
; CHECK-NEXT: store i32 [[T2]], ptr @e, align 4
|
|
; CHECK-NEXT: store i32 [[T2]], ptr @f, align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%A = load i32, ptr @a
|
|
%B = load i32, ptr @b
|
|
%C = load i32, ptr @c
|
|
%t1 = add i32 %A, %B
|
|
%t2 = add i32 %t1, %C
|
|
%t3 = add i32 %C, %A
|
|
%t4 = add i32 %t3, %B
|
|
; e = (a+b)+c;
|
|
store i32 %t2, ptr @e
|
|
; f = (a+c)+b
|
|
store i32 %t4, ptr @f
|
|
ret void
|
|
}
|
|
|
|
define void @test4() {
|
|
; CHECK-LABEL: @test4(
|
|
; CHECK-NEXT: [[A:%.*]] = load i32, ptr @a, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = load i32, ptr @b, align 4
|
|
; CHECK-NEXT: [[C:%.*]] = load i32, ptr @c, align 4
|
|
; CHECK-NEXT: [[T1:%.*]] = add i32 [[B]], [[A]]
|
|
; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[C]]
|
|
; CHECK-NEXT: store i32 [[T2]], ptr @e, align 4
|
|
; CHECK-NEXT: store i32 [[T2]], ptr @f, align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%A = load i32, ptr @a
|
|
%B = load i32, ptr @b
|
|
%C = load i32, ptr @c
|
|
%t1 = add i32 %A, %B
|
|
%t2 = add i32 %t1, %C
|
|
%t3 = add i32 %C, %A
|
|
%t4 = add i32 %t3, %B
|
|
; e = c+(a+b)
|
|
store i32 %t2, ptr @e
|
|
; f = (c+a)+b
|
|
store i32 %t4, ptr @f
|
|
ret void
|
|
}
|
|
|
|
define void @test5() {
|
|
; CHECK-LABEL: @test5(
|
|
; CHECK-NEXT: [[A:%.*]] = load i32, ptr @a, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = load i32, ptr @b, align 4
|
|
; CHECK-NEXT: [[C:%.*]] = load i32, ptr @c, align 4
|
|
; CHECK-NEXT: [[T1:%.*]] = add i32 [[B]], [[A]]
|
|
; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[C]]
|
|
; CHECK-NEXT: store i32 [[T2]], ptr @e, align 4
|
|
; CHECK-NEXT: store i32 [[T2]], ptr @f, align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%A = load i32, ptr @a
|
|
%B = load i32, ptr @b
|
|
%C = load i32, ptr @c
|
|
%t1 = add i32 %B, %A
|
|
%t2 = add i32 %t1, %C
|
|
%t3 = add i32 %C, %A
|
|
%t4 = add i32 %t3, %B
|
|
; e = c+(b+a)
|
|
store i32 %t2, ptr @e
|
|
; f = (c+a)+b
|
|
store i32 %t4, ptr @f
|
|
ret void
|
|
}
|
|
|
|
define i32 @test6() {
|
|
; CHECK-LABEL: @test6(
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
%tmp.0 = load i32, ptr @a
|
|
%tmp.1 = load i32, ptr @b
|
|
; (a+b)
|
|
%tmp.2 = add i32 %tmp.0, %tmp.1
|
|
%tmp.4 = load i32, ptr @c
|
|
; (a+b)+c
|
|
%tmp.5 = add i32 %tmp.2, %tmp.4
|
|
; (a+c)
|
|
%tmp.8 = add i32 %tmp.0, %tmp.4
|
|
; (a+c)+b
|
|
%tmp.11 = add i32 %tmp.8, %tmp.1
|
|
; X ^ X = 0
|
|
%RV = xor i32 %tmp.5, %tmp.11
|
|
ret i32 %RV
|
|
}
|
|
|
|
; This should be one add and two multiplies.
|
|
; A*A*B + A*C*A
|
|
|
|
define i32 @test7(i32 %A, i32 %B, i32 %C) {
|
|
; CHECK-LABEL: @test7(
|
|
; CHECK-NEXT: [[REASS_ADD1:%.*]] = add i32 [[C:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[REASS_MUL2:%.*]] = mul i32 [[A:%.*]], [[A]]
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 [[REASS_MUL2]], [[REASS_ADD1]]
|
|
; CHECK-NEXT: ret i32 [[REASS_MUL]]
|
|
;
|
|
%aa = mul i32 %A, %A
|
|
%aab = mul i32 %aa, %B
|
|
%ac = mul i32 %A, %C
|
|
%aac = mul i32 %ac, %A
|
|
%r = add i32 %aab, %aac
|
|
ret i32 %r
|
|
}
|
|
|
|
define i32 @test8(i32 %X, i32 %Y, i32 %Z) {
|
|
; CHECK-LABEL: @test8(
|
|
; CHECK-NEXT: [[A:%.*]] = mul i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[C:%.*]] = sub i32 [[Z:%.*]], [[A]]
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
%A = sub i32 0, %X
|
|
%B = mul i32 %A, %Y
|
|
; (-X)*Y + Z -> Z-X*Y
|
|
%C = add i32 %B, %Z
|
|
ret i32 %C
|
|
}
|
|
|
|
; PR5458
|
|
|
|
define i32 @test9(i32 %X) {
|
|
; CHECK-LABEL: @test9(
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i32 [[X:%.*]], 94
|
|
; CHECK-NEXT: ret i32 [[FACTOR]]
|
|
;
|
|
%Y = mul i32 %X, 47
|
|
%Z = add i32 %Y, %Y
|
|
ret i32 %Z
|
|
}
|
|
|
|
define i32 @test10(i32 %X) {
|
|
; CHECK-LABEL: @test10(
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i32 [[X:%.*]], 3
|
|
; CHECK-NEXT: ret i32 [[FACTOR]]
|
|
;
|
|
%Y = add i32 %X ,%X
|
|
%Z = add i32 %Y, %X
|
|
ret i32 %Z
|
|
}
|
|
|
|
define i32 @test11(i32 %W) {
|
|
; CHECK-LABEL: @test11(
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i32 [[W:%.*]], 381
|
|
; CHECK-NEXT: ret i32 [[FACTOR]]
|
|
;
|
|
%X = mul i32 %W, 127
|
|
%Y = add i32 %X ,%X
|
|
%Z = add i32 %Y, %X
|
|
ret i32 %Z
|
|
}
|
|
|
|
declare void @mumble(i32)
|
|
|
|
define i32 @test12(i32 %X) {
|
|
; CHECK-LABEL: @test12(
|
|
; CHECK-NEXT: [[X_NEG:%.*]] = sub i32 0, [[X:%.*]]
|
|
; CHECK-NEXT: call void @mumble(i32 [[X_NEG]])
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i32 [[X]], -3
|
|
; CHECK-NEXT: [[Z:%.*]] = add i32 [[FACTOR]], 6
|
|
; CHECK-NEXT: ret i32 [[Z]]
|
|
;
|
|
%X.neg = sub nsw nuw i32 0, %X
|
|
call void @mumble(i32 %X.neg)
|
|
%A = sub i32 1, %X
|
|
%B = sub i32 2, %X
|
|
%C = sub i32 3, %X
|
|
%Y = add i32 %A ,%B
|
|
%Z = add i32 %Y, %C
|
|
ret i32 %Z
|
|
}
|
|
|
|
define i32 @test13(i32 %X1, i32 %X2, i32 %X3) {
|
|
; CHECK-LABEL: @test13(
|
|
; CHECK-NEXT: [[REASS_ADD:%.*]] = sub i32 [[X3:%.*]], [[X2:%.*]]
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 [[REASS_ADD]], [[X1:%.*]]
|
|
; CHECK-NEXT: ret i32 [[REASS_MUL]]
|
|
;
|
|
%A = sub i32 0, %X1
|
|
%B = mul i32 %A, %X2 ; -X1*X2
|
|
%C = mul i32 %X1, %X3 ; X1*X3
|
|
%D = add i32 %B, %C ; -X1*X2 + X1*X3 -> X1*(X3-X2)
|
|
ret i32 %D
|
|
}
|
|
|
|
; PR5359
|
|
|
|
define i32 @test14(i32 %X1, i32 %X2) {
|
|
; CHECK-LABEL: @test14(
|
|
; CHECK-NEXT: [[REASS_ADD:%.*]] = sub i32 [[X1:%.*]], [[X2:%.*]]
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 [[REASS_ADD]], 47
|
|
; CHECK-NEXT: ret i32 [[REASS_MUL]]
|
|
;
|
|
%B = mul i32 %X1, 47 ; X1*47
|
|
%C = mul i32 %X2, -47 ; X2*-47
|
|
%D = add i32 %B, %C ; X1*47 + X2*-47 -> 47*(X1-X2)
|
|
ret i32 %D
|
|
}
|
|
|
|
; Do not reassociate expressions of type i1
|
|
|
|
define i32 @test15(i32 %X1, i32 %X2, i32 %X3) {
|
|
; CHECK-LABEL: @test15(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X1:%.*]], 0
|
|
; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[X2:%.*]], [[X3:%.*]]
|
|
; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
|
|
; CHECK-NEXT: [[D:%.*]] = select i1 [[C]], i32 [[X1]], i32 0
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp ne i32 %X1, 0
|
|
%B = icmp slt i32 %X2, %X3
|
|
%C = and i1 %A, %B
|
|
%D = select i1 %C, i32 %X1, i32 0
|
|
ret i32 %D
|
|
}
|
|
|
|
; PR30256 - previously this asserted.
|
|
|
|
define i64 @test16(i1 %cmp, i64 %a, i64 %b) {
|
|
; CHECK-LABEL: @test16(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = shl i64 [[A:%.*]], 2
|
|
; CHECK-NEXT: [[ADD2:%.*]] = sub i64 [[B:%.*]], [[TMP0]]
|
|
; CHECK-NEXT: ret i64 [[ADD2]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret i64 0
|
|
;
|
|
entry:
|
|
%shl = shl i64 %a, 1
|
|
%shl.neg = sub i64 0, %shl
|
|
br i1 %cmp, label %if.then, label %if.end
|
|
|
|
if.then:
|
|
%add1 = add i64 %shl.neg, %shl.neg
|
|
%add2 = add i64 %add1, %b
|
|
ret i64 %add2
|
|
|
|
if.end:
|
|
ret i64 0
|
|
}
|
|
|
|
define i32 @test17(i32 %X1, i32 %X2, i32 %X3, i32 %X4) {
|
|
; CHECK-LABEL: @test17(
|
|
; CHECK-NEXT: [[A:%.*]] = mul i32 [[X4:%.*]], [[X3:%.*]]
|
|
; CHECK-NEXT: [[C:%.*]] = mul i32 [[A]], [[X1:%.*]]
|
|
; CHECK-NEXT: [[D:%.*]] = mul i32 [[A]], [[X2:%.*]]
|
|
; CHECK-NEXT: [[E:%.*]] = xor i32 [[C]], [[D]]
|
|
; CHECK-NEXT: ret i32 [[E]]
|
|
;
|
|
%A = mul i32 %X3, %X1
|
|
%B = mul i32 %X3, %X2
|
|
%C = mul i32 %A, %X4
|
|
%D = mul i32 %B, %X4
|
|
%E = xor i32 %C, %D
|
|
ret i32 %E
|
|
}
|
|
|