@@ -2948,6 +2948,14 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
2948
2948
return nullptr ;
2949
2949
2950
2950
if (GEP.getNumIndices () == 1 ) {
2951
+ // We can only preserve inbounds if the original gep is inbounds, the add
2952
+ // is nsw, and the add operands are non-negative.
2953
+ auto CanPreserveInBounds = [&](bool AddIsNSW, Value *Idx1, Value *Idx2) {
2954
+ SimplifyQuery Q = SQ.getWithInstruction (&GEP);
2955
+ return GEP.isInBounds () && AddIsNSW && isKnownNonNegative (Idx1, Q) &&
2956
+ isKnownNonNegative (Idx2, Q);
2957
+ };
2958
+
2951
2959
// Try to replace ADD + GEP with GEP + GEP.
2952
2960
Value *Idx1, *Idx2;
2953
2961
if (match (GEP.getOperand (1 ),
@@ -2957,10 +2965,15 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
2957
2965
// as:
2958
2966
// %newptr = getelementptr i32, ptr %ptr, i64 %idx1
2959
2967
// %newgep = getelementptr i32, ptr %newptr, i64 %idx2
2960
- auto *NewPtr = Builder.CreateGEP (GEP.getResultElementType (),
2961
- GEP.getPointerOperand (), Idx1);
2962
- return GetElementPtrInst::Create (GEP.getResultElementType (), NewPtr,
2963
- Idx2);
2968
+ bool IsInBounds = CanPreserveInBounds (
2969
+ cast<OverflowingBinaryOperator>(GEP.getOperand (1 ))->hasNoSignedWrap (),
2970
+ Idx1, Idx2);
2971
+ auto *NewPtr =
2972
+ Builder.CreateGEP (GEP.getResultElementType (), GEP.getPointerOperand (),
2973
+ Idx1, " " , IsInBounds);
2974
+ return replaceInstUsesWith (
2975
+ GEP, Builder.CreateGEP (GEP.getResultElementType (), NewPtr, Idx2, " " ,
2976
+ IsInBounds));
2964
2977
}
2965
2978
ConstantInt *C;
2966
2979
if (match (GEP.getOperand (1 ), m_OneUse (m_SExtLike (m_OneUse (m_NSWAdd (
@@ -2971,12 +2984,17 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
2971
2984
// as:
2972
2985
// %newptr = getelementptr i32, ptr %ptr, i32 %idx1
2973
2986
// %newgep = getelementptr i32, ptr %newptr, i32 idx2
2987
+ bool IsInBounds = CanPreserveInBounds (
2988
+ /* IsNSW=*/ true , Idx1, C);
2974
2989
auto *NewPtr = Builder.CreateGEP (
2975
2990
GEP.getResultElementType (), GEP.getPointerOperand (),
2976
- Builder.CreateSExt (Idx1, GEP.getOperand (1 )->getType ()));
2977
- return GetElementPtrInst::Create (
2978
- GEP.getResultElementType (), NewPtr,
2979
- Builder.CreateSExt (C, GEP.getOperand (1 )->getType ()));
2991
+ Builder.CreateSExt (Idx1, GEP.getOperand (1 )->getType ()), " " ,
2992
+ IsInBounds);
2993
+ return replaceInstUsesWith (
2994
+ GEP,
2995
+ Builder.CreateGEP (GEP.getResultElementType (), NewPtr,
2996
+ Builder.CreateSExt (C, GEP.getOperand (1 )->getType ()),
2997
+ " " , IsInBounds));
2980
2998
}
2981
2999
}
2982
3000
0 commit comments