diff options
author | Nikita Popov <npopov@redhat.com> | 2023-12-21 16:27:11 +0100 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2023-12-21 16:38:09 +0100 |
commit | b8df88b41c8a1b4e879b4fd34be3522c9b45e86f (patch) | |
tree | 6581764362ab2b2f13a3d12e42b5dfa70bfd3892 | |
parent | 4d7112435e31dafb5854f69c516373e4548bd0a3 (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.h | 26 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/array.ll | 6 |
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 ; |