@@ -162,6 +162,7 @@ bool VPRecipeBase::mayHaveSideEffects() const {
162
162
case VPDerivedIVSC:
163
163
case VPPredInstPHISC:
164
164
case VPScalarCastSC:
165
+ case VPReverseVectorPointerSC:
165
166
return false ;
166
167
case VPInstructionSC:
167
168
return mayWriteToMemory ();
@@ -1971,38 +1972,63 @@ void VPWidenGEPRecipe::print(raw_ostream &O, const Twine &Indent,
1971
1972
}
1972
1973
#endif
1973
1974
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) {
1978
1977
// Use i32 for the gep index type when the value is constant,
1979
1978
// or query DataLayout for a more suitable index type otherwise.
1980
1979
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);
1984
2001
Value *Ptr = State.get (getOperand (0 ), VPLane (0 ));
1985
2002
bool InBounds = isInBounds ();
2003
+ Value *ResultPtr = Builder.CreateGEP (IndexedTy, Ptr, NumElt, " " , InBounds);
2004
+ ResultPtr = Builder.CreateGEP (IndexedTy, ResultPtr, LastLane, " " , InBounds);
1986
2005
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);
2006
2032
2007
2033
State.set (this , ResultPtr, /* IsScalar*/ true );
2008
2034
}
@@ -2013,8 +2039,6 @@ void VPVectorPointerRecipe::print(raw_ostream &O, const Twine &Indent,
2013
2039
O << Indent;
2014
2040
printAsOperand (O, SlotTracker);
2015
2041
O << " = vector-pointer " ;
2016
- if (IsReverse)
2017
- O << " (reverse) " ;
2018
2042
2019
2043
printOperands (O, SlotTracker);
2020
2044
}
0 commit comments