@@ -2744,125 +2744,53 @@ Instruction *InstCombinerImpl::visitGEPOfGEP(GetElementPtrInst &GEP,
2744
2744
if (auto *I = combineConstantOffsets (GEP, *this ))
2745
2745
return I;
2746
2746
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
-
2810
2747
if (Src->getResultElementType () != GEP.getSourceElementType ())
2811
2748
return nullptr ;
2812
2749
2813
- SmallVector<Value*, 8 > Indices;
2814
-
2815
2750
// Find out whether the last index in the source GEP is a sequential idx.
2816
2751
bool EndsWithSequential = false ;
2817
2752
for (gep_type_iterator I = gep_type_begin (*Src), E = gep_type_end (*Src);
2818
2753
I != E; ++I)
2819
2754
EndsWithSequential = I.isSequential ();
2755
+ if (!EndsWithSequential)
2756
+ return nullptr ;
2820
2757
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 );
2834
2762
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 ;
2841
2769
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 )
2857
2775
return nullptr ;
2858
2776
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 ());
2864
2781
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))));
2866
2794
}
2867
2795
2868
2796
Value *InstCombiner::getFreelyInvertedImpl (Value *V, bool WillInvertAllUses,
@@ -3334,17 +3262,18 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
3334
3262
return replaceInstUsesWith (GEP, Res);
3335
3263
}
3336
3264
3337
- bool SeenVarIndex = false ;
3265
+ bool SeenNonZeroIndex = false ;
3338
3266
for (auto [IdxNum, Idx] : enumerate(Indices)) {
3339
- if (isa<Constant>(Idx))
3267
+ auto *C = dyn_cast<Constant>(Idx);
3268
+ if (C && C->isNullValue ())
3340
3269
continue ;
3341
3270
3342
- if (!SeenVarIndex ) {
3343
- SeenVarIndex = true ;
3271
+ if (!SeenNonZeroIndex ) {
3272
+ SeenNonZeroIndex = true ;
3344
3273
continue ;
3345
3274
}
3346
3275
3347
- // GEP has multiple variable indices: Split it.
3276
+ // GEP has multiple non-zero indices: Split it.
3348
3277
ArrayRef<Value *> FrontIndices = ArrayRef (Indices).take_front (IdxNum);
3349
3278
Value *FrontGEP =
3350
3279
Builder.CreateGEP (GEPEltType, PtrOp, FrontIndices,
0 commit comments