|  | ; RUN: opt %s -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 | 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 true. | 
|  | ; CHECK-LABEL: @test_eq_uge | 
|  | ; CHECK: call void @is(i1 true) | 
|  | ; CHECK-NOT: 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 true. | 
|  | ; CHECK-LABEL: @test_eq_ule | 
|  | ; CHECK: call void @is(i1 true) | 
|  | ; CHECK-NOT: 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 true. | 
|  | ; CHECK-LABEL: @test_eq_sge | 
|  | ; CHECK: call void @is(i1 true) | 
|  | ; CHECK-NOT: 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 true. | 
|  | ; CHECK-LABEL: @test_eq_sle | 
|  | ; CHECK: call void @is(i1 true) | 
|  | ; CHECK-NOT: 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 | 
|  | } | 
|  |  | 
|  | ; A >=u 5 implies A <u 5 is false. | 
|  | ; CHECK-LABEL: @test_uge_ult_const | 
|  | ; CHECK-NOT: call void @is(i1 true) | 
|  | ; CHECK: call void @is(i1 false) | 
|  | define void @test_uge_ult_const(i32 %a, i32 %b) { | 
|  | %cmp1 = icmp uge i32 %a, 5 | 
|  | br i1 %cmp1, label %taken, label %untaken | 
|  |  | 
|  | taken: | 
|  | %cmp2 = icmp ult i32 %a, 5 | 
|  | br i1 %cmp2, label %istrue, label %isfalse | 
|  |  | 
|  | istrue: | 
|  | call void @is(i1 true) | 
|  | ret void | 
|  |  | 
|  | isfalse: | 
|  | call void @is(i1 false) | 
|  | ret void | 
|  |  | 
|  | untaken: | 
|  | ret void | 
|  | } |