[PATCH] D75807: [InstCombine] fold gep-of-select-of-constants (PR45084)
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 10 06:26:11 PDT 2020
This revision was automatically updated to reflect the committed changes.
Closed by commit rG467eec09109f: [InstCombine] fold gep-of-select-of-constants (PR45084) (authored by spatel).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75807/new/
https://reviews.llvm.org/D75807
Files:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/getelementptr.ll
llvm/test/Transforms/InstCombine/mem-gep-zidx.ll
Index: llvm/test/Transforms/InstCombine/mem-gep-zidx.ll
===================================================================
--- llvm/test/Transforms/InstCombine/mem-gep-zidx.ll
+++ llvm/test/Transforms/InstCombine/mem-gep-zidx.ll
@@ -35,9 +35,7 @@
define signext i32 @test3(i32 signext %x, i1 %y) #0 {
; CHECK-LABEL: @test3(
-; CHECK-NEXT: [[P:%.*]] = select i1 [[Y:%.*]], [1 x i32]* @f.a, [1 x i32]* @f.b
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* [[P]], i64 0, i64 0
-; CHECK-NEXT: [[R:%.*]] = load i32, i32* [[TMP1]], align 4
+; CHECK-NEXT: [[R:%.*]] = select i1 [[Y:%.*]], i32 12, i32 55
; CHECK-NEXT: ret i32 [[R]]
;
%idxprom = sext i32 %x to i64
Index: llvm/test/Transforms/InstCombine/getelementptr.ll
===================================================================
--- llvm/test/Transforms/InstCombine/getelementptr.ll
+++ llvm/test/Transforms/InstCombine/getelementptr.ll
@@ -1216,8 +1216,7 @@
define i32* @PR45084(i1 %cond) {
; CHECK-LABEL: @PR45084(
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], %struct.f* @g0, %struct.f* @g1, !prof !0
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_F:%.*]], %struct.f* [[SEL]], i64 0, i32 0
+; CHECK-NEXT: [[GEP:%.*]] = select i1 [[COND:%.*]], i32* getelementptr inbounds (%struct.f, %struct.f* @g0, i64 0, i32 0), i32* getelementptr inbounds (%struct.f, %struct.f* @g1, i64 0, i32 0), !prof !0
; CHECK-NEXT: ret i32* [[GEP]]
;
%sel = select i1 %cond, %struct.f* @g0, %struct.f* @g1, !prof !0
@@ -1229,7 +1228,7 @@
; CHECK-LABEL: @PR45084_extra_use(
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], %struct.f* @g0, %struct.f* @g1
; CHECK-NEXT: store %struct.f* [[SEL]], %struct.f** [[P:%.*]], align 8
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr [[STRUCT_F:%.*]], %struct.f* [[SEL]], i64 0, i32 0
+; CHECK-NEXT: [[GEP:%.*]] = select i1 [[COND]], i32* getelementptr inbounds (%struct.f, %struct.f* @g0, i64 0, i32 0), i32* getelementptr inbounds (%struct.f, %struct.f* @g1, i64 0, i32 0)
; CHECK-NEXT: ret i32* [[GEP]]
;
%sel = select i1 %cond, %struct.f* @g0, %struct.f* @g1
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1803,6 +1803,33 @@
(GEP2.isInBounds() || GEP2.hasAllZeroIndices());
}
+/// Thread a GEP operation with constant indices through the constant true/false
+/// arms of a select.
+static Instruction *foldSelectGEP(GetElementPtrInst &GEP,
+ InstCombiner::BuilderTy &Builder) {
+ if (!GEP.hasAllConstantIndices())
+ return nullptr;
+
+ Instruction *Sel;
+ Value *Cond;
+ Constant *TrueC, *FalseC;
+ if (!match(GEP.getPointerOperand(), m_Instruction(Sel)) ||
+ !match(Sel,
+ m_Select(m_Value(Cond), m_Constant(TrueC), m_Constant(FalseC))))
+ return nullptr;
+
+ // gep (select Cond, TrueC, FalseC), IndexC --> select Cond, TrueC', FalseC'
+ // Propagate 'inbounds' and metadata from existing instructions.
+ // Note: using IRBuilder to create the constants for efficiency.
+ SmallVector<Value *, 4> IndexC(GEP.idx_begin(), GEP.idx_end());
+ bool IsInBounds = GEP.isInBounds();
+ Value *NewTrueC = IsInBounds ? Builder.CreateInBoundsGEP(TrueC, IndexC)
+ : Builder.CreateGEP(TrueC, IndexC);
+ Value *NewFalseC = IsInBounds ? Builder.CreateInBoundsGEP(FalseC, IndexC)
+ : Builder.CreateGEP(FalseC, IndexC);
+ return SelectInst::Create(Cond, NewTrueC, NewFalseC, "", nullptr, Sel);
+}
+
Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
SmallVector<Value*, 8> Ops(GEP.op_begin(), GEP.op_end());
Type *GEPType = GEP.getType();
@@ -2446,6 +2473,9 @@
}
}
+ if (Instruction *R = foldSelectGEP(GEP, Builder))
+ return R;
+
return nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D75807.249355.patch
Type: text/x-patch
Size: 4026 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200310/b9e6f296/attachment.bin>
More information about the llvm-commits
mailing list