summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2023-12-21 16:27:11 +0100
committerNikita Popov <npopov@redhat.com>2023-12-21 16:38:09 +0100
commitb8df88b41c8a1b4e879b4fd34be3522c9b45e86f (patch)
tree6581764362ab2b2f13a3d12e42b5dfa70bfd3892
parent4d7112435e31dafb5854f69c516373e4548bd0a3 (diff)
[InstCombine] Support zext nneg in gep of sext add fold
Add m_NNegZext() and m_SExtLike() matchers to make doing these kinds of changes simpler in the future.
-rw-r--r--llvm/include/llvm/IR/PatternMatch.h26
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp2
-rw-r--r--llvm/test/Transforms/InstCombine/array.ll6
3 files changed, 30 insertions, 4 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 096d1688af3f..48afdb867ba6 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -1656,6 +1656,19 @@ template <typename Op_t> struct PtrToIntSameSize_match {
}
};
+template <typename Op_t> struct NNegZExt_match {
+ Op_t Op;
+
+ NNegZExt_match(const Op_t &OpMatch) : Op(OpMatch) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ if (auto *I = dyn_cast<Instruction>(V))
+ return I->getOpcode() == Instruction::ZExt && I->hasNonNeg() &&
+ Op.match(I->getOperand(0));
+ return false;
+ }
+};
+
/// Matches BitCast.
template <typename OpTy>
inline CastOperator_match<OpTy, Instruction::BitCast>
@@ -1708,6 +1721,11 @@ inline CastInst_match<OpTy, Instruction::ZExt> m_ZExt(const OpTy &Op) {
}
template <typename OpTy>
+inline NNegZExt_match<OpTy> m_NNegZExt(const OpTy &Op) {
+ return NNegZExt_match<OpTy>(Op);
+}
+
+template <typename OpTy>
inline match_combine_or<CastInst_match<OpTy, Instruction::ZExt>, OpTy>
m_ZExtOrSelf(const OpTy &Op) {
return m_CombineOr(m_ZExt(Op), Op);
@@ -1719,6 +1737,14 @@ m_SExtOrSelf(const OpTy &Op) {
return m_CombineOr(m_SExt(Op), Op);
}
+/// Match either "sext" or "zext nneg".
+template <typename OpTy>
+inline match_combine_or<CastInst_match<OpTy, Instruction::SExt>,
+ NNegZExt_match<OpTy>>
+m_SExtLike(const OpTy &Op) {
+ return m_CombineOr(m_SExt(Op), m_NNegZExt(Op));
+}
+
template <typename OpTy>
inline match_combine_or<CastInst_match<OpTy, Instruction::ZExt>,
CastInst_match<OpTy, Instruction::SExt>>
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 775720ab43a5..7f5a7b666903 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2516,7 +2516,7 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
Idx2);
}
ConstantInt *C;
- if (match(GEP.getOperand(1), m_OneUse(m_SExt(m_OneUse(m_NSWAdd(
+ if (match(GEP.getOperand(1), m_OneUse(m_SExtLike(m_OneUse(m_NSWAdd(
m_Value(Idx1), m_ConstantInt(C))))))) {
// %add = add nsw i32 %idx1, idx2
// %sidx = sext i32 %add to i64
diff --git a/llvm/test/Transforms/InstCombine/array.ll b/llvm/test/Transforms/InstCombine/array.ll
index 824cf3d663c8..396a7aa340f6 100644
--- a/llvm/test/Transforms/InstCombine/array.ll
+++ b/llvm/test/Transforms/InstCombine/array.ll
@@ -77,9 +77,9 @@ define void @test_zext_nneg(ptr %ptr, i32 %a, i32 %b) {
; CHECK-LABEL: define void @test_zext_nneg(
; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 10
-; CHECK-NEXT: [[IDX:%.*]] = zext nneg i32 [[ADD]] to i64
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
+; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[A]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP0]]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 10
; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 4
; CHECK-NEXT: ret void
;