@@ -2744,125 +2744,53 @@ Instruction *InstCombinerImpl::visitGEPOfGEP(GetElementPtrInst &GEP,
27442744 if (auto *I = combineConstantOffsets (GEP, *this ))
27452745 return I;
27462746
2747- // For constant GEPs, use a more general offset-based folding approach.
2748- Type *PtrTy = Src->getType ()->getScalarType ();
2749- if (GEP.hasAllConstantIndices () &&
2750- (Src->hasOneUse () || Src->hasAllConstantIndices ())) {
2751- // Split Src into a variable part and a constant suffix.
2752- gep_type_iterator GTI = gep_type_begin (*Src);
2753- Type *BaseType = GTI.getIndexedType ();
2754- bool IsFirstType = true ;
2755- unsigned NumVarIndices = 0 ;
2756- for (auto Pair : enumerate(Src->indices ())) {
2757- if (!isa<ConstantInt>(Pair.value ())) {
2758- BaseType = GTI.getIndexedType ();
2759- IsFirstType = false ;
2760- NumVarIndices = Pair.index () + 1 ;
2761- }
2762- ++GTI;
2763- }
2764-
2765- // Determine the offset for the constant suffix of Src.
2766- APInt Offset (DL.getIndexTypeSizeInBits (PtrTy), 0 );
2767- if (NumVarIndices != Src->getNumIndices ()) {
2768- // FIXME: getIndexedOffsetInType() does not handled scalable vectors.
2769- if (BaseType->isScalableTy ())
2770- return nullptr ;
2771-
2772- SmallVector<Value *> ConstantIndices;
2773- if (!IsFirstType)
2774- ConstantIndices.push_back (
2775- Constant::getNullValue (Type::getInt32Ty (GEP.getContext ())));
2776- append_range (ConstantIndices, drop_begin (Src->indices (), NumVarIndices));
2777- Offset += DL.getIndexedOffsetInType (BaseType, ConstantIndices);
2778- }
2779-
2780- // Add the offset for GEP (which is fully constant).
2781- if (!GEP.accumulateConstantOffset (DL, Offset))
2782- return nullptr ;
2783-
2784- // Convert the total offset back into indices.
2785- SmallVector<APInt> ConstIndices =
2786- DL.getGEPIndicesForOffset (BaseType, Offset);
2787- if (!Offset.isZero () || (!IsFirstType && !ConstIndices[0 ].isZero ()))
2788- return nullptr ;
2789-
2790- GEPNoWrapFlags NW = getMergedGEPNoWrapFlags (*Src, *cast<GEPOperator>(&GEP));
2791- SmallVector<Value *> Indices (
2792- drop_end (Src->indices (), Src->getNumIndices () - NumVarIndices));
2793- for (const APInt &Idx : drop_begin (ConstIndices, !IsFirstType)) {
2794- Indices.push_back (ConstantInt::get (GEP.getContext (), Idx));
2795- // Even if the total offset is inbounds, we may end up representing it
2796- // by first performing a larger negative offset, and then a smaller
2797- // positive one. The large negative offset might go out of bounds. Only
2798- // preserve inbounds if all signs are the same.
2799- if (Idx.isNonNegative () != ConstIndices[0 ].isNonNegative ())
2800- NW = NW.withoutNoUnsignedSignedWrap ();
2801- if (!Idx.isNonNegative ())
2802- NW = NW.withoutNoUnsignedWrap ();
2803- }
2804-
2805- return replaceInstUsesWith (
2806- GEP, Builder.CreateGEP (Src->getSourceElementType (), Src->getOperand (0 ),
2807- Indices, " " , NW));
2808- }
2809-
28102747 if (Src->getResultElementType () != GEP.getSourceElementType ())
28112748 return nullptr ;
28122749
2813- SmallVector<Value*, 8 > Indices;
2814-
28152750 // Find out whether the last index in the source GEP is a sequential idx.
28162751 bool EndsWithSequential = false ;
28172752 for (gep_type_iterator I = gep_type_begin (*Src), E = gep_type_end (*Src);
28182753 I != E; ++I)
28192754 EndsWithSequential = I.isSequential ();
2755+ if (!EndsWithSequential)
2756+ return nullptr ;
28202757
2821- // Can we combine the two pointer arithmetics offsets?
2822- if (EndsWithSequential) {
2823- // Replace: gep (gep %P, long B), long A, ...
2824- // With: T = long A+B; gep %P, T, ...
2825- Value *SO1 = Src->getOperand (Src->getNumOperands ()-1 );
2826- Value *GO1 = GEP.getOperand (1 );
2827-
2828- // If they aren't the same type, then the input hasn't been processed
2829- // by the loop above yet (which canonicalizes sequential index types to
2830- // intptr_t). Just avoid transforming this until the input has been
2831- // normalized.
2832- if (SO1->getType () != GO1->getType ())
2833- return nullptr ;
2758+ // Replace: gep (gep %P, long B), long A, ...
2759+ // With: T = long A+B; gep %P, T, ...
2760+ Value *SO1 = Src->getOperand (Src->getNumOperands () - 1 );
2761+ Value *GO1 = GEP.getOperand (1 );
28342762
2835- Value *Sum =
2836- simplifyAddInst (GO1, SO1, false , false , SQ. getWithInstruction (&GEP));
2837- // Only do the combine when we are sure the cost after the
2838- // merge is never more than that before the merge .
2839- if (Sum == nullptr )
2840- return nullptr ;
2763+ // If they aren't the same type, then the input hasn't been processed
2764+ // by the loop above yet (which canonicalizes sequential index types to
2765+ // intptr_t). Just avoid transforming this until the input has been
2766+ // normalized .
2767+ if (SO1-> getType () != GO1-> getType () )
2768+ return nullptr ;
28412769
2842- Indices.append (Src->op_begin ()+1 , Src->op_end ()-1 );
2843- Indices.push_back (Sum);
2844- Indices.append (GEP.op_begin ()+2 , GEP.op_end ());
2845- } else if (isa<Constant>(*GEP.idx_begin ()) &&
2846- cast<Constant>(*GEP.idx_begin ())->isNullValue () &&
2847- Src->getNumOperands () != 1 ) {
2848- // Otherwise we can do the fold if the first index of the GEP is a zero
2849- Indices.append (Src->op_begin ()+1 , Src->op_end ());
2850- Indices.append (GEP.idx_begin ()+1 , GEP.idx_end ());
2851- }
2852-
2853- // Don't create GEPs with more than one variable index.
2854- unsigned NumVarIndices =
2855- count_if (Indices, [](Value *Idx) { return !isa<Constant>(Idx); });
2856- if (NumVarIndices > 1 )
2770+ Value *Sum =
2771+ simplifyAddInst (GO1, SO1, false , false , SQ.getWithInstruction (&GEP));
2772+ // Only do the combine when we are sure the cost after the
2773+ // merge is never more than that before the merge.
2774+ if (Sum == nullptr )
28572775 return nullptr ;
28582776
2859- if (!Indices.empty ())
2860- return replaceInstUsesWith (
2861- GEP, Builder.CreateGEP (
2862- Src->getSourceElementType (), Src->getOperand (0 ), Indices, " " ,
2863- getMergedGEPNoWrapFlags (*Src, *cast<GEPOperator>(&GEP))));
2777+ SmallVector<Value *, 8 > Indices;
2778+ Indices.append (Src->op_begin () + 1 , Src->op_end () - 1 );
2779+ Indices.push_back (Sum);
2780+ Indices.append (GEP.op_begin () + 2 , GEP.op_end ());
28642781
2865- return nullptr ;
2782+ // Don't create GEPs with more than one non-zero index.
2783+ unsigned NumNonZeroIndices = count_if (Indices, [](Value *Idx) {
2784+ auto *C = dyn_cast<Constant>(Idx);
2785+ return !C || !C->isNullValue ();
2786+ });
2787+ if (NumNonZeroIndices > 1 )
2788+ return nullptr ;
2789+
2790+ return replaceInstUsesWith (
2791+ GEP, Builder.CreateGEP (
2792+ Src->getSourceElementType (), Src->getOperand (0 ), Indices, " " ,
2793+ getMergedGEPNoWrapFlags (*Src, *cast<GEPOperator>(&GEP))));
28662794}
28672795
28682796Value *InstCombiner::getFreelyInvertedImpl (Value *V, bool WillInvertAllUses,
@@ -3334,17 +3262,18 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
33343262 return replaceInstUsesWith (GEP, Res);
33353263 }
33363264
3337- bool SeenVarIndex = false ;
3265+ bool SeenNonZeroIndex = false ;
33383266 for (auto [IdxNum, Idx] : enumerate(Indices)) {
3339- if (isa<Constant>(Idx))
3267+ auto *C = dyn_cast<Constant>(Idx);
3268+ if (C && C->isNullValue ())
33403269 continue ;
33413270
3342- if (!SeenVarIndex ) {
3343- SeenVarIndex = true ;
3271+ if (!SeenNonZeroIndex ) {
3272+ SeenNonZeroIndex = true ;
33443273 continue ;
33453274 }
33463275
3347- // GEP has multiple variable indices: Split it.
3276+ // GEP has multiple non-zero indices: Split it.
33483277 ArrayRef<Value *> FrontIndices = ArrayRef (Indices).take_front (IdxNum);
33493278 Value *FrontGEP =
33503279 Builder.CreateGEP (GEPEltType, PtrOp, FrontIndices,
0 commit comments