[InstCombine] remove incorrect gep(x, undef) -> undef optimization

gep(x, undef) carries the provenance of x, so we can't replace it with any
pointer like undef.
This leaves room for improvement for the poison case, but that's currently
not possible as the demanded bits API doesn't distinguish between undef &
poison bits.

Fixes #44790
This commit is contained in:
Nuno Lopes 2022-01-30 11:34:32 +00:00
parent 0dc20e321c
commit dd995aceda
3 changed files with 18 additions and 7 deletions

View File

@ -1219,7 +1219,7 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
for (auto I = gep_type_begin(GEP), E = gep_type_end(GEP);
I != E; I++)
if (I.isStruct())
return true;;
return true;
return false;
};
if (mayIndexStructType(cast<GetElementPtrInst>(*I)))
@ -1228,10 +1228,11 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
// Conservatively track the demanded elements back through any vector
// 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.
// merge the undef bits here since gepping with either an poison base or
// index results in poison.
for (unsigned i = 0; i < I->getNumOperands(); i++) {
if (match(I->getOperand(i), m_Undef())) {
if (i == 0 ? match(I->getOperand(i), m_Undef())
: match(I->getOperand(i), m_Poison())) {
// If the entire vector is undefined, just return this info.
UndefElts = EltMask;
return nullptr;
@ -1239,7 +1240,11 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
if (I->getOperand(i)->getType()->isVectorTy()) {
APInt UndefEltsOp(VWidth, 0);
simplifyAndSetOp(I, i, DemandedElts, UndefEltsOp);
UndefElts |= UndefEltsOp;
// gep(x, undef) is not undef, so skip considering idx ops here
// Note that we could propagate poison, but we can't distinguish between
// undef & poison bits ATM
if (i == 0)
UndefElts |= UndefEltsOp;
}
}

View File

@ -614,7 +614,10 @@ define i32* @gep_splat_both(i32* %base, i64 %idx) {
define <2 x i32*> @gep_all_lanes_undef(i32* %base, i64 %idx) {;
; CHECK-LABEL: @gep_all_lanes_undef(
; CHECK-NEXT: ret <2 x i32*> undef
; CHECK-NEXT: [[BASEVEC:%.*]] = insertelement <2 x i32*> poison, i32* [[BASE:%.*]], i64 0
; CHECK-NEXT: [[IDXVEC:%.*]] = insertelement <2 x i64> poison, i64 [[IDX:%.*]], i64 1
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, <2 x i32*> [[BASEVEC]], <2 x i64> [[IDXVEC]]
; CHECK-NEXT: ret <2 x i32*> [[GEP]]
;
%basevec = insertelement <2 x i32*> poison, i32* %base, i32 0
%idxvec = insertelement <2 x i64> poison, i64 %idx, i32 1

View File

@ -614,7 +614,10 @@ define i32* @gep_splat_both(i32* %base, i64 %idx) {
define <2 x i32*> @gep_all_lanes_undef(i32* %base, i64 %idx) {;
; CHECK-LABEL: @gep_all_lanes_undef(
; CHECK-NEXT: ret <2 x i32*> undef
; CHECK-NEXT: [[BASEVEC:%.*]] = insertelement <2 x i32*> undef, i32* [[BASE:%.*]], i64 0
; CHECK-NEXT: [[IDXVEC:%.*]] = insertelement <2 x i64> undef, i64 [[IDX:%.*]], i64 1
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, <2 x i32*> [[BASEVEC]], <2 x i64> [[IDXVEC]]
; CHECK-NEXT: ret <2 x i32*> [[GEP]]
;
%basevec = insertelement <2 x i32*> undef, i32* %base, i32 0
%idxvec = insertelement <2 x i64> undef, i64 %idx, i32 1