[PATCH] D60600: [InstCombine] Fix a vector-of-pointers instcombine undef bug.
Neil Henning via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 23 03:41:23 PDT 2019
sheredom updated this revision to Diff 196205.
sheredom added a comment.
Fix some review comments by @spatel
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D60600/new/
https://reviews.llvm.org/D60600
Files:
lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
test/Transforms/InstCombine/vec_demanded_elts.ll
Index: test/Transforms/InstCombine/vec_demanded_elts.ll
===================================================================
--- test/Transforms/InstCombine/vec_demanded_elts.ll
+++ test/Transforms/InstCombine/vec_demanded_elts.ll
@@ -638,3 +638,25 @@
%ee = extractelement <2 x i32*> %gep, i32 1
ret i32* %ee
}
+
+%foo = type { float, i8 }
+
+define void @gep_vector_of_pointers_to_struct(float* %out, [2 x %foo]* %in) {
+; CHECK-LABEL: @gep_vector_of_pointers_to_struct(
+; CHECK-NEXT: [[B:%.*]] = insertelement <2 x [2 x %foo]*> undef, [2 x %foo]* [[IN:%.*]], i32 1
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr [2 x %foo], <2 x [2 x %foo]*> [[B]], <2 x i64> <i64 undef, i64 0>, <2 x i64> <i64 undef, i64 1>, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[BC:%.*]] = bitcast <2 x float*> [[GEP]] to <2 x i32*>
+; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x i32*> [[BC]], i64 1
+; CHECK-NEXT: [[LOAD1:%.*]] = load i32, i32* [[TMP1]], align 4
+; CHECK-NEXT: [[TMP2:%.*]] = bitcast float* [[OUT:%.*]] to i32*
+; CHECK-NEXT: store i32 [[LOAD1]], i32* [[TMP2]], align 4
+; CHECK-NEXT: ret void
+;
+ %a = insertelement <2 x [2 x %foo]*> undef, [2 x %foo]* %in, i32 0
+ %b = insertelement <2 x [2 x %foo]*> %a, [2 x %foo]* %in, i32 1
+ %gep = getelementptr [2 x %foo], <2 x [2 x %foo]*> %b, <2 x i32> zeroinitializer, <2 x i32> <i32 0, i32 1>, <2 x i32> zeroinitializer
+ %extract = extractelement <2 x float*> %gep, i64 1
+ %load = load float, float* %extract, align 4
+ store float %load, float* %out
+ ret void
+}
Index: lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1173,18 +1173,35 @@
// operands we may have. We know there must be at least one, or we
// wouldn't have a vector result to get here. Note that we intentionally
// merge the undef bits here since gepping with either an undef base or
- // index results in undef.
- for (unsigned i = 0; i < I->getNumOperands(); i++) {
- if (isa<UndefValue>(I->getOperand(i))) {
+ // index results in undef.
+
+ auto simplifyGEPOperand = [&](unsigned Idx, bool IsIndexStruct) {
+ if (isa<UndefValue>(I->getOperand(Idx))) {
// If the entire vector is undefined, just return this info.
UndefElts = EltMask;
- return nullptr;
+ return true;
}
- if (I->getOperand(i)->getType()->isVectorTy()) {
+
+ if (!IsIndexStruct && I->getOperand(Idx)->getType()->isVectorTy()) {
+ // If we have a vector of indices into a struct element of the GEP, and
+ // change a single element of this into an undef while preserving the
+ // others, that breaks the guarantee that each index of a
+ // vector-of-pointers into a struct will have the same index.
APInt UndefEltsOp(VWidth, 0);
- simplifyAndSetOp(I, i, DemandedElts, UndefEltsOp);
+ simplifyAndSetOp(I, Idx, DemandedElts, UndefEltsOp);
UndefElts |= UndefEltsOp;
}
+
+ return false;
+ };
+
+ if (simplifyGEPOperand(0, false))
+ return nullptr;
+
+ gep_type_iterator GTI = gep_type_begin(cast<GetElementPtrInst>(I));
+ for (unsigned Idx = 1; Idx < I->getNumOperands(); Idx++, GTI++) {
+ if (simplifyGEPOperand(Idx, GTI.isStruct()))
+ return nullptr;
}
break;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60600.196205.patch
Type: text/x-patch
Size: 3483 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190423/365793d5/attachment.bin>
More information about the llvm-commits
mailing list