[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