[llvm] c014454 - [ConstraintElim] Add extra tests with AND and OR of conditions.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 17 13:08:55 PST 2023


Author: Florian Hahn
Date: 2023-12-17T21:08:26Z
New Revision: c014454f43bf523fee2bf695c075882b1cefd21c

URL: https://github.com/llvm/llvm-project/commit/c014454f43bf523fee2bf695c075882b1cefd21c
DIFF: https://github.com/llvm/llvm-project/commit/c014454f43bf523fee2bf695c075882b1cefd21c.diff

LOG: [ConstraintElim] Add extra tests with AND and OR of conditions.

Add additional tests where one of the operands of the AND/OR implies the
other.

Added: 
    llvm/test/Transforms/ConstraintElimination/or-implied-by-operands.ll

Modified: 
    llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll b/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll
index 22f20f739b9e6f..dc3b0f17c79602 100644
--- a/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll
+++ b/llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll
@@ -26,6 +26,31 @@ else:
   ret i1 1
 }
 
+define i1 @test_first_and_condition_implied_by_second_ops(i8 %x) {
+; CHECK-LABEL: @test_first_and_condition_implied_by_second_ops(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[T_1]], [[C_1]]
+; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ugt i8 %x, 10
+  %t.1 = icmp ugt i8 %x, 5
+  %and = and i1 %t.1, %c.1
+  br i1 %and, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
 define i1 @test_second_and_condition_implied_by_first_select_form(i8 %x) {
 ; CHECK-LABEL: @test_second_and_condition_implied_by_first_select_form(
 ; CHECK-NEXT:  entry:
@@ -51,6 +76,31 @@ else:
   ret i1 1
 }
 
+define i1 @test_first_and_condition_implied_by_second_select_form(i8 %x) {
+; CHECK-LABEL: @test_first_and_condition_implied_by_second_select_form(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[T_1]], i1 [[C_1]], i1 false
+; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ugt i8 %x, 10
+  %t.1 = icmp ugt i8 %x, 5
+  %and = select i1 %t.1, i1 %c.1, i1 false
+  br i1 %and, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
 define i1 @test_same_cond_for_and(i8 %x) {
 ; CHECK-LABEL: @test_same_cond_for_and(
 ; CHECK-NEXT:  entry:
@@ -394,3 +444,37 @@ then:
 else:
   ret i1 %t.1
 }
+
+define i1 @and_select_first_implies_second_may_be_poison(ptr noundef %A, ptr noundef %B) {
+; CHECK-LABEL: @and_select_first_implies_second_may_be_poison(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_2]], i1 true, i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+entry:
+  %c.1 = icmp ne ptr %A, %B
+  %gep = getelementptr inbounds ptr, ptr %B, i64 -1
+  %c.2 = icmp ugt ptr %gep, %A
+  %and = select i1 %c.2, i1 %c.1, i1 false
+  ret i1 %and
+}
+
+define i1 @and_select_second_implies_first_may_be_poison(ptr noundef %A, ptr noundef %B) {
+; CHECK-LABEL: @and_select_second_implies_first_may_be_poison(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+entry:
+  %c.1 = icmp ne ptr %A, %B
+  %gep = getelementptr inbounds ptr, ptr %B, i64 -1
+  %c.2 = icmp ugt ptr %gep, %A
+  %and = select i1 %c.1, i1 %c.2, i1 false
+  ret i1 %and
+}

diff  --git a/llvm/test/Transforms/ConstraintElimination/or-implied-by-operands.ll b/llvm/test/Transforms/ConstraintElimination/or-implied-by-operands.ll
new file mode 100644
index 00000000000000..61e6e250f6dd99
--- /dev/null
+++ b/llvm/test/Transforms/ConstraintElimination/or-implied-by-operands.ll
@@ -0,0 +1,310 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
+
+define i1 @test_second_or_condition_implied_by_first(i8 %x) {
+; CHECK-LABEL: @test_second_or_condition_implied_by_first(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_1]], [[T_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ule i8 %x, 10
+  %t.1 = icmp ugt i8 %x, 5
+  %or = or i1 %c.1, %t.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
+define i1 @test_first_or_condition_implied_by_second_ops(i8 %x) {
+; CHECK-LABEL: @test_first_or_condition_implied_by_second_ops(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T_1]], [[C_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ule i8 %x, 10
+  %t.1 = icmp ugt i8 %x, 5
+  %or = or i1 %t.1, %c.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
+define i1 @test_second_or_condition_implied_by_first_select_form(i8 %x) {
+; CHECK-LABEL: @test_second_or_condition_implied_by_first_select_form(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
+; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C_1]], i1 false, i1 [[T_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ule i8 %x, 10
+  %t.1 = icmp ugt i8 %x, 5
+  %or = select i1 %c.1, i1 false, i1 %t.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
+define i1 @test_first_or_condition_implied_by_second_select_form(i8 %x) {
+; CHECK-LABEL: @test_first_or_condition_implied_by_second_select_form(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
+; CHECK-NEXT:    [[OR:%.*]] = select i1 [[T_1]], i1 false, i1 [[C_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ule i8 %x, 10
+  %t.1 = icmp ugt i8 %x, 5
+  %or = select i1 %t.1, i1 false, i1 %c.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
+define i1 @test_same_cond_for_or(i8 %x) {
+; CHECK-LABEL: @test_same_cond_for_or(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_1]], [[C_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ugt i8 %x, 10
+  %or = or i1 %c.1, %c.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
+define i1 @test_same_cond_for_or_select_form(i8 %x) {
+; CHECK-LABEL: @test_same_cond_for_or_select_form(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C_1]], i1 false, i1 [[C_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ugt i8 %x, 10
+  %or = select i1 %c.1, i1 false, i1 %c.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
+define i1 @test_second_or_condition_not_implied_by_first(i8 %x) {
+; CHECK-LABEL: @test_second_or_condition_not_implied_by_first(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i8 [[X]], 5
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_2]], [[C_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  %c.1 = icmp ugt i8 %x, 10
+  %c.2 = icmp ugt i8 %x, 5
+  %or = or i1 %c.2, %c.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 0
+
+else:
+  ret i1 1
+}
+
+define i1 @test_remove_variables(i1 %c, ptr %A, i64 %B, ptr %C) {
+; CHECK-LABEL: @test_remove_variables(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN_1:%.*]], label [[EXIT:%.*]]
+; CHECK:       then.1:
+; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C:%.*]], align 8
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[TMP0]], [[A:%.*]]
+; CHECK-NEXT:    br i1 [[C_1]], label [[THEN_2:%.*]], label [[ELSE_2:%.*]]
+; CHECK:       then.2:
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ne ptr [[A]], null
+; CHECK-NEXT:    [[C_3:%.*]] = icmp sgt i64 [[B:%.*]], 0
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_2]], [[C_3]]
+; CHECK-NEXT:    ret i1 [[OR]]
+; CHECK:       else.2:
+; CHECK-NEXT:    ret i1 false
+; CHECK:       exit:
+; CHECK-NEXT:    ret i1 true
+;
+entry:
+  br i1 %c, label %then.1, label %exit
+
+then.1:
+  %0 = load ptr, ptr %C, align 8
+  %c.1 = icmp ult ptr %0, %A
+  br i1 %c.1, label %then.2, label %else.2
+
+then.2:
+  %c.2 = icmp ne ptr %A, null
+  %c.3 = icmp sgt i64 %B, 0
+  %or = or i1 %c.2, %c.3
+  ret i1 %or
+
+else.2:
+  ret i1 0
+
+exit:
+  %t = icmp eq ptr null, null
+  ret i1 %t
+}
+
+define i1 @test_or_op_0_simplified(i32 %v) {
+; CHECK-LABEL: @test_or_op_0_simplified(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0
+; CHECK-NEXT:    [[OR:%.*]] = or i1 false, [[C_1]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+entry:
+  %c.1 = icmp sgt i32 %v, 0
+  %t.1 = icmp sgt i32 0, 0
+  %or = or i1 %t.1, %c.1
+  ret i1 %or
+}
+
+define i1 @test_or_op_1_simplified(i32 %v) {
+; CHECK-LABEL: @test_or_op_1_simplified(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_1]], false
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+entry:
+  %c.1 = icmp sgt i32 %v, 0
+  %t.1 = icmp sgt i32 0, 0
+  %or = or i1 %c.1, %t.1
+  ret i1 %or
+}
+
+define i1 @test_or_used_in_false_branch(i8 %x) {
+; CHECK-LABEL: @test_or_used_in_false_branch(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[X]], 5
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_1]], [[T_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 [[T_1]]
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 false
+;
+
+entry:
+  %c.1 = icmp ule i8 %x, 10
+  %t.1 = icmp ule i8 %x, 5
+  %or = or i1 %c.1, %t.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 %t.1
+
+else:
+  ret i1 %t.1
+}
+
+define i1 @test_or_used_in_false_branch2(i8 %x) {
+; CHECK-LABEL: @test_or_used_in_false_branch2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[X]], 5
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_1]], [[T_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    ret i1 [[T_1]]
+; CHECK:       else:
+; CHECK-NEXT:    ret i1 false
+;
+
+entry:
+  %c.1 = icmp ugt i8 %x, 10
+  %t.1 = icmp ugt i8 %x, 5
+  %or = or i1 %c.1, %t.1
+  br i1 %or, label %then, label %else
+
+then:
+  ret i1 %t.1
+
+else:
+  ret i1 %t.1
+}
+
+define i1 @select_or_set_operand(ptr noundef %a, ptr noundef %b) {
+; CHECK-LABEL: @select_or_set_operand(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP_EQ:%.*]] = icmp eq ptr [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[INCDEC_PTR12_I:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 1
+; CHECK-NEXT:    [[CMP_EQ_1:%.*]] = icmp eq ptr [[INCDEC_PTR12_I]], [[B]]
+; CHECK-NEXT:    [[OR:%.*]] = select i1 [[CMP_EQ]], i1 true, i1 [[CMP_EQ_1]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+entry:
+  %cmp.eq = icmp eq ptr %a, %b
+  %incdec.ptr12.i = getelementptr inbounds i32, ptr %a, i64 1
+  %cmp.eq.1 = icmp eq ptr %incdec.ptr12.i, %b
+  %or = select i1 %cmp.eq, i1 true, i1 %cmp.eq.1
+  ret i1 %or
+}


        


More information about the llvm-commits mailing list