[llvm] fa1eb2e - [ConstraintElimination] Add tests to check for `or` instruction decomposition if a constant operand is < 2^known_zero_bits of the first operand.

Zain Jaffal via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 20 06:39:50 PST 2023


Author: Zain Jaffal
Date: 2023-02-20T14:39:02Z
New Revision: fa1eb2eb1606de47f29261e1b5ae43a2db13ef7d

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

LOG: [ConstraintElimination] Add tests to check for `or` instruction decomposition if a constant operand is < 2^known_zero_bits of the first operand.

Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D142545

Added: 
    

Modified: 
    llvm/test/Transforms/ConstraintElimination/or.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/ConstraintElimination/or.ll b/llvm/test/Transforms/ConstraintElimination/or.ll
index 5a120c9213025..4fa8edd83c291 100644
--- a/llvm/test/Transforms/ConstraintElimination/or.ll
+++ b/llvm/test/Transforms/ConstraintElimination/or.ll
@@ -431,3 +431,364 @@ exit:
 
   ret i1 %res.9
 }
+
+define void @test_or_as_add_ult(i8 %init_val, i8 %high) {
+; CHECK-LABEL: @test_or_as_add_ult(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2
+; CHECK-NEXT:    [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3
+; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]
+; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[F_0:%.*]] = icmp ult i8 [[START]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_0]])
+; CHECK-NEXT:    [[I_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ult i8 [[I_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[I_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[F_2:%.*]] = icmp ult i8 [[I_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    ret void
+; CHECK:       end:
+; CHECK-NEXT:    [[T_0:%.*]] = icmp ult i8 [[START]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[START_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8 [[START_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[START_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i8 [[START_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    [[START_3:%.*]] = or i8 [[START]], 3
+; CHECK-NEXT:    [[T_3:%.*]] = icmp ult i8 [[START_3]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_3]])
+; CHECK-NEXT:    [[START_4:%.*]] = or i8 [[START]], 4
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  %start = shl nuw nsw i8 %init_val, 2
+  %start.plus.3 = add nuw i8 %start, 3
+  %c.1 = icmp uge i8 %start.plus.3, %high
+  br i1 %c.1, label %then, label %end
+
+then:                                          ; preds = %entry
+  %f.0 = icmp ult i8 %start, %high
+  call void @use(i1 %f.0)
+  %i.1 = or i8 %start, 1
+  %f.1 = icmp ult i8 %i.1, %high
+  call void @use(i1 %f.1)
+  %i.2 = or i8 %start, 2
+  %f.2 = icmp ult i8 %i.2, %high
+  call void @use(i1 %f.2)
+  ret void
+
+end:                                           ; preds = %entry
+  %t.0 = icmp ult i8 %start, %high
+  call void @use(i1 %t.0)
+  %start.1 = or i8 %start, 1
+  %t.1 = icmp ult i8 %start.1, %high
+  call void @use(i1 %t.1)
+  %start.2 = or i8 %start, 2
+  %t.2 = icmp ult i8 %start.2, %high
+  call void @use(i1 %t.2)
+  %start.3 = or i8 %start, 3
+  %t.3 = icmp ult i8 %start.3, %high
+  call void @use(i1 %t.3)
+  %start.4 = or i8 %start, 4
+  %c.4 = icmp ult i8 %start.4, %high
+  call void @use(i1 %c.4)
+  ret void
+}
+
+define void @test_or_as_add_ule(i8 %init_val, i8 %high) {
+; CHECK-LABEL: @test_or_as_add_ule(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2
+; CHECK-NEXT:    [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3
+; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]
+; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[F_0:%.*]] = icmp ule i8 [[START]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_0]])
+; CHECK-NEXT:    [[I_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i8 [[I_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[I_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[F_2:%.*]] = icmp ule i8 [[I_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    ret void
+; CHECK:       end:
+; CHECK-NEXT:    [[T_0:%.*]] = icmp ule i8 [[START]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[START_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i8 [[START_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[START_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i8 [[START_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    [[START_3:%.*]] = or i8 [[START]], 3
+; CHECK-NEXT:    [[T_3:%.*]] = icmp ule i8 [[START_3]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_3]])
+; CHECK-NEXT:    [[START_4:%.*]] = or i8 [[START]], 4
+; CHECK-NEXT:    [[T_4:%.*]] = icmp ule i8 [[START_4]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_4]])
+; CHECK-NEXT:    [[START_5:%.*]] = or i8 [[START]], 5
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ule i8 [[START_5]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  %start = shl nuw nsw i8 %init_val, 2
+  %start.plus.3 = add nuw i8 %start, 3
+  %c.1 = icmp uge i8 %start.plus.3, %high
+  br i1 %c.1, label %then, label %end
+
+then:                                          ; preds = %entry
+  %f.0 = icmp ule i8 %start, %high
+  call void @use(i1 %f.0)
+  %i.1 = or i8 %start, 1
+  %f.1 = icmp ule i8 %i.1, %high
+  call void @use(i1 %f.1)
+  %i.2 = or i8 %start, 2
+  %f.2 = icmp ule i8 %i.2, %high
+  call void @use(i1 %f.2)
+  ret void
+
+end:                                           ; preds = %entry
+  %t.0 = icmp ule i8 %start, %high
+  call void @use(i1 %t.0)
+  %start.1 = or i8 %start, 1
+  %t.1 = icmp ule i8 %start.1, %high
+  call void @use(i1 %t.1)
+  %start.2 = or i8 %start, 2
+  %t.2 = icmp ule i8 %start.2, %high
+  call void @use(i1 %t.2)
+  %start.3 = or i8 %start, 3
+  %t.3 = icmp ule i8 %start.3, %high
+  call void @use(i1 %t.3)
+  %start.4 = or i8 %start, 4
+  %t.4 = icmp ule i8 %start.4, %high
+  call void @use(i1 %t.4)
+  %start.5 = or i8 %start, 5
+  %c.5 = icmp ule i8 %start.5, %high
+  call void @use(i1 %c.5)
+
+  ret void
+}
+
+define void @test_or_as_add_ugt(i8 %init_val, i8 %high) {
+; CHECK-LABEL: @test_or_as_add_ugt(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2
+; CHECK-NEXT:    [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3
+; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]
+; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[T_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_0]])
+; CHECK-NEXT:    [[I_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i8 [[I_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[I_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[T_2:%.*]] = icmp ugt i8 [[I_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    ret void
+; CHECK:       end:
+; CHECK-NEXT:    [[F_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    [[START_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i8 [[START_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[START_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[F_2:%.*]] = icmp ugt i8 [[START_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    [[START_3:%.*]] = or i8 [[START]], 3
+; CHECK-NEXT:    [[F_3:%.*]] = icmp ugt i8 [[START_3]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_3]])
+; CHECK-NEXT:    [[START_4:%.*]] = or i8 [[START]], 4
+; CHECK-NEXT:    [[F_4:%.*]] = icmp ugt i8 [[START_4]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_4]])
+; CHECK-NEXT:    [[START_5:%.*]] = or i8 [[START]], 5
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i8 [[START_5]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  %start = shl nuw nsw i8 %init_val, 2
+  %start.plus.3 = add nuw i8 %start, 3
+  %c.1 = icmp uge i8 %start.plus.3, %high
+  br i1 %c.1, label %then, label %end
+
+then:                                          ; preds = %entry
+  %t.0 = icmp ugt i8 %start, %high
+  call void @use(i1 %t.0)
+  %i.1 = or i8 %start, 1
+  %t.1 = icmp ugt i8 %i.1, %high
+  call void @use(i1 %t.1)
+  %i.2 = or i8 %start, 2
+  %t.2 = icmp ugt i8 %i.2, %high
+  call void @use(i1 %t.2)
+  ret void
+
+end:                                           ; preds = %entry
+  %f.0 = icmp ugt i8 %start, %high
+  call void @use(i1 %f.0)
+  %start.1 = or i8 %start, 1
+  %f.1 = icmp ugt i8 %start.1, %high
+  call void @use(i1 %f.1)
+  %start.2 = or i8 %start, 2
+  %f.2 = icmp ugt i8 %start.2, %high
+  call void @use(i1 %f.2)
+  %start.3 = or i8 %start, 3
+  %f.3 = icmp ugt i8 %start.3, %high
+  call void @use(i1 %f.3)
+  %start.4 = or i8 %start, 4
+  %f.4 = icmp ugt i8 %start.4, %high
+  call void @use(i1 %f.4)
+  %start.5 = or i8 %start, 5
+  %c.5 = icmp ugt i8 %start.5, %high
+  call void @use(i1 %c.5)
+  ret void
+}
+
+define void @test_or_as_add_uge(i8 %init_val, i8 %high) {
+; CHECK-LABEL: @test_or_as_add_uge(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[START:%.*]] = shl nuw nsw i8 [[INIT_VAL:%.*]], 2
+; CHECK-NEXT:    [[START_PLUS_3:%.*]] = add nuw i8 [[START]], 3
+; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]
+; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[T_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_0]])
+; CHECK-NEXT:    [[I_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[I_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    ret void
+; CHECK:       end:
+; CHECK-NEXT:    [[F_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    [[START_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[F_1:%.*]] = icmp uge i8 [[START_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[START_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[F_2:%.*]] = icmp uge i8 [[START_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    [[START_3:%.*]] = or i8 [[START]], 3
+; CHECK-NEXT:    [[F_3:%.*]] = icmp uge i8 [[START_3]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_3]])
+; CHECK-NEXT:    [[START_4:%.*]] = or i8 [[START]], 4
+; CHECK-NEXT:    [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[START_5:%.*]] = or i8 [[START]], 5
+; CHECK-NEXT:    [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  %start = shl nuw nsw i8 %init_val, 2
+  %start.plus.3 = add nuw i8 %start, 3
+  %c.1 = icmp uge i8 %start.plus.3, %high
+  br i1 %c.1, label %then, label %end
+
+then:                                          ; preds = %entry
+  %t.0 = icmp ugt i8 %start, %high
+  call void @use(i1 %t.0)
+  %i.1 = or i8 %start, 1
+  %t.1 = icmp uge i8 %i.1, %high
+  call void @use(i1 %t.1)
+  %i.2 = or i8 %start, 2
+  %t.2 = icmp uge i8 %i.2, %high
+  call void @use(i1 %t.2)
+  ret void
+
+end:                                           ; preds = %entry
+  %f.0 = icmp ugt i8 %start, %high
+  call void @use(i1 %f.0)
+  %start.1 = or i8 %start, 1
+  %f.1 = icmp uge i8 %start.1, %high
+  call void @use(i1 %f.1)
+  %start.2 = or i8 %start, 2
+  %f.2 = icmp uge i8 %start.2, %high
+  call void @use(i1 %f.2)
+  %start.3 = or i8 %start, 3
+  %f.3 = icmp uge i8 %start.3, %high
+  call void @use(i1 %f.3)
+  %start.4 = or i8 %start, 4
+  %c.4 = icmp uge i8 %start.4, %high
+  call void @use(i1 %c.4)
+  %start.5 = or i8 %start, 5
+  %c.5 = icmp uge i8 %start.5, %high
+  call void @use(i1 %c.5)
+  ret void
+}
+
+define void @test_not_decompose(i8 %start, i8 %high) {
+; CHECK-LABEL: @test_not_decompose(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[START_PLUS_3:%.*]] = add nuw i8 [[START:%.*]], 3
+; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]
+; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[I_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[I_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    ret void
+; CHECK:       end:
+; CHECK-NEXT:    [[START_1:%.*]] = or i8 [[START]], 1
+; CHECK-NEXT:    [[F_1:%.*]] = icmp uge i8 [[START_1]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[START_2:%.*]] = or i8 [[START]], 2
+; CHECK-NEXT:    [[F_2:%.*]] = icmp uge i8 [[START_2]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    [[START_3:%.*]] = or i8 [[START]], 3
+; CHECK-NEXT:    [[F_3:%.*]] = icmp uge i8 [[START_3]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[F_3]])
+; CHECK-NEXT:    [[START_4:%.*]] = or i8 [[START]], 4
+; CHECK-NEXT:    [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[START_5:%.*]] = or i8 [[START]], 5
+; CHECK-NEXT:    [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]]
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  %start.plus.3 = add nuw i8 %start, 3
+  %c.1 = icmp uge i8 %start.plus.3, %high
+  br i1 %c.1, label %then, label %end
+
+then:                                          ; preds = %entry
+  %i.1 = or i8 %start, 1
+  %t.1 = icmp uge i8 %i.1, %high
+  call void @use(i1 %t.1)
+  %i.2 = or i8 %start, 2
+  %t.2 = icmp uge i8 %i.2, %high
+  call void @use(i1 %t.2)
+  ret void
+
+end:                                           ; preds = %entry
+  %start.1 = or i8 %start, 1
+  %f.1 = icmp uge i8 %start.1, %high
+  call void @use(i1 %f.1)
+  %start.2 = or i8 %start, 2
+  %f.2 = icmp uge i8 %start.2, %high
+  call void @use(i1 %f.2)
+  %start.3 = or i8 %start, 3
+  %f.3 = icmp uge i8 %start.3, %high
+  call void @use(i1 %f.3)
+  %start.4 = or i8 %start, 4
+  %c.4 = icmp uge i8 %start.4, %high
+  call void @use(i1 %c.4)
+  %start.5 = or i8 %start, 5
+  %c.5 = icmp uge i8 %start.5, %high
+  call void @use(i1 %c.5)
+
+  ret void
+}


        


More information about the llvm-commits mailing list