[llvm] ed23609 - [PatternMatch] Do not match constant expressions for binops

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 29 02:22:04 PDT 2023


Author: Nikita Popov
Date: 2023-07-29T11:21:22+02:00
New Revision: ed23609bc2adcf3c9b4a446d7a74580adfa76092

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

LOG: [PatternMatch] Do not match constant expressions for binops

Currently, m_Mul() style matchers also match constant expressions.
This is a regular source of assertion failures (usually by trying
to do a match and then cast to Instruction or BinaryOperator) and
infinite combine loops. At the same time, I don't think this provides
useful optimization capabilities (all of the tests affected here are
regression tests for crashes / infinite loops).

Long term, all of these constant expressions (apart from possibly
add/sub) are slated for removal per
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
-- but doing those removals can itself expose new crashes and
infinite loops due to the current PatternMatch behavior.

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

Added: 
    

Modified: 
    llvm/include/llvm/IR/PatternMatch.h
    llvm/test/Transforms/InstCombine/mul-inseltpoison.ll
    llvm/test/Transforms/InstCombine/mul.ll
    llvm/test/Transforms/InstCombine/pr32686.ll
    llvm/test/Transforms/InstCombine/switch-constant-expr.ll
    llvm/test/Transforms/InstCombine/udiv-simplify.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 621eba6bd0b679..13877538f79de6 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -972,11 +972,6 @@ struct BinaryOp_match {
              (Commutable && L.match(I->getOperand(1)) &&
               R.match(I->getOperand(0)));
     }
-    if (auto *CE = dyn_cast<ConstantExpr>(V))
-      return CE->getOpcode() == Opc &&
-             ((L.match(CE->getOperand(0)) && R.match(CE->getOperand(1))) ||
-              (Commutable && L.match(CE->getOperand(1)) &&
-               R.match(CE->getOperand(0))));
     return false;
   }
 
@@ -1258,9 +1253,6 @@ struct BinOpPred_match : Predicate {
     if (auto *I = dyn_cast<Instruction>(V))
       return this->isOpType(I->getOpcode()) && L.match(I->getOperand(0)) &&
              R.match(I->getOperand(1));
-    if (auto *CE = dyn_cast<ConstantExpr>(V))
-      return this->isOpType(CE->getOpcode()) && L.match(CE->getOperand(0)) &&
-             R.match(CE->getOperand(1));
     return false;
   }
 };

diff  --git a/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll b/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll
index f0c97c1707cdee..f2e618173367ae 100644
--- a/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll
@@ -570,8 +570,8 @@ define i64 @test30(i32 %A, i32 %B) {
 @PR22087 = external global i32
 define i32 @test31(i32 %V) {
 ; CHECK-LABEL: @test31(
-; CHECK-NEXT:    [[MUL1:%.*]] = shl i32 [[V:%.*]], zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32)
-; CHECK-NEXT:    ret i32 [[MUL1]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[V:%.*]], shl (i32 1, i32 zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32))
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %mul = mul i32 %V, shl (i32 1, i32 zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32))
   ret i32 %mul
