diff options
author | Chad Rosier <mcrosier@codeaurora.org> | 2016-04-22 17:14:12 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@codeaurora.org> | 2016-04-22 17:14:12 +0000 |
commit | 3456cb5672715f9d7528cae17fbe1de395240a5c (patch) | |
tree | 0480c227ad5680329ecc1f7759c20c4b1a31cbda /llvm/test | |
parent | 1960d13e29ad8520ebbec3d24fb4b0b58c548091 (diff) | |
download | bcm5719-llvm-3456cb5672715f9d7528cae17fbe1de395240a5c.tar.gz bcm5719-llvm-3456cb5672715f9d7528cae17fbe1de395240a5c.zip |
[SimplifyCFG] Add missing implications to isImpliedTrueByMatchingCmp.
Summary: [u|s]gt and [u|s]lt imply [u|s]ge and [u|s]le are true, respectively.
I've simplified the existing tests and added additional tests to cover the new
cases mentioned above. I've also added tests for all the cases where the
first compare doesn't imply anything about the second compare.
llvm-svn: 267171
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/Transforms/SimplifyCFG/implied-cond-matching.ll | 1005 |
1 files changed, 1005 insertions, 0 deletions
diff --git a/llvm/test/Transforms/SimplifyCFG/implied-cond-matching.ll b/llvm/test/Transforms/SimplifyCFG/implied-cond-matching.ll new file mode 100644 index 00000000000..e49139bc1e3 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/implied-cond-matching.ll @@ -0,0 +1,1005 @@ +; RUN: opt %s -S -simplifycfg | FileCheck %s + +declare void @dead() +declare void @alive() +declare void @is(i1) + +; Test same condition with swapped operands. +; void test_swapped_ops(unsigned a, unsigned b) { +; if (a > b) { +; if (b > a) <- always false +; dead(); +; alive(); +; } +; } +; +; CHECK-LABEL: @test_swapped_ops +; CHECK-NOT: call void @dead() +; CHECK: call void @alive() +; CHECK: ret +define void @test_swapped_ops(i32 %a, i32 %b) { +entry: + %cmp = icmp ugt i32 %a, %b + br i1 %cmp, label %if.then, label %if.end3 + +if.then: + %cmp1 = icmp ugt i32 %b, %a + br i1 %cmp1, label %if.then2, label %if.end + +if.then2: + call void @dead() + br label %if.end + +if.end: + call void @alive() + br label %if.end3 + +if.end3: + ret void +} + +; void test_swapped_pred(unsigned a, unsigned b) { +; if (a > b) { +; alive(); +; if (b < a) <- always true; remove branch +; alive(); +; } +; } +; +; CHECK-LABEL: @test_swapped_pred +; CHECK: call void @alive() +; CHECK-NEXT: call void @alive() +; CHECK: ret +define void @test_swapped_pred(i32 %a, i32 %b) { +entry: + %cmp = icmp ugt i32 %a, %b + br i1 %cmp, label %if.then, label %if.end3 + +if.then: + call void @alive() + %cmp1 = icmp ult i32 %b, %a + br i1 %cmp1, label %if.then2, label %if.end3 + +if.then2: + call void @alive() + br label %if.end3 + +if.end3: + ret void +} + +; A == B implies A == B is true. +; CHECK-LABEL: @test_eq_eq +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_eq_eq(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp eq i32 %a, %b + br i1 %cmp2, label %eq_eq_istrue, label %eq_eq_isfalse + +eq_eq_istrue: + call void @is(i1 true) + ret void + +eq_eq_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A != B is false. +; CHECK-LABEL: @test_eq_ne +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_ne(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ne i32 %a, %b + br i1 %cmp2, label %eq_ne_istrue, label %eq_ne_isfalse + +eq_ne_istrue: + call void @is(i1 true) + ret void + +eq_ne_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A >u B is false. +; CHECK-LABEL: @test_eq_ugt +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_ugt(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ugt i32 %a, %b + br i1 %cmp2, label %eq_ugt_istrue, label %eq_ugt_isfalse + +eq_ugt_istrue: + call void @is(i1 true) + ret void + +eq_ugt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A >=u B is unknown to be true or false. +; CHECK-LABEL: @test_eq_uge +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_uge(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp uge i32 %a, %b + br i1 %cmp2, label %eq_uge_istrue, label %eq_uge_isfalse + +eq_uge_istrue: + call void @is(i1 true) + ret void + +eq_uge_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A <u B is false. +; CHECK-LABEL: @test_eq_ult +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_ult(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ult i32 %a, %b + br i1 %cmp2, label %eq_ult_istrue, label %eq_ult_isfalse + +eq_ult_istrue: + call void @is(i1 true) + ret void + +eq_ult_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A <=u B is unknown to be true or false. +; CHECK-LABEL: @test_eq_ule +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_ule(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ule i32 %a, %b + br i1 %cmp2, label %eq_ule_istrue, label %eq_ule_isfalse + +eq_ule_istrue: + call void @is(i1 true) + ret void + +eq_ule_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A >s B is false. +; CHECK-LABEL: @test_eq_sgt +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_sgt(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sgt i32 %a, %b + br i1 %cmp2, label %eq_sgt_istrue, label %eq_sgt_isfalse + +eq_sgt_istrue: + call void @is(i1 true) + ret void + +eq_sgt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A >=s B is unknown to be true or false. +; CHECK-LABEL: @test_eq_sge +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_sge(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sge i32 %a, %b + br i1 %cmp2, label %eq_sge_istrue, label %eq_sge_isfalse + +eq_sge_istrue: + call void @is(i1 true) + ret void + +eq_sge_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A <s B is false. +; CHECK-LABEL: @test_eq_slt +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_slt(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp slt i32 %a, %b + br i1 %cmp2, label %eq_slt_istrue, label %eq_slt_isfalse + +eq_slt_istrue: + call void @is(i1 true) + ret void + +eq_slt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A == B implies A <=s B is unknown to be true or false. +; CHECK-LABEL: @test_eq_sle +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_eq_sle(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sle i32 %a, %b + br i1 %cmp2, label %eq_sle_istrue, label %eq_sle_isfalse + +eq_sle_istrue: + call void @is(i1 true) + ret void + +eq_sle_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A != B is true. +; CHECK-LABEL: @test_ne_ne +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_ne_ne(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ne i32 %a, %b + br i1 %cmp2, label %ne_ne_istrue, label %ne_ne_isfalse + +ne_ne_istrue: + call void @is(i1 true) + ret void + +ne_ne_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A >u B is unknown to be true or false. +; CHECK-LABEL: @test_ne_ugt +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ne_ugt(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ugt i32 %a, %b + br i1 %cmp2, label %ne_ugt_istrue, label %ne_ugt_isfalse + +ne_ugt_istrue: + call void @is(i1 true) + ret void + +ne_ugt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A >=u B is unknown to be true or false. +; CHECK-LABEL: @test_ne_uge +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ne_uge(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp uge i32 %a, %b + br i1 %cmp2, label %ne_uge_istrue, label %ne_uge_isfalse + +ne_uge_istrue: + call void @is(i1 true) + ret void + +ne_uge_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A <u B is unknown to be true or false. +; CHECK-LABEL: @test_ne_ult +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ne_ult(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ult i32 %a, %b + br i1 %cmp2, label %ne_ult_istrue, label %ne_ult_isfalse + +ne_ult_istrue: + call void @is(i1 true) + ret void + +ne_ult_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A <=u B is unknown to be true or false. +; CHECK-LABEL: @test_ne_ule +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ne_ule(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ule i32 %a, %b + br i1 %cmp2, label %ne_ule_istrue, label %ne_ule_isfalse + +ne_ule_istrue: + call void @is(i1 true) + ret void + +ne_ule_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A >s B is unknown to be true or false. +; CHECK-LABEL: @test_ne_sgt +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ne_sgt(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sgt i32 %a, %b + br i1 %cmp2, label %ne_sgt_istrue, label %ne_sgt_isfalse + +ne_sgt_istrue: + call void @is(i1 true) + ret void + +ne_sgt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A >=s B is unknown to be true or false. +; CHECK-LABEL: @test_ne_sge +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ne_sge(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sge i32 %a, %b + br i1 %cmp2, label %ne_sge_istrue, label %ne_sge_isfalse + +ne_sge_istrue: + call void @is(i1 true) + ret void + +ne_sge_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A <s B is unknown to be true or false. +; CHECK-LABEL: @test_ne_slt +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ne_slt(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp slt i32 %a, %b + br i1 %cmp2, label %ne_slt_istrue, label %ne_slt_isfalse + +ne_slt_istrue: + call void @is(i1 true) + ret void + +ne_slt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A != B implies A <=s B is unknown to be true or false. +; CHECK-LABEL: @test_ne_sle +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ne_sle(i32 %a, i32 %b) { + %cmp1 = icmp ne i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sle i32 %a, %b + br i1 %cmp2, label %ne_sle_istrue, label %ne_sle_isfalse + +ne_sle_istrue: + call void @is(i1 true) + ret void + +ne_sle_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >u B implies A >u B is true. +; CHECK-LABEL: @test_ugt_ugt +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_ugt_ugt(i32 %a, i32 %b) { + %cmp1 = icmp ugt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ugt i32 %a, %b + br i1 %cmp2, label %ugt_ugt_istrue, label %ugt_ugt_isfalse + +ugt_ugt_istrue: + call void @is(i1 true) + ret void + +ugt_ugt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >u B implies A >=u B is true. +; CHECK-LABEL: @test_ugt_uge +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_ugt_uge(i32 %a, i32 %b) { + %cmp1 = icmp ugt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp uge i32 %a, %b + br i1 %cmp2, label %ugt_uge_istrue, label %ugt_uge_isfalse + +ugt_uge_istrue: + call void @is(i1 true) + ret void + +ugt_uge_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >u B implies A <u B is false. +; CHECK-LABEL: @test_ugt_ult +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ugt_ult(i32 %a, i32 %b) { + %cmp1 = icmp ugt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ult i32 %a, %b + br i1 %cmp2, label %ugt_ult_istrue, label %ugt_ult_isfalse + +ugt_ult_istrue: + call void @is(i1 true) + ret void + +ugt_ult_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >u B implies A <=u B is false. +; CHECK-LABEL: @test_ugt_ule +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_ugt_ule(i32 %a, i32 %b) { + %cmp1 = icmp ugt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ule i32 %a, %b + br i1 %cmp2, label %ugt_ule_istrue, label %ugt_ule_isfalse + +ugt_ule_istrue: + call void @is(i1 true) + ret void + +ugt_ule_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >=u B implies A >=u B is true. +; CHECK-LABEL: @test_uge_uge +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_uge_uge(i32 %a, i32 %b) { + %cmp1 = icmp uge i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp uge i32 %a, %b + br i1 %cmp2, label %uge_uge_istrue, label %uge_uge_isfalse + +uge_uge_istrue: + call void @is(i1 true) + ret void + +uge_uge_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >=u B implies A <u B is false. +; CHECK-LABEL: @test_uge_ult +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_uge_ult(i32 %a, i32 %b) { + %cmp1 = icmp uge i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ult i32 %a, %b + br i1 %cmp2, label %uge_ult_istrue, label %uge_ult_isfalse + +uge_ult_istrue: + call void @is(i1 true) + ret void + +uge_ult_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >=u B implies A <=u B is unknown to be true or false. +; CHECK-LABEL: @test_uge_ule +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_uge_ule(i32 %a, i32 %b) { + %cmp1 = icmp uge i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ule i32 %a, %b + br i1 %cmp2, label %uge_ule_istrue, label %uge_ule_isfalse + +uge_ule_istrue: + call void @is(i1 true) + ret void + +uge_ule_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A <u B implies A <u B is true. +; CHECK-LABEL: @test_ult_ult +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_ult_ult(i32 %a, i32 %b) { + %cmp1 = icmp ult i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ult i32 %a, %b + br i1 %cmp2, label %ult_ult_istrue, label %ult_ult_isfalse + +ult_ult_istrue: + call void @is(i1 true) + ret void + +ult_ult_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A <u B implies A <=u B is true. +; CHECK-LABEL: @test_ult_ule +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_ult_ule(i32 %a, i32 %b) { + %cmp1 = icmp ult i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ule i32 %a, %b + br i1 %cmp2, label %ult_ule_istrue, label %ult_ule_isfalse + +ult_ule_istrue: + call void @is(i1 true) + ret void + +ult_ule_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A <=u B implies A <=u B is true. +; CHECK-LABEL: @test_ule_ule +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_ule_ule(i32 %a, i32 %b) { + %cmp1 = icmp ule i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp ule i32 %a, %b + br i1 %cmp2, label %ule_ule_istrue, label %ule_ule_isfalse + +ule_ule_istrue: + call void @is(i1 true) + ret void + +ule_ule_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >s B implies A >s B is true. +; CHECK-LABEL: @test_sgt_sgt +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_sgt_sgt(i32 %a, i32 %b) { + %cmp1 = icmp sgt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sgt i32 %a, %b + br i1 %cmp2, label %sgt_sgt_istrue, label %sgt_sgt_isfalse + +sgt_sgt_istrue: + call void @is(i1 true) + ret void + +sgt_sgt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >s B implies A >=s B is true. +; CHECK-LABEL: @test_sgt_sge +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_sgt_sge(i32 %a, i32 %b) { + %cmp1 = icmp sgt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sge i32 %a, %b + br i1 %cmp2, label %sgt_sge_istrue, label %sgt_sge_isfalse + +sgt_sge_istrue: + call void @is(i1 true) + ret void + +sgt_sge_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >s B implies A <s B is false. +; CHECK-LABEL: @test_sgt_slt +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_sgt_slt(i32 %a, i32 %b) { + %cmp1 = icmp sgt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp slt i32 %a, %b + br i1 %cmp2, label %sgt_slt_istrue, label %sgt_slt_isfalse + +sgt_slt_istrue: + call void @is(i1 true) + ret void + +sgt_slt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >s B implies A <=s B is false. +; CHECK-LABEL: @test_sgt_sle +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_sgt_sle(i32 %a, i32 %b) { + %cmp1 = icmp sgt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sle i32 %a, %b + br i1 %cmp2, label %sgt_sle_istrue, label %sgt_sle_isfalse + +sgt_sle_istrue: + call void @is(i1 true) + ret void + +sgt_sle_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >=s B implies A >=s B is true. +; CHECK-LABEL: @test_sge_sge +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_sge_sge(i32 %a, i32 %b) { + %cmp1 = icmp sge i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sge i32 %a, %b + br i1 %cmp2, label %sge_sge_istrue, label %sge_sge_isfalse + +sge_sge_istrue: + call void @is(i1 true) + ret void + +sge_sge_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >=s B implies A <s B is false. +; CHECK-LABEL: @test_sge_slt +; CHECK-NOT: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_sge_slt(i32 %a, i32 %b) { + %cmp1 = icmp sge i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp slt i32 %a, %b + br i1 %cmp2, label %sge_slt_istrue, label %sge_slt_isfalse + +sge_slt_istrue: + call void @is(i1 true) + ret void + +sge_slt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A >=s B implies A <=s B is unknown to be true or false. +; CHECK-LABEL: @test_sge_sle +; CHECK: call void @is(i1 true) +; CHECK: call void @is(i1 false) +define void @test_sge_sle(i32 %a, i32 %b) { + %cmp1 = icmp sge i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sle i32 %a, %b + br i1 %cmp2, label %sge_sle_istrue, label %sge_sle_isfalse + +sge_sle_istrue: + call void @is(i1 true) + ret void + +sge_sle_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A <s B implies A <s B is true. +; CHECK-LABEL: @test_slt_slt +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_slt_slt(i32 %a, i32 %b) { + %cmp1 = icmp slt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp slt i32 %a, %b + br i1 %cmp2, label %slt_slt_istrue, label %slt_slt_isfalse + +slt_slt_istrue: + call void @is(i1 true) + ret void + +slt_slt_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A <s B implies A <=s B is true. +; CHECK-LABEL: @test_slt_sle +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_slt_sle(i32 %a, i32 %b) { + %cmp1 = icmp slt i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sle i32 %a, %b + br i1 %cmp2, label %slt_sle_istrue, label %slt_sle_isfalse + +slt_sle_istrue: + call void @is(i1 true) + ret void + +slt_sle_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} + +; A <=s B implies A <=s B is true. +; CHECK-LABEL: @test_sle_sle +; CHECK: call void @is(i1 true) +; CHECK-NOT: call void @is(i1 false) +define void @test_sle_sle(i32 %a, i32 %b) { + %cmp1 = icmp sle i32 %a, %b + br i1 %cmp1, label %taken, label %untaken + +taken: + %cmp2 = icmp sle i32 %a, %b + br i1 %cmp2, label %sle_sle_istrue, label %sle_sle_isfalse + +sle_sle_istrue: + call void @is(i1 true) + ret void + +sle_sle_isfalse: + call void @is(i1 false) + ret void + +untaken: + ret void +} |