@@ -2713,7 +2713,7 @@ inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
27132713template <class LT , class RT , ShiftDir Dir>
27142714inline bool DoShift (InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS,
27152715 LT *Result) {
2716-
2716+ static_assert (!needsAlloc<LT>());
27172717 const unsigned Bits = LHS.bitWidth ();
27182718
27192719 // OpenCL 6.3j: shift values are effectively % word size of LHS.
@@ -2770,7 +2770,10 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS,
27702770 LT::AsUnsigned::shiftLeft (LT::AsUnsigned::from (LHS),
27712771 LT::AsUnsigned::from (RHS, Bits), Bits, &R);
27722772 }
2773- } else {
2773+ S.Stk .push <LT>(LT::from (R));
2774+ return true ;
2775+ }
2776+
27742777 // Right shift.
27752778 if (Compare (RHS, RT::from (MaxShiftAmount, RHS.bitWidth ())) ==
27762779 ComparisonCategoryResult::Greater) {
@@ -2779,51 +2782,52 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS,
27792782 // Do the shift on potentially signed LT, then convert to unsigned type.
27802783 LT A;
27812784 LT::shiftRight (LHS, LT::from (RHS, Bits), Bits, &A);
2782- // LT::shiftRight(LHS, LT(RHSTemp), Bits, &A);
27832785 R = LT::AsUnsigned::from (A);
27842786 }
2785- }
27862787
27872788 S.Stk .push <LT>(LT::from (R));
27882789 return true ;
27892790}
27902791
27912792// / A version of DoShift that works on IntegralAP.
27922793template <class LT , class RT , ShiftDir Dir>
2793- inline bool DoShiftAP (InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS,
2794- LT *Result) {
2795- const unsigned Bits = LHS.bitWidth ();
2796- const APSInt &LHSAP = LHS.toAPSInt ();
2797- APSInt RHSAP = RHS.toAPSInt ();
2794+ inline bool DoShiftAP (InterpState &S, CodePtr OpPC, const APSInt &LHS,
2795+ APSInt RHS, LT *Result) {
2796+ const unsigned Bits = LHS.getBitWidth ();
27982797
27992798 // OpenCL 6.3j: shift values are effectively % word size of LHS.
28002799 if (S.getLangOpts ().OpenCL )
2801- RHSAP &= APSInt ( llvm::APInt (RHSAP. getBitWidth (),
2802- static_cast <uint64_t >(LHSAP. getBitWidth () - 1 )),
2803- RHSAP .isUnsigned ());
2800+ RHS &=
2801+ APSInt ( llvm::APInt (RHS. getBitWidth (), static_cast <uint64_t >(Bits - 1 )),
2802+ RHS .isUnsigned ());
28042803
28052804 if (RHS.isNegative ()) {
28062805 // During constant-folding, a negative shift is an opposite shift. Such a
28072806 // shift is not a constant expression.
28082807 const SourceInfo &Loc = S.Current ->getSource (OpPC);
2809- S.CCEDiag (Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt ();
2808+ S.CCEDiag (Loc, diag::note_constexpr_negative_shift) << RHS; // .toAPSInt();
28102809 if (!S.noteUndefinedBehavior ())
28112810 return false ;
2812- RHS = -RHS;
28132811 return DoShiftAP<LT, RT,
28142812 Dir == ShiftDir::Left ? ShiftDir::Right : ShiftDir::Left>(
2815- S, OpPC, LHS, RHS, Result);
2813+ S, OpPC, LHS, - RHS, Result);
28162814 }
28172815
2818- if (!CheckShift<Dir>(S, OpPC, LHS, RHS, Bits))
2816+ if (!CheckShift<Dir>(S, OpPC, static_cast <LT>(LHS), static_cast <RT>(RHS),
2817+ Bits))
28192818 return false ;
28202819
2820+ unsigned SA = (unsigned )RHS.getLimitedValue (Bits - 1 );
28212821 if constexpr (Dir == ShiftDir::Left) {
2822- unsigned SA = (unsigned )RHSAP.getLimitedValue (LHS.bitWidth () - 1 );
2823- Result->copy (LHSAP << SA);
2822+ if constexpr (needsAlloc<LT>())
2823+ Result->copy (LHS << SA);
2824+ else
2825+ *Result = LT (LHS << SA);
28242826 } else {
2825- unsigned SA = (unsigned )RHSAP.getLimitedValue (LHS.bitWidth () - 1 );
2826- Result->copy (LHSAP >> SA);
2827+ if constexpr (needsAlloc<LT>())
2828+ Result->copy (LHS >> SA);
2829+ else
2830+ *Result = LT (LHS >> SA);
28272831 }
28282832
28292833 S.Stk .push <LT>(*Result);
@@ -2837,9 +2841,12 @@ inline bool Shr(InterpState &S, CodePtr OpPC) {
28372841 auto RHS = S.Stk .pop <RT>();
28382842 auto LHS = S.Stk .pop <LT>();
28392843
2840- if constexpr (needsAlloc<LT>()) {
2841- LT Result = S.allocAP <LT>(LHS.bitWidth ());
2842- return DoShiftAP<LT, RT, ShiftDir::Right>(S, OpPC, LHS, RHS, &Result);
2844+ if constexpr (needsAlloc<LT>() || needsAlloc<RT>()) {
2845+ LT Result;
2846+ if constexpr (needsAlloc<LT>())
2847+ Result = S.allocAP <LT>(LHS.bitWidth ());
2848+ return DoShiftAP<LT, RT, ShiftDir::Right>(S, OpPC, LHS.toAPSInt (),
2849+ RHS.toAPSInt (), &Result);
28432850 } else {
28442851 LT Result;
28452852 return DoShift<LT, RT, ShiftDir::Right>(S, OpPC, LHS, RHS, &Result);
@@ -2852,9 +2859,13 @@ inline bool Shl(InterpState &S, CodePtr OpPC) {
28522859 using RT = typename PrimConv<NameR>::T;
28532860 auto RHS = S.Stk .pop <RT>();
28542861 auto LHS = S.Stk .pop <LT>();
2855- if constexpr (needsAlloc<LT>()) {
2856- LT Result = S.allocAP <LT>(LHS.bitWidth ());
2857- return DoShiftAP<LT, RT, ShiftDir::Left>(S, OpPC, LHS, RHS, &Result);
2862+
2863+ if constexpr (needsAlloc<LT>() || needsAlloc<RT>()) {
2864+ LT Result;
2865+ if constexpr (needsAlloc<LT>())
2866+ Result = S.allocAP <LT>(LHS.bitWidth ());
2867+ return DoShiftAP<LT, RT, ShiftDir::Left>(S, OpPC, LHS.toAPSInt (),
2868+ RHS.toAPSInt (), &Result);
28582869 } else {
28592870 LT Result;
28602871 return DoShift<LT, RT, ShiftDir::Left>(S, OpPC, LHS, RHS, &Result);
0 commit comments