1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[Tests] Autogen a bunch of Reassociate tests for ease of update

llvm-svn: 367634
This commit is contained in:
Philip Reames 2019-08-01 23:30:32 +00:00
parent 61bbdae349
commit 6c11505c3d
18 changed files with 374 additions and 242 deletions

View File

@ -1,11 +1,13 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -instcombine -S | FileCheck %s
define i32 @test1(i32 %A, i32 %B) {
; CHECK-LABEL: test1
; CHECK: %Z = add i32 %B, %A
; CHECK: ret i32 %Z
%W = add i32 %B, -5
%Y = add i32 %A, 5
%Z = add i32 %W, %Y
ret i32 %Z
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[Z:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: ret i32 [[Z]]
;
%W = add i32 %B, -5
%Y = add i32 %A, 5
%Z = add i32 %W, %Y
ret i32 %Z
}

View File

@ -1,9 +1,10 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -constprop -instcombine -dce -S | FileCheck %s
; With sub reassociation, constant folding can eliminate all of the constants.
define i32 @test1(i32 %A, i32 %B) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[Z:%.*]] = sub i32 %A, %B
; CHECK-NEXT: [[Z:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret i32 [[Z]]
;
%W = add i32 5, %B
@ -16,9 +17,9 @@ define i32 @test1(i32 %A, i32 %B) {
; With sub reassociation, constant folding can eliminate the two 12 constants.
define i32 @test2(i32 %A, i32 %B, i32 %C, i32 %D) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[SUM:%.*]] = add i32 %B, %A
; CHECK-NEXT: [[SUM1:%.*]] = add i32 [[SUM]], %C
; CHECK-NEXT: [[Q:%.*]] = sub i32 %D, [[SUM1]]
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: [[Q:%.*]] = sub i32 [[D:%.*]], [[TMP2]]
; CHECK-NEXT: ret i32 [[Q]]
;
%M = add i32 %A, 12

View File

@ -1,11 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -reassociate -gvn -S < %s | FileCheck %s
; (x + 0.1234 * y) * (x + -0.1234 * y) -> (x + 0.1234 * y) * (x - 0.1234 * y)
define double @test1(double %x, double %y) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[MUL:%.*]] = fmul double %y, 1.234000e-01
; CHECK-NEXT: [[ADD:%.*]] = fadd double %x, [[MUL]]
; CHECK-NEXT: [[ADD21:%.*]] = fsub double %x, [[MUL]]
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[Y:%.*]], 1.234000e-01
; CHECK-NEXT: [[ADD:%.*]] = fadd double [[X:%.*]], [[MUL]]
; CHECK-NEXT: [[ADD21:%.*]] = fsub double [[X]], [[MUL]]
; CHECK-NEXT: [[MUL3:%.*]] = fmul double [[ADD]], [[ADD21]]
; CHECK-NEXT: ret double [[MUL3]]
;
@ -20,8 +21,8 @@ define double @test1(double %x, double %y) {
; (x + -0.1234 * y) * (x + -0.1234 * y) -> (x - 0.1234 * y) * (x - 0.1234 * y)
define double @test2(double %x, double %y) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[MUL:%.*]] = fmul double %y, 1.234000e-01
; CHECK-NEXT: [[ADD1:%.*]] = fsub double %x, [[MUL]]
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[Y:%.*]], 1.234000e-01
; CHECK-NEXT: [[ADD1:%.*]] = fsub double [[X:%.*]], [[MUL]]
; CHECK-NEXT: [[MUL3:%.*]] = fmul double [[ADD1]], [[ADD1]]
; CHECK-NEXT: ret double [[MUL3]]
;
@ -36,8 +37,8 @@ define double @test2(double %x, double %y) {
; (x + 0.1234 * y) * (x - -0.1234 * y) -> (x + 0.1234 * y) * (x + 0.1234 * y)
define double @test3(double %x, double %y) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[MUL:%.*]] = fmul double %y, 1.234000e-01
; CHECK-NEXT: [[ADD:%.*]] = fadd double %x, [[MUL]]
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[Y:%.*]], 1.234000e-01
; CHECK-NEXT: [[ADD:%.*]] = fadd double [[X:%.*]], [[MUL]]
; CHECK-NEXT: [[MUL3:%.*]] = fmul double [[ADD]], [[ADD]]
; CHECK-NEXT: ret double [[MUL3]]
;
@ -52,8 +53,8 @@ define double @test3(double %x, double %y) {
; Canonicalize (x - -0.1234 * y)
define double @test5(double %x, double %y) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: [[MUL:%.*]] = fmul double %y, 1.234000e-01
; CHECK-NEXT: [[SUB1:%.*]] = fadd double %x, [[MUL]]
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[Y:%.*]], 1.234000e-01
; CHECK-NEXT: [[SUB1:%.*]] = fadd double [[X:%.*]], [[MUL]]
; CHECK-NEXT: ret double [[SUB1]]
;
%mul = fmul double -1.234000e-01, %y
@ -64,8 +65,8 @@ define double @test5(double %x, double %y) {
; Don't modify (-0.1234 * y - x)
define double @test6(double %x, double %y) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: [[MUL:%.*]] = fmul double %y, -1.234000e-01
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[MUL]], %x
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[Y:%.*]], -1.234000e-01
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[MUL]], [[X:%.*]]
; CHECK-NEXT: ret double [[SUB]]
;
%mul = fmul double -1.234000e-01, %y
@ -76,8 +77,8 @@ define double @test6(double %x, double %y) {
; Canonicalize (-0.1234 * y + x) -> (x - 0.1234 * y)
define double @test7(double %x, double %y) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: [[MUL:%.*]] = fmul double %y, 1.234000e-01
; CHECK-NEXT: [[ADD1:%.*]] = fsub double %x, [[MUL]]
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[Y:%.*]], 1.234000e-01
; CHECK-NEXT: [[ADD1:%.*]] = fsub double [[X:%.*]], [[MUL]]
; CHECK-NEXT: ret double [[ADD1]]
;
%mul = fmul double -1.234000e-01, %y
@ -88,8 +89,8 @@ define double @test7(double %x, double %y) {
; Canonicalize (y * -0.1234 + x) -> (x - 0.1234 * y)
define double @test8(double %x, double %y) {
; CHECK-LABEL: @test8(
; CHECK-NEXT: [[MUL:%.*]] = fmul double %y, 1.234000e-01
; CHECK-NEXT: [[ADD1:%.*]] = fsub double %x, [[MUL]]
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[Y:%.*]], 1.234000e-01
; CHECK-NEXT: [[ADD1:%.*]] = fsub double [[X:%.*]], [[MUL]]
; CHECK-NEXT: ret double [[ADD1]]
;
%mul = fmul double %y, -1.234000e-01
@ -100,8 +101,8 @@ define double @test8(double %x, double %y) {
; Canonicalize (x - -0.1234 / y)
define double @test9(double %x, double %y) {
; CHECK-LABEL: @test9(
; CHECK-NEXT: [[DIV:%.*]] = fdiv double 1.234000e-01, %y
; CHECK-NEXT: [[SUB1:%.*]] = fadd double %x, [[DIV]]
; CHECK-NEXT: [[DIV:%.*]] = fdiv double 1.234000e-01, [[Y:%.*]]
; CHECK-NEXT: [[SUB1:%.*]] = fadd double [[X:%.*]], [[DIV]]
; CHECK-NEXT: ret double [[SUB1]]
;
%div = fdiv double -1.234000e-01, %y
@ -112,8 +113,8 @@ define double @test9(double %x, double %y) {
; Don't modify (-0.1234 / y - x)
define double @test10(double %x, double %y) {
; CHECK-LABEL: @test10(
; CHECK-NEXT: [[DIV:%.*]] = fdiv double -1.234000e-01, %y
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DIV]], %x
; CHECK-NEXT: [[DIV:%.*]] = fdiv double -1.234000e-01, [[Y:%.*]]
; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DIV]], [[X:%.*]]
; CHECK-NEXT: ret double [[SUB]]
;
%div = fdiv double -1.234000e-01, %y
@ -124,8 +125,8 @@ define double @test10(double %x, double %y) {
; Canonicalize (-0.1234 / y + x) -> (x - 0.1234 / y)
define double @test11(double %x, double %y) {
; CHECK-LABEL: @test11(
; CHECK-NEXT: [[DIV:%.*]] = fdiv double 1.234000e-01, %y
; CHECK-NEXT: [[ADD1:%.*]] = fsub double %x, [[DIV]]
; CHECK-NEXT: [[DIV:%.*]] = fdiv double 1.234000e-01, [[Y:%.*]]
; CHECK-NEXT: [[ADD1:%.*]] = fsub double [[X:%.*]], [[DIV]]
; CHECK-NEXT: ret double [[ADD1]]
;
%div = fdiv double -1.234000e-01, %y
@ -136,8 +137,8 @@ define double @test11(double %x, double %y) {
; Canonicalize (y / -0.1234 + x) -> (x - y / 0.1234)
define double @test12(double %x, double %y) {
; CHECK-LABEL: @test12(
; CHECK-NEXT: [[DIV:%.*]] = fdiv double %y, 1.234000e-01
; CHECK-NEXT: [[ADD1:%.*]] = fsub double %x, [[DIV]]
; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[Y:%.*]], 1.234000e-01
; CHECK-NEXT: [[ADD1:%.*]] = fsub double [[X:%.*]], [[DIV]]
; CHECK-NEXT: ret double [[ADD1]]
;
%div = fdiv double %y, -1.234000e-01
@ -148,7 +149,7 @@ define double @test12(double %x, double %y) {
; Don't create an NSW violation
define i4 @test13(i4 %x) {
; CHECK-LABEL: @test13(
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i4 %x, -2
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i4 [[X:%.*]], -2
; CHECK-NEXT: [[ADD:%.*]] = add i4 [[MUL]], 3
; CHECK-NEXT: ret i4 [[ADD]]
;
@ -169,8 +170,8 @@ define i4 @test13(i4 %x) {
define double @pr34078(double %A) {
; CHECK-LABEL: @pr34078(
; CHECK-NEXT: [[SUB:%.*]] = fsub fast double 1.000000e+00, %A
; CHECK-NEXT: [[POW2:%.*]] = fmul double %A, %A
; CHECK-NEXT: [[SUB:%.*]] = fsub fast double 1.000000e+00, [[A:%.*]]
; CHECK-NEXT: [[POW2:%.*]] = fmul double [[A]], [[A]]
; CHECK-NEXT: [[MUL5_NEG:%.*]] = fmul fast double [[POW2]], -5.000000e-01
; CHECK-NEXT: [[SUB1:%.*]] = fadd fast double [[MUL5_NEG]], [[SUB]]
; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast double [[SUB1]], 2.000000e+00

View File

@ -1,14 +1,17 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -reassociate -S < %s | FileCheck %s
declare void @use(i32)
define void @test1(i32 %x, i32 %y) {
; CHECK-LABEL: test1
; CHECK: mul i32 %y, %x
; CHECK: mul i32 %y, %x
; CHECK: sub i32 %1, %2
; CHECK: call void @use(i32 %{{.*}})
; CHECK: call void @use(i32 %{{.*}})
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[Y]], [[X]]
; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[TMP1]], [[TMP2]]
; CHECK-NEXT: call void @use(i32 [[TMP1]])
; CHECK-NEXT: call void @use(i32 [[TMP3]])
; CHECK-NEXT: ret void
;
%1 = mul i32 %x, %y
%2 = mul i32 %y, %x

View File

@ -1,9 +1,10 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -constprop -instcombine -S | FileCheck %s
define float @test1(float %A, float %B) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[W:%.*]] = fadd float %B, 5.000000e+00
; CHECK-NEXT: [[X:%.*]] = fadd float %A, -7.000000e+00
; CHECK-NEXT: [[W:%.*]] = fadd float [[B:%.*]], 5.000000e+00
; CHECK-NEXT: [[X:%.*]] = fadd float [[A:%.*]], -7.000000e+00
; CHECK-NEXT: [[Y:%.*]] = fsub float [[X]], [[W]]
; CHECK-NEXT: [[Z:%.*]] = fadd float [[Y]], 1.200000e+01
; CHECK-NEXT: ret float [[Z]]
@ -18,7 +19,7 @@ define float @test1(float %A, float %B) {
; With sub reassociation, constant folding can eliminate all of the constants.
define float @test2(float %A, float %B) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[Z:%.*]] = fsub fast float %A, %B
; CHECK-NEXT: [[Z:%.*]] = fsub fast float [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret float [[Z]]
;
%W = fadd fast float %B, 5.000000e+00
@ -32,8 +33,8 @@ define float @test2(float %A, float %B) {
; Both 'reassoc' and 'nsz' are required.
define float @test2_minimal(float %A, float %B) {
; CHECK-LABEL: @test2_minimal(
; CHECK-NEXT: [[Z:%.*]] = fsub reassoc nsz float %A, %B
; CHECK-NEXT: ret float [[Z]]
; CHECK-NEXT: [[TMP1:%.*]] = fsub reassoc nsz float [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret float [[TMP1]]
;
%W = fadd reassoc nsz float %B, 5.000000e+00
%X = fadd reassoc nsz float %A, -7.000000e+00
@ -45,8 +46,8 @@ define float @test2_minimal(float %A, float %B) {
; Verify the fold is not done with only 'reassoc' ('nsz' is required).
define float @test2_reassoc(float %A, float %B) {
; CHECK-LABEL: @test2_reassoc(
; CHECK-NEXT: [[W:%.*]] = fadd reassoc float %B, 5.000000e+00
; CHECK-NEXT: [[X:%.*]] = fadd reassoc float %A, -7.000000e+00
; CHECK-NEXT: [[W:%.*]] = fadd reassoc float [[B:%.*]], 5.000000e+00
; CHECK-NEXT: [[X:%.*]] = fadd reassoc float [[A:%.*]], -7.000000e+00
; CHECK-NEXT: [[Y:%.*]] = fsub reassoc float [[X]], [[W]]
; CHECK-NEXT: [[Z:%.*]] = fadd reassoc float [[Y]], 1.200000e+01
; CHECK-NEXT: ret float [[Z]]
@ -60,10 +61,10 @@ define float @test2_reassoc(float %A, float %B) {
define float @test3(float %A, float %B, float %C, float %D) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[M:%.*]] = fadd float %A, 1.200000e+01
; CHECK-NEXT: [[N:%.*]] = fadd float [[M]], %B
; CHECK-NEXT: [[O:%.*]] = fadd float [[N]], %C
; CHECK-NEXT: [[P:%.*]] = fsub float %D, [[O]]
; CHECK-NEXT: [[M:%.*]] = fadd float [[A:%.*]], 1.200000e+01
; CHECK-NEXT: [[N:%.*]] = fadd float [[M]], [[B:%.*]]
; CHECK-NEXT: [[O:%.*]] = fadd float [[N]], [[C:%.*]]
; CHECK-NEXT: [[P:%.*]] = fsub float [[D:%.*]], [[O]]
; CHECK-NEXT: [[Q:%.*]] = fadd float [[P]], 1.200000e+01
; CHECK-NEXT: ret float [[Q]]
;
@ -84,10 +85,10 @@ define float @test4(float %A, float %B, float %C, float %D) {
; %Q = fsub fast float %D, %sum1
; ret i32 %Q
; CHECK-LABEL: @test4(
; CHECK-NEXT: [[B_NEG:%.*]] = fsub fast float -0.000000e+00, %B
; CHECK-NEXT: [[O_NEG:%.*]] = fsub fast float [[B_NEG]], %A
; CHECK-NEXT: [[P:%.*]] = fsub fast float [[O_NEG]], %C
; CHECK-NEXT: [[Q:%.*]] = fadd fast float [[P]], %D
; CHECK-NEXT: [[B_NEG:%.*]] = fsub fast float -0.000000e+00, [[B:%.*]]
; CHECK-NEXT: [[O_NEG:%.*]] = fsub fast float [[B_NEG]], [[A:%.*]]
; CHECK-NEXT: [[P:%.*]] = fsub fast float [[O_NEG]], [[C:%.*]]
; CHECK-NEXT: [[Q:%.*]] = fadd fast float [[P]], [[D:%.*]]
; CHECK-NEXT: ret float [[Q]]
;
%M = fadd fast float 1.200000e+01, %A
@ -102,10 +103,10 @@ define float @test4(float %A, float %B, float %C, float %D) {
define float @test4_reassoc(float %A, float %B, float %C, float %D) {
; CHECK-LABEL: @test4_reassoc(
; CHECK-NEXT: [[M:%.*]] = fadd reassoc float %A, 1.200000e+01
; CHECK-NEXT: [[N:%.*]] = fadd reassoc float [[M]], %B
; CHECK-NEXT: [[O:%.*]] = fadd reassoc float [[N]], %C
; CHECK-NEXT: [[P:%.*]] = fsub reassoc float %D, [[O]]
; CHECK-NEXT: [[M:%.*]] = fadd reassoc float [[A:%.*]], 1.200000e+01
; CHECK-NEXT: [[N:%.*]] = fadd reassoc float [[M]], [[B:%.*]]
; CHECK-NEXT: [[O:%.*]] = fadd reassoc float [[N]], [[C:%.*]]
; CHECK-NEXT: [[P:%.*]] = fsub reassoc float [[D:%.*]], [[O]]
; CHECK-NEXT: [[Q:%.*]] = fadd reassoc float [[P]], 1.200000e+01
; CHECK-NEXT: ret float [[Q]]
;

View File

@ -1,11 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -reassociate -S < %s | FileCheck %s
declare void @use(float)
define void @test1(float %x, float %y) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float %y, %x
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float %y, %x
; 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]])
@ -21,8 +22,8 @@ define void @test1(float %x, float %y) {
define float @test2(float %x, float %y) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float %y, %x
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast float %y, %x
; 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]]
;
@ -34,7 +35,7 @@ define float @test2(float %x, float %y) {
define float @test3(float %x, float %y) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float %y, %x
; CHECK-NEXT: [[FACTOR:%.*]] = fmul fast float [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast float [[FACTOR]], 2.000000e+00
; CHECK-NEXT: ret float [[REASS_MUL]]
;

View File

@ -1,12 +1,13 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -S | FileCheck %s
; Check that a*a*b+a*a*c is turned into a*(a*(b+c)).
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: [[REASS_ADD1:%.*]] = fadd fast float [[C:%.*]], [[B:%.*]]
; CHECK-NEXT: [[REASS_MUL2:%.*]] = fmul fast float [[A:%.*]], [[A]]
; CHECK-NEXT: [[REASS_MUL:%.*]] = fmul fast float [[REASS_MUL2]], [[REASS_ADD1]]
; CHECK-NEXT: ret float [[REASS_MUL]]
;
%t0 = fmul fast float %a, %b
@ -21,9 +22,9 @@ define float @fmultistep1(float %a, float %b, float %c) {
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: [[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

View File

@ -1,3 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; This testcase comes from this C fragment:
;
; void test(unsigned Num, int *Array) {
@ -19,34 +20,63 @@
declare i32 @printf(i8*, ...)
; Check that (i+j) has been reassociated (i=reg115, j=reg116)
; CHECK: %reg113 = add i32 %reg116, %reg115
define void @test(i32 %Num, i32* %Array) {
; CHECK-LABEL: @test(
; CHECK-NEXT: bb0:
; CHECK-NEXT: [[COND221:%.*]] = icmp eq i32 0, [[NUM:%.*]]
; CHECK-NEXT: br i1 [[COND221]], label [[BB7:%.*]], label [[BB2:%.*]]
; CHECK: bb2:
; CHECK-NEXT: [[REG115:%.*]] = phi i32 [ [[REG120:%.*]], [[BB6:%.*]] ], [ 0, [[BB0:%.*]] ]
; CHECK-NEXT: br i1 [[COND221]], label [[BB6]], label [[BB3:%.*]]
; CHECK: bb3:
; CHECK-NEXT: [[REG116:%.*]] = phi i32 [ [[REG119:%.*]], [[BB5:%.*]] ], [ 0, [[BB2]] ]
; CHECK-NEXT: br i1 [[COND221]], label [[BB5]], label [[BB4:%.*]]
; CHECK: bb4:
; CHECK-NEXT: [[REG117:%.*]] = phi i32 [ [[REG118:%.*]], [[BB4]] ], [ 0, [[BB3]] ]
; CHECK-NEXT: [[REG113:%.*]] = add i32 [[REG116]], [[REG115]]
; CHECK-NEXT: [[REG114:%.*]] = add i32 [[REG113]], [[REG117]]
; CHECK-NEXT: [[CAST227:%.*]] = getelementptr [4 x i8], [4 x i8]* @.LC0, i64 0, i64 0
; CHECK-NEXT: [[TMP0:%.*]] = call i32 (i8*, ...) @printf(i8* [[CAST227]], i32 [[REG114]])
; CHECK-NEXT: [[REG118]] = add i32 [[REG117]], 1
; CHECK-NEXT: [[COND224:%.*]] = icmp ne i32 [[REG118]], [[NUM]]
; CHECK-NEXT: br i1 [[COND224]], label [[BB4]], label [[BB5]]
; CHECK: bb5:
; CHECK-NEXT: [[REG119]] = add i32 [[REG116]], 1
; CHECK-NEXT: [[COND225:%.*]] = icmp ne i32 [[REG119]], [[NUM]]
; CHECK-NEXT: br i1 [[COND225]], label [[BB3]], label [[BB6]]
; CHECK: bb6:
; CHECK-NEXT: [[REG120]] = add i32 [[REG115]], 1
; CHECK-NEXT: [[COND226:%.*]] = icmp ne i32 [[REG120]], [[NUM]]
; CHECK-NEXT: br i1 [[COND226]], label [[BB2]], label [[BB7]]
; CHECK: bb7:
; CHECK-NEXT: ret void
;
bb0:
%cond221 = icmp eq i32 0, %Num ; <i1> [#uses=3]
br i1 %cond221, label %bb7, label %bb2
%cond221 = icmp eq i32 0, %Num ; <i1> [#uses=3]
br i1 %cond221, label %bb7, label %bb2
bb2: ; preds = %bb6, %bb0
%reg115 = phi i32 [ %reg120, %bb6 ], [ 0, %bb0 ] ; <i32> [#uses=2]
br i1 %cond221, label %bb6, label %bb3
%reg115 = phi i32 [ %reg120, %bb6 ], [ 0, %bb0 ] ; <i32> [#uses=2]
br i1 %cond221, label %bb6, label %bb3
bb3: ; preds = %bb5, %bb2
%reg116 = phi i32 [ %reg119, %bb5 ], [ 0, %bb2 ] ; <i32> [#uses=2]
br i1 %cond221, label %bb5, label %bb4
%reg116 = phi i32 [ %reg119, %bb5 ], [ 0, %bb2 ] ; <i32> [#uses=2]
br i1 %cond221, label %bb5, label %bb4
bb4: ; preds = %bb4, %bb3
%reg117 = phi i32 [ %reg118, %bb4 ], [ 0, %bb3 ] ; <i32> [#uses=2]
%reg113 = add i32 %reg115, %reg117 ; <i32> [#uses=1]
%reg114 = add i32 %reg113, %reg116 ; <i32> [#uses=1]
%cast227 = getelementptr [4 x i8], [4 x i8]* @.LC0, i64 0, i64 0 ; <i8*> [#uses=1]
call i32 (i8*, ...) @printf( i8* %cast227, i32 %reg114 ) ; <i32>:0 [#uses=0]
%reg118 = add i32 %reg117, 1 ; <i32> [#uses=2]
%cond224 = icmp ne i32 %reg118, %Num ; <i1> [#uses=1]
br i1 %cond224, label %bb4, label %bb5
%reg117 = phi i32 [ %reg118, %bb4 ], [ 0, %bb3 ] ; <i32> [#uses=2]
%reg113 = add i32 %reg115, %reg117 ; <i32> [#uses=1]
%reg114 = add i32 %reg113, %reg116 ; <i32> [#uses=1]
%cast227 = getelementptr [4 x i8], [4 x i8]* @.LC0, i64 0, i64 0 ; <i8*> [#uses=1]
call i32 (i8*, ...) @printf( i8* %cast227, i32 %reg114 ) ; <i32>:0 [#uses=0]
%reg118 = add i32 %reg117, 1 ; <i32> [#uses=2]
%cond224 = icmp ne i32 %reg118, %Num ; <i1> [#uses=1]
br i1 %cond224, label %bb4, label %bb5
bb5: ; preds = %bb4, %bb3
%reg119 = add i32 %reg116, 1 ; <i32> [#uses=2]
%cond225 = icmp ne i32 %reg119, %Num ; <i1> [#uses=1]
br i1 %cond225, label %bb3, label %bb6
%reg119 = add i32 %reg116, 1 ; <i32> [#uses=2]
%cond225 = icmp ne i32 %reg119, %Num ; <i1> [#uses=1]
br i1 %cond225, label %bb3, label %bb6
bb6: ; preds = %bb5, %bb2
%reg120 = add i32 %reg115, 1 ; <i32> [#uses=2]
%cond226 = icmp ne i32 %reg120, %Num ; <i1> [#uses=1]
br i1 %cond226, label %bb2, label %bb7
%reg120 = add i32 %reg115, 1 ; <i32> [#uses=2]
%cond226 = icmp ne i32 %reg120, %Num ; <i1> [#uses=1]
br i1 %cond226, label %bb2, label %bb7
bb7: ; preds = %bb6, %bb0
ret void
ret void
}

View File

@ -1,11 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -reassociate %s -S | FileCheck %s
define float @foo(float %a,float %b, float %c) {
; 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: [[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]]
;
@ -21,10 +22,10 @@ define float @foo(float %a,float %b, float %c) {
define float @foo_reassoc(float %a,float %b, float %c) {
; CHECK-LABEL: @foo_reassoc(
; CHECK-NEXT: [[MUL1:%.*]] = fmul reassoc float %a, %c
; CHECK-NEXT: [[MUL2:%.*]] = fmul fast float %b, %a
; CHECK-NEXT: [[MUL3:%.*]] = fmul float %a, %b
; CHECK-NEXT: [[MUL4:%.*]] = fmul reassoc float %a, %c
; CHECK-NEXT: [[MUL1:%.*]] = fmul reassoc float [[A:%.*]], [[C:%.*]]
; CHECK-NEXT: [[MUL2:%.*]] = fmul fast float [[B:%.*]], [[A]]
; CHECK-NEXT: [[MUL3:%.*]] = fmul float [[A]], [[B]]
; CHECK-NEXT: [[MUL4:%.*]] = fmul reassoc float [[A]], [[C]]
; CHECK-NEXT: [[ADD1:%.*]] = fadd fast float [[MUL1]], [[MUL3]]
; CHECK-NEXT: [[ADD2:%.*]] = fadd reassoc float [[MUL2]], [[MUL4]]
; CHECK-NEXT: [[ADD3:%.*]] = fadd fast float [[ADD1]], [[ADD2]]

View File

@ -1,11 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -S | FileCheck %s
define i32 @test1(i32 %a, i32 %b) {
; CHECK-LABEL: @test1(
; 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: [[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]]
;
@ -20,7 +21,7 @@ define i32 @test1(i32 %a, i32 %b) {
define i32 @test2(i32 %t) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 %t, 42
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 [[T:%.*]], 42
; CHECK-NEXT: [[D:%.*]] = add i32 [[REASS_MUL]], 15
; CHECK-NEXT: ret i32 [[D]]
;
@ -34,7 +35,7 @@ define i32 @test2(i32 %t) {
; (x^8)
define i32 @test3(i32 %x) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
; 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]]
@ -52,9 +53,9 @@ define i32 @test3(i32 %x) {
; (x^7)
define i32 @test4(i32 %x) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], %x
; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[TMP2]], %x
; 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]]
;
@ -70,8 +71,8 @@ define i32 @test4(i32 %x) {
; (x^4) * (y^2)
define i32 @test5(i32 %x, i32 %y) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], %y
; 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]]
;
@ -86,12 +87,12 @@ define i32 @test5(i32 %x, i32 %y) {
; (x^5) * (y^3) * z
define i32 @test6(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %x, %x
; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], %y
; CHECK-NEXT: [[F:%.*]] = mul i32 %y, %x
; 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: [[H:%.*]] = mul i32 [[TMP3]], [[Z:%.*]]
; CHECK-NEXT: ret i32 [[H]]
;
%a = mul i32 %x, %y
@ -108,10 +109,10 @@ define i32 @test6(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-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: [[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]]
;

View File

@ -1,12 +1,13 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -S | FileCheck %s
; 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: [[REASS_ADD1:%.*]] = add i64 [[C:%.*]], [[B:%.*]]
; CHECK-NEXT: [[REASS_MUL2:%.*]] = mul i64 [[A:%.*]], [[A]]
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i64 [[REASS_MUL2]], [[REASS_ADD1]]
; CHECK-NEXT: ret i64 [[REASS_MUL]]
;
%t0 = mul i64 %a, %b
@ -21,9 +22,9 @@ define i64 @multistep1(i64 %a, i64 %b, i64 %c) {
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: [[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

View File

@ -1,3 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -S | FileCheck %s
; When there is nothing to do, or not much to do, check that reassociate leaves
@ -9,16 +10,19 @@ define void @test1(i32 %a, i32 %b) {
; Shouldn't change or move any of the add instructions. Should commute but
; otherwise not change or move any of the mul instructions.
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[A0:%.*]] = add nsw i32 [[A:%.*]], 1
; CHECK-NEXT: [[M0:%.*]] = mul nsw i32 [[A]], 3
; CHECK-NEXT: [[A1:%.*]] = add nsw i32 [[A0]], [[B:%.*]]
; CHECK-NEXT: [[M1:%.*]] = mul nsw i32 [[M0]], [[B]]
; CHECK-NEXT: call void @use(i32 [[A1]])
; CHECK-NEXT: call void @use(i32 [[M1]])
; CHECK-NEXT: ret void
;
%a0 = add nsw i32 %a, 1
; CHECK-NEXT: %a0 = add nsw i32 %a, 1
%m0 = mul nsw i32 3, %a
; CHECK-NEXT: %m0 = mul nsw i32 %a, 3
%a1 = add nsw i32 %a0, %b
; CHECK-NEXT: %a1 = add nsw i32 %a0, %b
%m1 = mul nsw i32 %b, %m0
; CHECK-NEXT: %m1 = mul nsw i32 %m0, %b
call void @use(i32 %a1)
; CHECK-NEXT: call void @use
call void @use(i32 %m1)
ret void
}
@ -26,13 +30,15 @@ define void @test1(i32 %a, i32 %b) {
define void @test2(i32 %a, i32 %b, i32 %c, i32 %d) {
; The initial add doesn't change so should not lose the nsw flag.
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[A0:%.*]] = add nsw i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[A1:%.*]] = add i32 [[A0]], [[C:%.*]]
; CHECK-NEXT: [[A2:%.*]] = add i32 [[A1]], [[D:%.*]]
; CHECK-NEXT: call void @use(i32 [[A2]])
; CHECK-NEXT: ret void
;
%a0 = add nsw i32 %b, %a
; CHECK-NEXT: %a0 = add nsw i32 %b, %a
%a1 = add nsw i32 %a0, %d
; CHECK-NEXT: %a1 = add i32 %a0, %c
%a2 = add nsw i32 %a1, %c
; CHECK-NEXT: %a2 = add i32 %a1, %d
call void @use(i32 %a2)
; CHECK-NEXT: call void @use
ret void
}

View File

@ -1,29 +1,40 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -reassociate < %s | FileCheck %s
; rdar://8944681
; Reassociate should clear optional flags like nsw when reassociating.
; CHECK-LABEL: @test0(
; CHECK: %y = add i64 %b, %a
; CHECK: %z = add i64 %y, %c
define i64 @test0(i64 %a, i64 %b, i64 %c) {
;
; CHECK-LABEL: @test0(
; CHECK-NEXT: [[Y:%.*]] = add i64 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[Z:%.*]] = add i64 [[Y]], [[C:%.*]]
; CHECK-NEXT: ret i64 [[Z]]
;
%y = add nsw i64 %c, %b
%z = add i64 %y, %a
ret i64 %z
}
; CHECK-LABEL: @test1(
; CHECK: %y = add i64 %b, %a
; CHECK: %z = add i64 %y, %c
define i64 @test1(i64 %a, i64 %b, i64 %c) {
;
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[Y:%.*]] = add i64 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[Z:%.*]] = add i64 [[Y]], [[C:%.*]]
; CHECK-NEXT: ret i64 [[Z]]
;
%y = add i64 %c, %b
%z = add nsw i64 %y, %a
ret i64 %z
}
; PR9215
; CHECK: %s = add nsw i32 %y, %x
define i32 @test2(i32 %x, i32 %y) {
;
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: ret i32 [[S]]
;
%s = add nsw i32 %x, %y
ret i32 %s
}

View File

@ -1,8 +1,9 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -S | FileCheck %s
define double @func(double %a, double %b) {
; CHECK-LABEL: @func(
; CHECK-NEXT: [[TMP1:%.*]] = fmul fast double %b, %a
; CHECK-NEXT: [[TMP1:%.*]] = fmul fast double [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = fmul fast double [[TMP1]], [[TMP1]]
; CHECK-NEXT: ret double [[TMP2]]
;

View File

@ -1,10 +1,11 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -instcombine -S | FileCheck %s
; There should be exactly one shift and one add left.
define i32 @test1(i32 %X, i32 %Y) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[REASS_ADD:%.*]] = add i32 %Y, %X
; CHECK-NEXT: [[REASS_ADD:%.*]] = add i32 [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: [[REASS_MUL:%.*]] = shl i32 [[REASS_ADD]], 1
; CHECK-NEXT: ret i32 [[REASS_MUL]]
;

View File

@ -1,18 +1,25 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -reassociate -die < %s | FileCheck %s
; The two va_arg instructions depend on the memory/context, are therfore not
; identical and the sub should not be optimized to 0 by reassociate.
;
; CHECK-LABEL: @func(
; ...
; CHECK: %v0 = va_arg i8** %varargs, i32
; CHECK: %v1 = va_arg i8** %varargs, i32
; CHECK: %v0.neg = sub i32 0, %v0
; CHECK: %sub = add i32 %v0.neg, 1
; CHECK: %add = add i32 %sub, %v1
; ...
; CHECK: ret i32 %add
define i32 @func(i32 %dummy, ...) {
;
; CHECK-LABEL: @func(
; CHECK-NEXT: [[VARARGS:%.*]] = alloca i8*, align 8
; CHECK-NEXT: [[VARARGS1:%.*]] = bitcast i8** [[VARARGS]] to i8*
; CHECK-NEXT: call void @llvm.va_start(i8* [[VARARGS1]])
; CHECK-NEXT: [[V0:%.*]] = va_arg i8** [[VARARGS]], i32
; CHECK-NEXT: [[V1:%.*]] = va_arg i8** [[VARARGS]], i32
; CHECK-NEXT: [[V0_NEG:%.*]] = sub i32 0, [[V0]]
; CHECK-NEXT: [[SUB:%.*]] = add i32 [[V0_NEG]], 1
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[V1]]
; CHECK-NEXT: call void @llvm.va_end(i8* [[VARARGS1]])
; CHECK-NEXT: ret i32 [[ADD]]
;
%varargs = alloca i8*, align 8
%varargs1 = bitcast i8** %varargs to i8*
call void @llvm.va_start(i8* %varargs1)

View File

@ -1,44 +1,59 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -dce -S | FileCheck %s
; PR12985
; Verify the nsw flags are preserved when converting shl to mul.
; CHECK-LABEL: @shl_to_mul_nsw(
; CHECK: %mul = mul i32 %i, -2147483648
; CHECK: add i32 %mul, 1
define i32 @shl_to_mul_nsw(i32 %i) {
;
; CHECK-LABEL: @shl_to_mul_nsw(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[I:%.*]], -2147483648
; CHECK-NEXT: [[MUL2:%.*]] = add i32 [[MUL]], 1
; CHECK-NEXT: ret i32 [[MUL2]]
;
entry:
%mul = shl nsw i32 %i, 31
%mul2 = add i32 %mul, 1
ret i32 %mul2
}
; CHECK-LABEL: @shl_to_mul_nuw(
; CHECK: %mul = mul nuw i32 %i, 4
; CHECK: add i32 %mul, 1
define i32 @shl_to_mul_nuw(i32 %i) {
;
; CHECK-LABEL: @shl_to_mul_nuw(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[I:%.*]], 4
; CHECK-NEXT: [[MUL2:%.*]] = add i32 [[MUL]], 1
; CHECK-NEXT: ret i32 [[MUL2]]
;
entry:
%mul = shl nuw i32 %i, 2
%mul2 = add i32 %mul, 1
ret i32 %mul2
}
; CHECK-LABEL: @shl_to_mul_nuw_nsw(
; CHECK: %mul = mul nuw nsw i32 %i, 4
; CHECK: add i32 %mul, 1
define i32 @shl_to_mul_nuw_nsw(i32 %i) {
;
; CHECK-LABEL: @shl_to_mul_nuw_nsw(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i32 [[I:%.*]], 4
; CHECK-NEXT: [[MUL2:%.*]] = add i32 [[MUL]], 1
; CHECK-NEXT: ret i32 [[MUL2]]
;
entry:
%mul = shl nuw nsw i32 %i, 2
%mul2 = add i32 %mul, 1
ret i32 %mul2
}
; CHECK-LABEL: @pr23926(
; CHECK: %[[X1_neg:.*]] = sub i2 0, %X1
; CHECK-NEXT: %[[sub_one:.*]] = add i2 %[[X1_neg]], -1
; CHECK-NEXT: %[[add:.*]] = add i2 %[[sub_one]], %X2
; CHECK-NEXT: ret i2 %[[add]]
define i2 @pr23926(i2 %X1, i2 %X2) {
;
; CHECK-LABEL: @pr23926(
; CHECK-NEXT: [[X1_NEG:%.*]] = sub i2 0, [[X1:%.*]]
; CHECK-NEXT: [[ADD_NEG:%.*]] = add i2 [[X1_NEG]], -1
; CHECK-NEXT: [[SUB:%.*]] = add i2 [[ADD_NEG]], [[X2:%.*]]
; CHECK-NEXT: ret i2 [[SUB]]
;
%add = add nuw i2 %X1, 1
%sub = sub nuw nsw i2 %X2, %add
ret i2 %sub

View File

@ -1,243 +1,275 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
;RUN: opt -S -reassociate < %s | FileCheck %s
; ==========================================================================
;
; Xor reassociation general cases
;
;
; ==========================================================================
; (x | c1) ^ (x | c2) => (x & c3) ^ c3, where c3 = c1^c2
;
;
define i32 @xor1(i32 %x) {
; CHECK-LABEL: @xor1(
; CHECK-NEXT: [[AND_RA:%.*]] = and i32 [[X:%.*]], 435
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[AND_RA]], 435
; CHECK-NEXT: ret i32 [[XOR]]
;
%or = or i32 %x, 123
%or1 = or i32 %x, 456
%xor = xor i32 %or, %or1
ret i32 %xor
;CHECK-LABEL: @xor1(
;CHECK: %and.ra = and i32 %x, 435
;CHECK: %xor = xor i32 %and.ra, 435
}
; (x | c1) ^ (x | c2) => (x & c3) ^ c3, where c3 = c1^c2
;
;
define <2 x i32> @xor1_vec(<2 x i32> %x) {
; CHECK-LABEL: @xor1_vec(
; CHECK-NEXT: [[AND_RA:%.*]] = and <2 x i32> [[X:%.*]], <i32 435, i32 435>
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[AND_RA]], <i32 435, i32 435>
; CHECK-NEXT: ret <2 x i32> [[XOR]]
;
%or = or <2 x i32> %x, <i32 123, i32 123>
%or1 = or <2 x i32> %x, <i32 456, i32 456>
%xor = xor <2 x i32> %or, %or1
ret <2 x i32> %xor
;CHECK-LABEL: @xor1_vec(
;CHECK: %and.ra = and <2 x i32> %x, <i32 435, i32 435>
;CHECK: %xor = xor <2 x i32> %and.ra, <i32 435, i32 435>
}
; Test rule : (x & c1) ^ (x & c2) = (x & (c1^c2))
; Real testing case : (x & 123) ^ y ^ (x & 345) => (x & 435) ^ y
define i32 @xor2(i32 %x, i32 %y) {
; CHECK-LABEL: @xor2(
; CHECK-NEXT: [[AND_RA:%.*]] = and i32 [[X:%.*]], 435
; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[AND_RA]], [[Y:%.*]]
; CHECK-NEXT: ret i32 [[XOR2]]
;
%and = and i32 %x, 123
%xor = xor i32 %and, %y
%and1 = and i32 %x, 456
%xor2 = xor i32 %xor, %and1
ret i32 %xor2
;CHECK-LABEL: @xor2(
;CHECK: %and.ra = and i32 %x, 435
;CHECK: %xor2 = xor i32 %and.ra, %y
}
; Test rule : (x & c1) ^ (x & c2) = (x & (c1^c2))
; Real testing case : (x & 123) ^ y ^ (x & 345) => (x & 435) ^ y
define <2 x i32> @xor2_vec(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @xor2_vec(
; CHECK-NEXT: [[AND_RA:%.*]] = and <2 x i32> [[X:%.*]], <i32 435, i32 435>
; CHECK-NEXT: [[XOR2:%.*]] = xor <2 x i32> [[AND_RA]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i32> [[XOR2]]
;
%and = and <2 x i32> %x, <i32 123, i32 123>
%xor = xor <2 x i32> %and, %y
%and1 = and <2 x i32> %x, <i32 456, i32 456>
%xor2 = xor <2 x i32> %xor, %and1
ret <2 x i32> %xor2
;CHECK-LABEL: @xor2_vec(
;CHECK: %and.ra = and <2 x i32> %x, <i32 435, i32 435>
;CHECK: %xor2 = xor <2 x i32> %and.ra, %y
}
; Test rule: (x | c1) ^ (x & c2) = (x & c3) ^ c1, where c3 = ~c1 ^ c2
; c3 = ~c1 ^ c2
define i32 @xor3(i32 %x, i32 %y) {
; CHECK-LABEL: @xor3(
; CHECK-NEXT: [[AND_RA:%.*]] = and i32 [[X:%.*]], -436
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 123
; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[XOR]], [[AND_RA]]
; CHECK-NEXT: ret i32 [[XOR1]]
;
%or = or i32 %x, 123
%xor = xor i32 %or, %y
%and = and i32 %x, 456
%xor1 = xor i32 %xor, %and
ret i32 %xor1
;CHECK-LABEL: @xor3(
;CHECK: %and.ra = and i32 %x, -436
;CHECK: %xor = xor i32 %y, 123
;CHECK: %xor1 = xor i32 %xor, %and.ra
}
; Test rule: (x | c1) ^ (x & c2) = (x & c3) ^ c1, where c3 = ~c1 ^ c2
; c3 = ~c1 ^ c2
define <2 x i32> @xor3_vec(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @xor3_vec(
; CHECK-NEXT: [[AND_RA:%.*]] = and <2 x i32> [[X:%.*]], <i32 -436, i32 -436>
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[Y:%.*]], <i32 123, i32 123>
; CHECK-NEXT: [[XOR1:%.*]] = xor <2 x i32> [[XOR]], [[AND_RA]]
; CHECK-NEXT: ret <2 x i32> [[XOR1]]
;
%or = or <2 x i32> %x, <i32 123, i32 123>
%xor = xor <2 x i32> %or, %y
%and = and <2 x i32> %x, <i32 456, i32 456>
%xor1 = xor <2 x i32> %xor, %and
ret <2 x i32> %xor1
;CHECK-LABEL: @xor3_vec(
;CHECK: %and.ra = and <2 x i32> %x, <i32 -436, i32 -436>
;CHECK: %xor = xor <2 x i32> %y, <i32 123, i32 123>
;CHECK: %xor1 = xor <2 x i32> %xor, %and.ra
}
; Test rule: (x | c1) ^ c2 = (x & ~c1) ^ (c1 ^ c2)
define i32 @xor4(i32 %x, i32 %y) {
; CHECK-LABEL: @xor4(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], -124
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 435
; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[XOR]], [[AND]]
; CHECK-NEXT: ret i32 [[XOR1]]
;
%and = and i32 %x, -124
%xor = xor i32 %y, 435
%xor1 = xor i32 %xor, %and
ret i32 %xor1
; CHECK-LABEL: @xor4(
; CHECK: %and = and i32 %x, -124
; CHECK: %xor = xor i32 %y, 435
; CHECK: %xor1 = xor i32 %xor, %and
}
; Test rule: (x | c1) ^ c2 = (x & ~c1) ^ (c1 ^ c2)
define <2 x i32> @xor4_vec(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @xor4_vec(
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 -124, i32 -124>
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[Y:%.*]], <i32 435, i32 435>
; CHECK-NEXT: [[XOR1:%.*]] = xor <2 x i32> [[XOR]], [[AND]]
; CHECK-NEXT: ret <2 x i32> [[XOR1]]
;
%and = and <2 x i32> %x, <i32 -124, i32 -124>
%xor = xor <2 x i32> %y, <i32 435, i32 435>
%xor1 = xor <2 x i32> %xor, %and
ret <2 x i32> %xor1
; CHECK-LABEL: @xor4_vec(
; CHECK: %and = and <2 x i32> %x, <i32 -124, i32 -124>
; CHECK: %xor = xor <2 x i32> %y, <i32 435, i32 435>
; CHECK: %xor1 = xor <2 x i32> %xor, %and
}
; ==========================================================================
;
; Xor reassociation special cases
;
;
; ==========================================================================
; Special case1:
; Special case1:
; (x | c1) ^ (x & ~c1) = c1
define i32 @xor_special1(i32 %x, i32 %y) {
; CHECK-LABEL: @xor_special1(
; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[Y:%.*]], 123
; CHECK-NEXT: ret i32 [[XOR1]]
;
%or = or i32 %x, 123
%xor = xor i32 %or, %y
%and = and i32 %x, -124
%xor1 = xor i32 %xor, %and
ret i32 %xor1
; CHECK-LABEL: @xor_special1(
; CHECK: %xor1 = xor i32 %y, 123
; CHECK: ret i32 %xor1
}
; Special case1:
; Special case1:
; (x | c1) ^ (x & ~c1) = c1
define <2 x i32> @xor_special1_vec(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @xor_special1_vec(
; CHECK-NEXT: [[XOR1:%.*]] = xor <2 x i32> [[Y:%.*]], <i32 123, i32 123>
; CHECK-NEXT: ret <2 x i32> [[XOR1]]
;
%or = or <2 x i32> %x, <i32 123, i32 123>
%xor = xor <2 x i32> %or, %y
%and = and <2 x i32> %x, <i32 -124, i32 -124>
%xor1 = xor <2 x i32> %xor, %and
ret <2 x i32> %xor1
; CHECK-LABEL: @xor_special1_vec(
; CHECK: %xor1 = xor <2 x i32> %y, <i32 123, i32 123>
; CHECK: ret <2 x i32> %xor1
}
; Special case1:
; Special case1:
; (x | c1) ^ (x & c1) = x ^ c1
define i32 @xor_special2(i32 %x, i32 %y) {
; CHECK-LABEL: @xor_special2(
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], 123
; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[XOR]], [[Y:%.*]]
; CHECK-NEXT: ret i32 [[XOR1]]
;
%or = or i32 %x, 123
%xor = xor i32 %or, %y
%and = and i32 %x, 123
%xor1 = xor i32 %xor, %and
ret i32 %xor1
; CHECK-LABEL: @xor_special2(
; CHECK: %xor = xor i32 %x, 123
; CHECK: %xor1 = xor i32 %xor, %y
; CHECK: ret i32 %xor1
}
; Special case1:
; Special case1:
; (x | c1) ^ (x & c1) = x ^ c1
define <2 x i32> @xor_special2_vec(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @xor_special2_vec(
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 123, i32 123>
; CHECK-NEXT: [[XOR1:%.*]] = xor <2 x i32> [[XOR]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i32> [[XOR1]]
;
%or = or <2 x i32> %x, <i32 123, i32 123>
%xor = xor <2 x i32> %or, %y
%and = and <2 x i32> %x, <i32 123, i32 123>
%xor1 = xor <2 x i32> %xor, %and
ret <2 x i32> %xor1
; CHECK-LABEL: @xor_special2_vec(
; CHECK: %xor = xor <2 x i32> %x, <i32 123, i32 123>
; CHECK: %xor1 = xor <2 x i32> %xor, %y
; CHECK: ret <2 x i32> %xor1
}
; (x | c1) ^ (x | c1) => 0
define i32 @xor_special3(i32 %x) {
; CHECK-LABEL: @xor_special3(
; CHECK-NEXT: ret i32 0
;
%or = or i32 %x, 123
%or1 = or i32 %x, 123
%xor = xor i32 %or, %or1
ret i32 %xor
;CHECK-LABEL: @xor_special3(
;CHECK: ret i32 0
}
; (x | c1) ^ (x | c1) => 0
define <2 x i32> @xor_special3_vec(<2 x i32> %x) {
; CHECK-LABEL: @xor_special3_vec(
; CHECK-NEXT: ret <2 x i32> zeroinitializer
;
%or = or <2 x i32> %x, <i32 123, i32 123>
%or1 = or <2 x i32> %x, <i32 123, i32 123>
%xor = xor <2 x i32> %or, %or1
ret <2 x i32> %xor
;CHECK-LABEL: @xor_special3_vec(
;CHECK: ret <2 x i32> zeroinitializer
}
; (x & c1) ^ (x & c1) => 0
define i32 @xor_special4(i32 %x) {
; CHECK-LABEL: @xor_special4(
; CHECK-NEXT: ret i32 0
;
%or = and i32 %x, 123
%or1 = and i32 123, %x
%xor = xor i32 %or, %or1
ret i32 %xor
;CHECK-LABEL: @xor_special4(
;CHECK: ret i32 0
}
; (x & c1) ^ (x & c1) => 0
define <2 x i32> @xor_special4_vec(<2 x i32> %x) {
; CHECK-LABEL: @xor_special4_vec(
; CHECK-NEXT: ret <2 x i32> zeroinitializer
;
%or = and <2 x i32> %x, <i32 123, i32 123>
%or1 = and <2 x i32> <i32 123, i32 123>, %x
%xor = xor <2 x i32> %or, %or1
ret <2 x i32> %xor
;CHECK-LABEL: @xor_special4_vec(
;CHECK: ret <2 x i32> zeroinitializer
}
; ==========================================================================
;
; Xor reassociation curtail code size
;
;
; ==========================================================================
; (x | c1) ^ (x | c2) => (x & c3) ^ c3
; is enabled if one of operands has multiple uses
;
;
define i32 @xor_ra_size1(i32 %x) {
; CHECK-LABEL: @xor_ra_size1(
; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 123
; CHECK-NEXT: [[AND_RA:%.*]] = and i32 [[X]], 435
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[AND_RA]], 435
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XOR]], [[OR]]
; CHECK-NEXT: ret i32 [[ADD]]
;
%or = or i32 %x, 123
%or1 = or i32 %x, 456
%xor = xor i32 %or, %or1
%add = add i32 %xor, %or
ret i32 %add
;CHECK-LABEL: @xor_ra_size1(
;CHECK: %xor = xor i32 %and.ra, 435
}
; (x | c1) ^ (x | c2) => (x & c3) ^ c3
; is disenabled if bothf operands has multiple uses.
;
;
define i32 @xor_ra_size2(i32 %x) {
; CHECK-LABEL: @xor_ra_size2(
; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 123
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X]], 456
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[OR]], [[OR1]]
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[OR1]], [[OR]]
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD]], [[XOR]]
; CHECK-NEXT: ret i32 [[ADD2]]
;
%or = or i32 %x, 123
%or1 = or i32 %x, 456
%xor = xor i32 %or, %or1
@ -246,20 +278,22 @@ define i32 @xor_ra_size2(i32 %x) {
%add2 = add i32 %add, %or1
ret i32 %add2
;CHECK-LABEL: @xor_ra_size2(
;CHECK: %or1 = or i32 %x, 456
;CHECK: %xor = xor i32 %or, %or1
}
; ==========================================================================
;
; Xor reassociation bugs
;
;
; ==========================================================================
@xor_bug1_data = external global <{}>, align 4
define void @xor_bug1() {
; CHECK-LABEL: @xor_bug1(
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i32* undef to i64
; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], ptrtoint (<{}>* @xor_bug1_data to i64)
; CHECK-NEXT: ret void
;
%1 = ptrtoint i32* undef to i64
%2 = xor i64 %1, ptrtoint (<{}>* @xor_bug1_data to i64)
%3 = and i64 undef, %2
@ -272,6 +306,22 @@ define void @xor_bug1() {
; of c1 and c2 accordingly, hence cause the problem.
;
define i32 @xor_bug2(i32, i32, i32, i32) {
; CHECK-LABEL: @xor_bug2(
; CHECK-NEXT: [[TMP5:%.*]] = mul i32 [[TMP0:%.*]], 123
; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP1:%.*]], 3456789
; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP6]], 4567890
; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP2:%.*]], 255
; CHECK-NEXT: [[AND_RA:%.*]] = and i32 [[TMP1]], -360490541
; CHECK-NEXT: [[TMP9:%.*]] = xor i32 [[TMP5]], 891034567
; CHECK-NEXT: [[TMP10:%.*]] = xor i32 [[TMP9]], [[AND_RA]]
; CHECK-NEXT: [[TMP11:%.*]] = xor i32 [[TMP10]], [[TMP7]]
; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP3:%.*]], 255
; CHECK-NEXT: [[TMP13:%.*]] = add i32 [[TMP1]], 32
; CHECK-NEXT: [[TMP14:%.*]] = add i32 [[TMP13]], [[TMP2]]
; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[TMP14]], [[TMP8]]
; CHECK-NEXT: [[TMP16:%.*]] = add i32 [[TMP15]], [[TMP11]]
; CHECK-NEXT: ret i32 [[TMP16]]
;
%5 = mul i32 %0, 123
%6 = add i32 %2, 24
%7 = add i32 %1, 8
@ -289,6 +339,4 @@ define i32 @xor_bug2(i32, i32, i32, i32) {
%19 = add i32 %18, %12
%20 = add i32 %19, %15
ret i32 %20
;CHECK-LABEL: @xor_bug2(
;CHECK: xor i32 %5, 891034567
}