@@ -3087,12 +3087,22 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
3087
3087
return nullptr ;
3088
3088
3089
3089
if (GEP.getNumIndices () == 1 ) {
3090
- // We can only preserve inbounds if the original gep is inbounds, the add
3091
- // is nsw, and the add operands are non-negative.
3092
- auto CanPreserveInBounds = [&](bool AddIsNSW, Value *Idx1, Value *Idx2) {
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.
3093
3098
SimplifyQuery Q = SQ.getWithInstruction (&GEP);
3094
- return GEP.isInBounds () && AddIsNSW && isKnownNonNegative (Idx1, Q) &&
3095
- isKnownNonNegative (Idx2, Q);
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 ();
3096
3106
};
3097
3107
3098
3108
// Try to replace ADD + GEP with GEP + GEP.
@@ -3104,15 +3114,15 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
3104
3114
// as:
3105
3115
// %newptr = getelementptr i32, ptr %ptr, i64 %idx1
3106
3116
// %newgep = getelementptr i32, ptr %newptr, i64 %idx2
3107
- bool IsInBounds = CanPreserveInBounds (
3108
- cast<OverflowingBinaryOperator> (GEP.getOperand (1 ))-> hasNoSignedWrap (),
3109
- Idx1, Idx2);
3117
+ bool NSW = match (GEP. getOperand ( 1 ), m_NSWAddLike ( m_Value (), m_Value ()));
3118
+ bool NUW = match (GEP.getOperand (1 ), m_NUWAddLike ( m_Value (), m_Value ()));
3119
+ GEPNoWrapFlags NWFlags = CanPreserveNoWrapFlags (NSW, NUW, Idx1, Idx2);
3110
3120
auto *NewPtr =
3111
3121
Builder.CreateGEP (GEP.getSourceElementType (), GEP.getPointerOperand (),
3112
- Idx1, " " , IsInBounds );
3113
- return replaceInstUsesWith (
3114
- GEP, Builder.CreateGEP (GEP.getSourceElementType (), NewPtr, Idx2, " " ,
3115
- IsInBounds ));
3122
+ Idx1, " " , NWFlags );
3123
+ return replaceInstUsesWith (GEP,
3124
+ Builder.CreateGEP (GEP.getSourceElementType (),
3125
+ NewPtr, Idx2, " " , NWFlags ));
3116
3126
}
3117
3127
ConstantInt *C;
3118
3128
if (match (GEP.getOperand (1 ), m_OneUse (m_SExtLike (m_OneUse (m_NSWAdd (
@@ -3123,17 +3133,16 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
3123
3133
// as:
3124
3134
// %newptr = getelementptr i32, ptr %ptr, i32 %idx1
3125
3135
// %newgep = getelementptr i32, ptr %newptr, i32 idx2
3126
- bool IsInBounds = CanPreserveInBounds (
3127
- /* IsNSW=*/ true , Idx1, C);
3136
+ GEPNoWrapFlags NWFlags = CanPreserveNoWrapFlags (
3137
+ /* IsNSW=*/ true , /* IsNUW= */ false , Idx1, C);
3128
3138
auto *NewPtr = Builder.CreateGEP (
3129
3139
GEP.getSourceElementType (), GEP.getPointerOperand (),
3130
- Builder.CreateSExt (Idx1, GEP.getOperand (1 )->getType ()), " " ,
3131
- IsInBounds);
3140
+ Builder.CreateSExt (Idx1, GEP.getOperand (1 )->getType ()), " " , NWFlags);
3132
3141
return replaceInstUsesWith (
3133
3142
GEP,
3134
3143
Builder.CreateGEP (GEP.getSourceElementType (), NewPtr,
3135
3144
Builder.CreateSExt (C, GEP.getOperand (1 )->getType ()),
3136
- " " , IsInBounds ));
3145
+ " " , NWFlags ));
3137
3146
}
3138
3147
}
3139
3148
0 commit comments