diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/test/Transforms/InstCombine/select-implied.ll | 158 |
1 files changed, 116 insertions, 42 deletions
diff --git a/llvm/test/Transforms/InstCombine/select-implied.ll b/llvm/test/Transforms/InstCombine/select-implied.ll index 2558745c18f..e925031b653 100644 --- a/llvm/test/Transforms/InstCombine/select-implied.ll +++ b/llvm/test/Transforms/InstCombine/select-implied.ll @@ -1,10 +1,18 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -instcombine -S | FileCheck %s ; A == B implies A >u B is false. -; CHECK-LABEL: @test1 -; CHECK-NOT: select -; CHECK: call void @foo(i32 10) + define void @test1(i32 %a, i32 %b) { +; CHECK-LABEL: @test1( +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] +; CHECK: taken: +; CHECK-NEXT: call void @foo(i32 10) +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: ret void +; %cmp1 = icmp eq i32 %a, %b br i1 %cmp1, label %taken, label %end @@ -19,10 +27,17 @@ end: } ; If A == B is false then A != B is true. -; CHECK-LABEL: @test2 -; CHECK-NOT: select -; CHECK: call void @foo(i32 20) + define void @test2(i32 %a, i32 %b) { +; CHECK-LABEL: @test2( +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] +; CHECK: taken: +; CHECK-NEXT: call void @foo(i32 20) +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: ret void +; %cmp1 = icmp eq i32 %a, %b br i1 %cmp1, label %end, label %taken @@ -37,10 +52,17 @@ end: } ; A >u 10 implies A >u 10 is true. -; CHECK-LABEL: @test3 -; CHECK-NOT: select -; CHECK: call void @foo(i32 30) + define void @test3(i32 %a) { +; CHECK-LABEL: @test3( +; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 10 +; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] +; CHECK: taken: +; CHECK-NEXT: call void @foo(i32 30) +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: ret void +; %cmp1 = icmp ugt i32 %a, 10 br i1 %cmp1, label %taken, label %end @@ -54,37 +76,55 @@ end: ret void } -; CHECK-LABEL: @PR23333 -; CHECK-NOT: select -; CHECK: ret i8 1 define i8 @PR23333(i8 addrspace(1)* %ptr) { - %cmp = icmp eq i8 addrspace(1)* %ptr, null - br i1 %cmp, label %taken, label %end +; CHECK-LABEL: @PR23333( +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 addrspace(1)* [[PTR:%.*]], null +; CHECK-NEXT: br i1 [[CMP]], label [[TAKEN:%.*]], label [[END:%.*]] +; CHECK: taken: +; CHECK-NEXT: ret i8 1 +; CHECK: end: +; CHECK-NEXT: ret i8 0 +; + %cmp = icmp eq i8 addrspace(1)* %ptr, null + br i1 %cmp, label %taken, label %end taken: - %cmp2 = icmp ne i8 addrspace(1)* %ptr, null - %res = select i1 %cmp2, i8 2, i8 1 - ret i8 %res + %cmp2 = icmp ne i8 addrspace(1)* %ptr, null + %res = select i1 %cmp2, i8 2, i8 1 + ret i8 %res end: - ret i8 0 + ret i8 0 } ; We know the condition of the select is true based on a dominating condition. ; Therefore, we can replace %cond with %len. However, now the inner icmp is ; always false and can be elided. -; CHECK-LABEL: @test4 -; CHECK-NOT: select + define void @test4(i32 %len) { +; CHECK-LABEL: @test4( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i32 @bar(i32 [[LEN:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LEN]], 4 +; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[B1:%.*]] +; CHECK: bb: +; CHECK-NEXT: br i1 false, label [[B0:%.*]], label [[B1]] +; CHECK: b0: +; CHECK-NEXT: br label [[B1]] +; CHECK: b1: +; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[LEN]], [[BB]] ], [ undef, [[B0]] ], [ [[TMP0]], [[ENTRY:%.*]] ] +; CHECK-NEXT: br label [[RET:%.*]] +; CHECK: ret: +; CHECK-NEXT: call void @foo(i32 [[TMP1]]) +; CHECK-NEXT: ret void +; entry: %0 = call i32 @bar(i32 %len); %cmp = icmp ult i32 %len, 4 br i1 %cmp, label %bb, label %b1 bb: %cond = select i1 %cmp, i32 %len, i32 8 -; CHECK-NOT: %cmp11 = icmp eq i32 %{{.*}}, 8 %cmp11 = icmp eq i32 %cond, 8 -; CHECK: br i1 false, label %b0, label %b1 br i1 %cmp11, label %b0, label %b1 b0: @@ -92,7 +132,6 @@ b0: br label %b1 b1: -; CHECK: phi i32 [ %len, %bb ], [ undef, %b0 ], [ %0, %entry ] %1 = phi i32 [ %cond, %bb ], [ undef, %b0 ], [ %0, %entry ] br label %ret @@ -102,10 +141,17 @@ ret: } ; A >u 10 implies A >u 9 is true. -; CHECK-LABEL: @test5 -; CHECK-NOT: select -; CHECK: call void @foo(i32 30) + define void @test5(i32 %a) { +; CHECK-LABEL: @test5( +; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 10 +; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] +; CHECK: taken: +; CHECK-NEXT: call void @foo(i32 30) +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: ret void +; %cmp1 = icmp ugt i32 %a, 10 br i1 %cmp1, label %taken, label %end @@ -122,11 +168,18 @@ end: declare void @foo(i32) declare i32 @bar(i32) -; CHECK-LABEL: @test_and -; CHECK: tpath: -; CHECK-NOT: select -; CHECK: ret i32 313 define i32 @test_and(i32 %a, i32 %b) { +; CHECK-LABEL: @test_and( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 0 +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[B:%.*]], 0 +; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] +; CHECK-NEXT: br i1 [[AND]], label [[TPATH:%.*]], label [[END:%.*]] +; CHECK: tpath: +; CHECK-NEXT: ret i32 313 +; CHECK: end: +; CHECK-NEXT: ret i32 0 +; entry: %cmp1 = icmp ne i32 %a, 0 %cmp2 = icmp ne i32 %b, 0 @@ -143,11 +196,19 @@ end: } ; cmp1 and cmp2 are false on the 'fpath' path and thus cmp3 is true. -; CHECK-LABEL: @test_or1 -; CHECK: fpath: -; CHECK-NOT: select -; CHECK: ret i32 37 + define i32 @test_or1(i32 %a, i32 %b) { +; CHECK-LABEL: @test_or1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0 +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[B:%.*]], 0 +; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] +; CHECK-NEXT: br i1 [[OR]], label [[END:%.*]], label [[FPATH:%.*]] +; CHECK: fpath: +; CHECK-NEXT: ret i32 37 +; CHECK: end: +; CHECK-NEXT: ret i32 0 +; entry: %cmp1 = icmp eq i32 %a, 0 %cmp2 = icmp eq i32 %b, 0 @@ -164,11 +225,17 @@ end: } ; LHS ==> RHS by definition (true -> true) -; CHECK-LABEL: @test6 -; CHECK: taken: -; CHECK-NOT: select -; CHECK: call void @foo(i32 10) + define void @test6(i32 %a, i32 %b) { +; CHECK-LABEL: @test6( +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] +; CHECK: taken: +; CHECK-NEXT: call void @foo(i32 10) +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: ret void +; %cmp1 = icmp eq i32 %a, %b br i1 %cmp1, label %taken, label %end @@ -182,11 +249,17 @@ end: } ; LHS ==> RHS by definition (false -> false) -; CHECK-LABEL: @test7 -; CHECK: taken: -; CHECK-NOT: select -; CHECK: call void @foo(i32 11) + define void @test7(i32 %a, i32 %b) { +; CHECK-LABEL: @test7( +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] +; CHECK: taken: +; CHECK-NEXT: call void @foo(i32 11) +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: ret void +; %cmp1 = icmp eq i32 %a, %b br i1 %cmp1, label %end, label %taken @@ -198,3 +271,4 @@ taken: end: ret void } + |

