@@ -162,6 +162,7 @@ bool VPRecipeBase::mayHaveSideEffects() const {
162162 case VPDerivedIVSC:
163163 case VPPredInstPHISC:
164164 case VPScalarCastSC:
165+ case VPReverseVectorPointerSC:
165166 return false ;
166167 case VPInstructionSC:
167168 return mayWriteToMemory ();
@@ -1971,38 +1972,63 @@ void VPWidenGEPRecipe::print(raw_ostream &O, const Twine &Indent,
19711972}
19721973#endif
19731974
1974- void VPVectorPointerRecipe ::execute (VPTransformState &State) {
1975- auto &Builder = State.Builder ;
1976- State.setDebugLocFrom (getDebugLoc ());
1977- unsigned CurrentPart = getUnrollPart (*this );
1975+ static Type *getGEPIndexTy (bool IsScalable, bool IsReverse,
1976+ unsigned CurrentPart, IRBuilderBase &Builder) {
19781977 // Use i32 for the gep index type when the value is constant,
19791978 // or query DataLayout for a more suitable index type otherwise.
19801979 const DataLayout &DL = Builder.GetInsertBlock ()->getDataLayout ();
1981- Type *IndexTy = State.VF .isScalable () && (IsReverse || CurrentPart > 0 )
1982- ? DL.getIndexType (Builder.getPtrTy (0 ))
1983- : Builder.getInt32Ty ();
1980+ return IsScalable && (IsReverse || CurrentPart > 0 )
1981+ ? DL.getIndexType (Builder.getPtrTy (0 ))
1982+ : Builder.getInt32Ty ();
1983+ }
1984+
1985+ void VPReverseVectorPointerRecipe::execute (VPTransformState &State) {
1986+ auto &Builder = State.Builder ;
1987+ State.setDebugLocFrom (getDebugLoc ());
1988+ unsigned CurrentPart = getUnrollPart (*this );
1989+ Type *IndexTy = getGEPIndexTy (State.VF .isScalable (), /* IsReverse*/ true ,
1990+ CurrentPart, Builder);
1991+
1992+ // The wide store needs to start at the last vector element.
1993+ Value *RunTimeVF = State.get (getVFValue (), VPLane (0 ));
1994+ if (IndexTy != RunTimeVF->getType ())
1995+ RunTimeVF = Builder.CreateZExtOrTrunc (RunTimeVF, IndexTy);
1996+ // NumElt = -CurrentPart * RunTimeVF
1997+ Value *NumElt = Builder.CreateMul (
1998+ ConstantInt::get (IndexTy, -(int64_t )CurrentPart), RunTimeVF);
1999+ // LastLane = 1 - RunTimeVF
2000+ Value *LastLane = Builder.CreateSub (ConstantInt::get (IndexTy, 1 ), RunTimeVF);
19842001 Value *Ptr = State.get (getOperand (0 ), VPLane (0 ));
19852002 bool InBounds = isInBounds ();
2003+ Value *ResultPtr = Builder.CreateGEP (IndexedTy, Ptr, NumElt, " " , InBounds);
2004+ ResultPtr = Builder.CreateGEP (IndexedTy, ResultPtr, LastLane, " " , InBounds);
19862005
1987- Value *ResultPtr = nullptr ;
1988- if (IsReverse) {
1989- // If the address is consecutive but reversed, then the
1990- // wide store needs to start at the last vector element.
1991- // RunTimeVF = VScale * VF.getKnownMinValue()
1992- // For fixed-width VScale is 1, then RunTimeVF = VF.getKnownMinValue()
1993- Value *RunTimeVF = getRuntimeVF (Builder, IndexTy, State.VF );
1994- // NumElt = -CurrentPart * RunTimeVF
1995- Value *NumElt = Builder.CreateMul (
1996- ConstantInt::get (IndexTy, -(int64_t )CurrentPart), RunTimeVF);
1997- // LastLane = 1 - RunTimeVF
1998- Value *LastLane =
1999- Builder.CreateSub (ConstantInt::get (IndexTy, 1 ), RunTimeVF);
2000- ResultPtr = Builder.CreateGEP (IndexedTy, Ptr, NumElt, " " , InBounds);
2001- ResultPtr = Builder.CreateGEP (IndexedTy, ResultPtr, LastLane, " " , InBounds);
2002- } else {
2003- Value *Increment = createStepForVF (Builder, IndexTy, State.VF , CurrentPart);
2004- ResultPtr = Builder.CreateGEP (IndexedTy, Ptr, Increment, " " , InBounds);
2005- }
2006+ State.set (this , ResultPtr, /* IsScalar*/ true );
2007+ }
2008+
2009+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2010+ void VPReverseVectorPointerRecipe::print (raw_ostream &O, const Twine &Indent,
2011+ VPSlotTracker &SlotTracker) const {
2012+ O << Indent;
2013+ printAsOperand (O, SlotTracker);
2014+ O << " = reverse-vector-pointer " ;
2015+ if (isInBounds ())
2016+ O << " inbounds " ;
2017+ printOperands (O, SlotTracker);
2018+ }
2019+ #endif
2020+
2021+ void VPVectorPointerRecipe::execute (VPTransformState &State) {
2022+ auto &Builder = State.Builder ;
2023+ State.setDebugLocFrom (getDebugLoc ());
2024+ unsigned CurrentPart = getUnrollPart (*this );
2025+ Type *IndexTy = getGEPIndexTy (State.VF .isScalable (), /* IsReverse*/ false ,
2026+ CurrentPart, Builder);
2027+ Value *Ptr = State.get (getOperand (0 ), VPLane (0 ));
2028+ bool InBounds = isInBounds ();
2029+
2030+ Value *Increment = createStepForVF (Builder, IndexTy, State.VF , CurrentPart);
2031+ Value *ResultPtr = Builder.CreateGEP (IndexedTy, Ptr, Increment, " " , InBounds);
20062032
20072033 State.set (this , ResultPtr, /* IsScalar*/ true );
20082034}
@@ -2013,8 +2039,6 @@ void VPVectorPointerRecipe::print(raw_ostream &O, const Twine &Indent,
20132039 O << Indent;
20142040 printAsOperand (O, SlotTracker);
20152041 O << " = vector-pointer " ;
2016- if (IsReverse)
2017- O << " (reverse) " ;
20182042
20192043 printOperands (O, SlotTracker);
20202044}
0 commit comments