@@ -686,8 +686,7 @@ define i64 @test_mul_canonicalize_neg_is_not_undone(i64 %L1) {
 ; Check we do not undo the canonicalization of 0 - (X * Y), if Y is a constant
 ; expr.
 ; CHECK-LABEL: @test_mul_canonicalize_neg_is_not_undone(
-; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[L1:%.*]], ptrtoint (ptr @X to i64)
-; CHECK-NEXT:    [[B4:%.*]] = sub i64 0, [[TMP1]]
+; CHECK-NEXT:    [[B4:%.*]] = mul i64 [[L1:%.*]], sub (i64 0, i64 ptrtoint (ptr @X to i64))
 ; CHECK-NEXT:    ret i64 [[B4]]
 ;
   %v1 = ptrtoint ptr @X to i64

diff  --git a/llvm/test/Transforms/InstCombine/mul.ll b/llvm/test/Transforms/InstCombine/mul.ll
index 81f634a879c9c7..de2b5115266360 100644
--- a/llvm/test/Transforms/InstCombine/mul.ll
+++ b/llvm/test/Transforms/InstCombine/mul.ll
@@ -1131,8 +1131,8 @@ define i64 @test30(i32 %A, i32 %B) {
 @PR22087 = external global i32
 define i32 @test31(i32 %V) {
 ; CHECK-LABEL: @test31(
-; CHECK-NEXT:    [[MUL1:%.*]] = shl i32 [[V:%.*]], zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32)
-; CHECK-NEXT:    ret i32 [[MUL1]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[V:%.*]], shl (i32 1, i32 zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32))
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %mul = mul i32 %V, shl (i32 1, i32 zext (i1 icmp ne (ptr inttoptr (i64 1 to ptr), ptr @PR22087) to i32))
   ret i32 %mul
@@ -1247,8 +1247,7 @@ define i64 @test_mul_canonicalize_neg_is_not_undone(i64 %L1) {
 ; Check we do not undo the canonicalization of 0 - (X * Y), if Y is a constant
 ; expr.
 ; CHECK-LABEL: @test_mul_canonicalize_neg_is_not_undone(
-; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[L1:%.*]], ptrtoint (ptr @X to i64)
-; CHECK-NEXT:    [[B4:%.*]] = sub i64 0, [[TMP1]]
+; CHECK-NEXT:    [[B4:%.*]] = mul i64 [[L1:%.*]], sub (i64 0, i64 ptrtoint (ptr @X to i64))
 ; CHECK-NEXT:    ret i64 [[B4]]
 ;
   %v1 = ptrtoint ptr @X to i64

diff  --git a/llvm/test/Transforms/InstCombine/pr32686.ll b/llvm/test/Transforms/InstCombine/pr32686.ll
index acce81a603d2d0..d77f30e31320a5 100644
--- a/llvm/test/Transforms/InstCombine/pr32686.ll
+++ b/llvm/test/Transforms/InstCombine/pr32686.ll
@@ -8,9 +8,9 @@ define void @tinkywinky() {
 ; CHECK-LABEL: @tinkywinky(
 ; CHECK-NEXT:    [[PATATINO:%.*]] = load i8, ptr @a, align 1
 ; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i8 [[PATATINO]], 0
-; CHECK-NEXT:    [[TMP1:%.*]] = zext i1 [[TOBOOL_NOT]] to i32
-; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[TMP1]], or (i32 zext (i1 icmp ne (ptr @a, ptr @b) to i32), i32 2)
-; CHECK-NEXT:    store i32 [[OR1]], ptr @b, align 4
+; CHECK-NEXT:    [[LNOT_EXT:%.*]] = zext i1 [[TOBOOL_NOT]] to i32
+; CHECK-NEXT:    [[OR:%.*]] = or i32 [[LNOT_EXT]], xor (i32 zext (i1 icmp ne (ptr @a, ptr @b) to i32), i32 2)
+; CHECK-NEXT:    store i32 [[OR]], ptr @b, align 4
 ; CHECK-NEXT:    ret void
 ;
   %patatino = load i8, ptr @a

diff  --git a/llvm/test/Transforms/InstCombine/switch-constant-expr.ll b/llvm/test/Transforms/InstCombine/switch-constant-expr.ll
index 4116177103d26b..e3a5e2ac8c117c 100644
--- a/llvm/test/Transforms/InstCombine/switch-constant-expr.ll
+++ b/llvm/test/Transforms/InstCombine/switch-constant-expr.ll
@@ -6,7 +6,7 @@
 ; PR30486
 define i32 @single_case() {
 ; CHECK-LABEL: @single_case(
-; CHECK-NEXT:    switch i32 ptrtoint (ptr @g to i32), label [[X:%.*]] [
+; CHECK-NEXT:    switch i32 add (i32 ptrtoint (ptr @g to i32), i32 -1), label [[X:%.*]] [
 ; CHECK-NEXT:    ]
 ; CHECK:       x:
 ; CHECK-NEXT:    ret i32 0
@@ -18,9 +18,9 @@ x:
 
 define i32 @multiple_cases() {
 ; CHECK-LABEL: @multiple_cases(
-; CHECK-NEXT:    switch i32 ptrtoint (ptr @g to i32), label [[X:%.*]] [
-; CHECK-NEXT:    i32 2, label [[ONE:%.*]]
-; CHECK-NEXT:    i32 3, label [[TWO:%.*]]
+; CHECK-NEXT:    switch i32 add (i32 ptrtoint (ptr @g to i32), i32 -1), label [[X:%.*]] [
+; CHECK-NEXT:    i32 1, label [[ONE:%.*]]
+; CHECK-NEXT:    i32 2, label [[TWO:%.*]]
 ; CHECK-NEXT:    ]
 ; CHECK:       x:
 ; CHECK-NEXT:    ret i32 0

diff  --git a/llvm/test/Transforms/InstCombine/udiv-simplify.ll b/llvm/test/Transforms/InstCombine/udiv-simplify.ll
index d7b300e98f1d7f..724170e376b35a 100644
--- a/llvm/test/Transforms/InstCombine/udiv-simplify.ll
+++ b/llvm/test/Transforms/InstCombine/udiv-simplify.ll
@@ -55,8 +55,8 @@ define i64 @test2_PR2274(i32 %x, i32 %v) nounwind {
 define i32 @PR30366(i1 %a) {
 ; CHECK-LABEL: @PR30366(
 ; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[A:%.*]] to i32
-; CHECK-NEXT:    [[D1:%.*]] = lshr i32 [[Z]], zext (i16 ptrtoint (ptr @b to i16) to i32)
-; CHECK-NEXT:    ret i32 [[D1]]
+; CHECK-NEXT:    [[D:%.*]] = udiv i32 [[Z]], zext (i16 shl (i16 1, i16 ptrtoint (ptr @b to i16)) to i32)
+; CHECK-NEXT:    ret i32 [[D]]
 ;
   %z = zext i1 %a to i32
   %d = udiv i32 %z, zext (i16 shl (i16 1, i16 ptrtoint (ptr @b to i16)) to i32)


        


More information about the llvm-commits mailing list