Skip to content

Commit 3ed5acf

Browse files
committed
Fixups after review feedback:
- Make sure we try to derive inbound + nuw before doing the ADD+GEP->GEP+GEP rewrites. This to make it possible to rely on "nuw" being present when trying to preserve flags. - Make sure the special ADDNSW+SEXTLIKE+GEP->GEP+GEP case is checking for ADDNUW+ZEXTNNEG+GEP->GEP+GEP when preserving flags. This way we do not need to check for non-negative operands.
1 parent 0abeb7b commit 3ed5acf

File tree

1 file changed

+48
-51
lines changed

1 file changed

+48
-51
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3086,23 +3086,51 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
30863086
if (GEPType->isVectorTy())
30873087
return nullptr;
30883088

3089+
if (!GEP.isInBounds()) {
3090+
unsigned IdxWidth =
3091+
DL.getIndexSizeInBits(PtrOp->getType()->getPointerAddressSpace());
3092+
APInt BasePtrOffset(IdxWidth, 0);
3093+
Value *UnderlyingPtrOp =
3094+
PtrOp->stripAndAccumulateInBoundsConstantOffsets(DL,
3095+
BasePtrOffset);
3096+
bool CanBeNull, CanBeFreed;
3097+
uint64_t DerefBytes = UnderlyingPtrOp->getPointerDereferenceableBytes(
3098+
DL, CanBeNull, CanBeFreed);
3099+
if (!CanBeNull && !CanBeFreed && DerefBytes != 0) {
3100+
if (GEP.accumulateConstantOffset(DL, BasePtrOffset) &&
3101+
BasePtrOffset.isNonNegative()) {
3102+
APInt AllocSize(IdxWidth, DerefBytes);
3103+
if (BasePtrOffset.ule(AllocSize)) {
3104+
return GetElementPtrInst::CreateInBounds(
3105+
GEP.getSourceElementType(), PtrOp, Indices, GEP.getName());
3106+
}
3107+
}
3108+
}
3109+
}
3110+
3111+
// nusw + nneg -> nuw
3112+
if (GEP.hasNoUnsignedSignedWrap() && !GEP.hasNoUnsignedWrap() &&
3113+
all_of(GEP.indices(), [&](Value *Idx) {
3114+
return isKnownNonNegative(Idx, SQ.getWithInstruction(&GEP));
3115+
})) {
3116+
GEP.setNoWrapFlags(GEP.getNoWrapFlags() | GEPNoWrapFlags::noUnsignedWrap());
3117+
return &GEP;
3118+
}
3119+
3120+
// These rewrites is trying to preserve inbounds/nuw attributes. So we want to
3121+
// do this after having tried to derive "nuw" above.
30893122
if (GEP.getNumIndices() == 1) {
3090-
auto CanPreserveNoWrapFlags = [&](bool AddIsNSW, bool AddIsNUW, Value *Idx1,
3091-
Value *Idx2) {
3092-
// Preserve "inbounds nuw" if the original gep is "inbounds nuw",
3093-
// and the add is "nuw".
3094-
if (GEP.isInBounds() && GEP.hasNoUnsignedWrap() && AddIsNUW)
3095-
return GEPNoWrapFlags::inBounds() | GEPNoWrapFlags::noUnsignedWrap();
3096-
// Preserve "inbounds" if the original gep is "inbounds", the add
3097-
// is "nsw", and the add operands are non-negative.
3098-
SimplifyQuery Q = SQ.getWithInstruction(&GEP);
3099-
if (GEP.isInBounds() && AddIsNSW && isKnownNonNegative(Idx1, Q) &&
3100-
isKnownNonNegative(Idx2, Q))
3101-
return GEPNoWrapFlags::inBounds();
3102-
// Preserve "nuw" if the original gep is "nuw", and the add is "nuw".
3103-
if (GEP.hasNoUnsignedWrap() && AddIsNUW)
3104-
return GEPNoWrapFlags::noUnsignedWrap();
3105-
return GEPNoWrapFlags::none();
3123+
auto GetPreservedNoWrapFlags = [&](bool AddIsNUW, Value *Idx1, Value *Idx2) {
3124+
// Preserve "inbounds nuw" if the original gep is "inbounds nuw", and the
3125+
// add is "nuw". Preserve "nuw" if the original gep is "nuw", and the add
3126+
// is "nuw".
3127+
GEPNoWrapFlags Flags = GEPNoWrapFlags::none();
3128+
if (GEP.hasNoUnsignedWrap() && AddIsNUW) {
3129+
Flags |= GEPNoWrapFlags::noUnsignedWrap();
3130+
if (GEP.isInBounds())
3131+
Flags |= GEPNoWrapFlags::inBounds();
3132+
}
3133+
return Flags;
31063134
};
31073135

31083136
// Try to replace ADD + GEP with GEP + GEP.
@@ -3114,9 +3142,8 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
31143142
// as:
31153143
// %newptr = getelementptr i32, ptr %ptr, i64 %idx1
31163144
// %newgep = getelementptr i32, ptr %newptr, i64 %idx2
3117-
bool NSW = match(GEP.getOperand(1), m_NSWAddLike(m_Value(), m_Value()));
31183145
bool NUW = match(GEP.getOperand(1), m_NUWAddLike(m_Value(), m_Value()));
3119-
GEPNoWrapFlags NWFlags = CanPreserveNoWrapFlags(NSW, NUW, Idx1, Idx2);
3146+
GEPNoWrapFlags NWFlags = GetPreservedNoWrapFlags(NUW, Idx1, Idx2);
31203147
auto *NewPtr =
31213148
Builder.CreateGEP(GEP.getSourceElementType(), GEP.getPointerOperand(),
31223149
Idx1, "", NWFlags);
@@ -3133,8 +3160,9 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
31333160
// as:
31343161
// %newptr = getelementptr i32, ptr %ptr, i32 %idx1
31353162
// %newgep = getelementptr i32, ptr %newptr, i32 idx2
3136-
GEPNoWrapFlags NWFlags = CanPreserveNoWrapFlags(
3137-
/*IsNSW=*/true, /*IsNUW=*/false, Idx1, C);
3163+
bool NUW = match(GEP.getOperand(1), m_NNegZExt(m_NUWAddLike(m_Value(),
3164+
m_Value())));
3165+
GEPNoWrapFlags NWFlags = GetPreservedNoWrapFlags(NUW, Idx1, C);
31383166
auto *NewPtr = Builder.CreateGEP(
31393167
GEP.getSourceElementType(), GEP.getPointerOperand(),
31403168
Builder.CreateSExt(Idx1, GEP.getOperand(1)->getType()), "", NWFlags);
@@ -3146,37 +3174,6 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
31463174
}
31473175
}
31483176

