[llvm] r330237 - [InstCombine] peek through bitcasted vector/array pointer GEP operand
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 17 17:36:40 PDT 2018
Author: spatel
Date: Tue Apr 17 17:36:40 2018
New Revision: 330237
URL: http://llvm.org/viewvc/llvm-project?rev=330237&view=rev
Log:
[InstCombine] peek through bitcasted vector/array pointer GEP operand
The bitcast may be interfering with other combines or vectorization
as shown in PR16739:
https://bugs.llvm.org/show_bug.cgi?id=16739
Most pointer-related optimizations are probably able to look through
this bitcast, but removing the bitcast shrinks the IR, so it's at
least a size savings.
Differential Revision: https://reviews.llvm.org/D44833
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/trunk/test/Transforms/InstCombine/gep-vector.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=330237&r1=330236&r2=330237&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Tue Apr 17 17:36:40 2018
@@ -1945,14 +1945,34 @@ Instruction *InstCombiner::visitGetEleme
PtrOp = BC;
}
- /// See if we can simplify:
- /// X = bitcast A* to B*
- /// Y = gep X, <...constant indices...>
- /// into a gep of the original struct. This is important for SROA and alias
- /// analysis of unions. If "A" is also a bitcast, wait for A/X to be merged.
if (auto *BCI = dyn_cast<BitCastInst>(PtrOp)) {
Value *SrcOp = BCI->getOperand(0);
PointerType *SrcType = cast<PointerType>(BCI->getSrcTy());
+ Type *SrcEltType = SrcType->getElementType();
+
+ // GEP directly using the source operand if this GEP is accessing an element
+ // of a bitcasted pointer to vector or array of the same dimensions:
+ // gep (bitcast <c x ty>* X to [c x ty]*), Y, Z --> gep X, Y, Z
+ // gep (bitcast [c x ty]* X to <c x ty>*), Y, Z --> gep X, Y, Z
+ auto areMatchingArrayAndVecTypes = [](Type *ArrTy, Type *VecTy) {
+ return ArrTy->getArrayElementType() == VecTy->getVectorElementType() &&
+ ArrTy->getArrayNumElements() == VecTy->getVectorNumElements();
+ };
+ if (GEP.getNumOperands() == 3 &&
+ ((GEPEltType->isArrayTy() && SrcEltType->isVectorTy() &&
+ areMatchingArrayAndVecTypes(GEPEltType, SrcEltType)) ||
+ (GEPEltType->isVectorTy() && SrcEltType->isArrayTy() &&
+ areMatchingArrayAndVecTypes(SrcEltType, GEPEltType)))) {
+ GEP.setOperand(0, SrcOp);
+ GEP.setSourceElementType(SrcEltType);
+ return &GEP;
+ }
+
+ // See if we can simplify:
+ // X = bitcast A* to B*
+ // Y = gep X, <...constant indices...>
+ // into a gep of the original struct. This is important for SROA and alias
+ // analysis of unions. If "A" is also a bitcast, wait for A/X to be merged.
unsigned OffsetBits = DL.getIndexTypeSizeInBits(GEPType);
APInt Offset(OffsetBits, 0);
if (!isa<BitCastInst>(SrcOp) && GEP.accumulateConstantOffset(DL, Offset)) {
Modified: llvm/trunk/test/Transforms/InstCombine/gep-vector.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/gep-vector.ll?rev=330237&r1=330236&r2=330237&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/gep-vector.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/gep-vector.ll Tue Apr 17 17:36:40 2018
@@ -27,3 +27,23 @@ define <2 x i8*> @vectorindex3() {
ret <2 x i8*> %1
}
+define i32* @bitcast_vec_to_array_gep(<7 x i32>* %x, i64 %y, i64 %z) {
+; CHECK-LABEL: @bitcast_vec_to_array_gep(
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr <7 x i32>, <7 x i32>* [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT: ret i32* [[GEP]]
+;
+ %arr_ptr = bitcast <7 x i32>* %x to [7 x i32]*
+ %gep = getelementptr [7 x i32], [7 x i32]* %arr_ptr, i64 %y, i64 %z
+ ret i32* %gep
+}
+
+define i32* @bitcast_array_to_vec_gep([3 x i32]* %x, i64 %y, i64 %z) {
+; CHECK-LABEL: @bitcast_array_to_vec_gep(
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [3 x i32], [3 x i32]* [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT: ret i32* [[GEP]]
+;
+ %vec_ptr = bitcast [3 x i32]* %x to <3 x i32>*
+ %gep = getelementptr inbounds <3 x i32>, <3 x i32>* %vec_ptr, i64 %y, i64 %z
+ ret i32* %gep
+}
+
More information about the llvm-commits
mailing list