3149-
if (!GEP.isInBounds()) {
3150-
unsigned IdxWidth =
3151-
DL.getIndexSizeInBits(PtrOp->getType()->getPointerAddressSpace());
3152-
APInt BasePtrOffset(IdxWidth, 0);
3153-
Value *UnderlyingPtrOp =
3154-
PtrOp->stripAndAccumulateInBoundsConstantOffsets(DL,
3155-
BasePtrOffset);
3156-
bool CanBeNull, CanBeFreed;
3157-
uint64_t DerefBytes = UnderlyingPtrOp->getPointerDereferenceableBytes(
3158-
DL, CanBeNull, CanBeFreed);
3159-
if (!CanBeNull && !CanBeFreed && DerefBytes != 0) {
3160-
if (GEP.accumulateConstantOffset(DL, BasePtrOffset) &&
3161-
BasePtrOffset.isNonNegative()) {
3162-
APInt AllocSize(IdxWidth, DerefBytes);
3163-
if (BasePtrOffset.ule(AllocSize)) {
3164-
return GetElementPtrInst::CreateInBounds(
3165-
GEP.getSourceElementType(), PtrOp, Indices, GEP.getName());
3166-
}
3167-
}
3168-
}
3169-
}
3170-
3171-
// nusw + nneg -> nuw
3172-
if (GEP.hasNoUnsignedSignedWrap() && !GEP.hasNoUnsignedWrap() &&
3173-
all_of(GEP.indices(), [&](Value *Idx) {
3174-
return isKnownNonNegative(Idx, SQ.getWithInstruction(&GEP));
3175-
})) {
3176-
GEP.setNoWrapFlags(GEP.getNoWrapFlags() | GEPNoWrapFlags::noUnsignedWrap());
3177-
return &GEP;
3178-
}
3179-
31803177
if (Instruction *R = foldSelectGEP(GEP, Builder))
31813178
return R;
31823179

0 commit comments

Comments
 (0)