@@ -2713,7 +2713,7 @@ inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
2713
2713
template <class LT , class RT , ShiftDir Dir>
2714
2714
inline bool DoShift (InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS,
2715
2715
LT *Result) {
2716
-
2716
+ static_assert (!needsAlloc<LT>());
2717
2717
const unsigned Bits = LHS.bitWidth ();
2718
2718
2719
2719
// 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,
2770
2770
LT::AsUnsigned::shiftLeft (LT::AsUnsigned::from (LHS),
2771
2771
LT::AsUnsigned::from (RHS, Bits), Bits, &R);
2772
2772
}
2773
- } else {
2773
+ S.Stk .push <LT>(LT::from (R));
2774
+ return true ;
2775
+ }
2776
+
2774
2777
// Right shift.
2775
2778
if (Compare (RHS, RT::from (MaxShiftAmount, RHS.bitWidth ())) ==
2776
2779
ComparisonCategoryResult::Greater) {
@@ -2779,51 +2782,52 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS,
2779
2782
// Do the shift on potentially signed LT, then convert to unsigned type.
2780
2783
LT A;
2781
2784
LT::shiftRight (LHS, LT::from (RHS, Bits), Bits, &A);
2782
- // LT::shiftRight(LHS, LT(RHSTemp), Bits, &A);
2783
2785
R = LT::AsUnsigned::from (A);
2784
2786
}
2785
- }
2786
2787
2787
2788
S.Stk .push <LT>(LT::from (R));
2788
2789
return true ;
2789
2790
}
2790
2791
2791
2792
// / A version of DoShift that works on IntegralAP.
2792
2793
template <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 ();
2798
2797
2799
2798
// OpenCL 6.3j: shift values are effectively % word size of LHS.
2800
2799
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 ());
2804
2803
2805
2804
if (RHS.isNegative ()) {
2806
2805
// During constant-folding, a negative shift is an opposite shift. Such a
2807
2806
// shift is not a constant expression.
2808
2807
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();
2810
2809
if (!S.noteUndefinedBehavior ())
2811
2810
return false ;
2812
- RHS = -RHS;
2813
2811
return DoShiftAP<LT, RT,
2814
2812
Dir == ShiftDir::Left ? ShiftDir::Right : ShiftDir::Left>(
2815
- S, OpPC, LHS, RHS, Result);
2813
+ S, OpPC, LHS, - RHS, Result);
2816
2814
}
2817
2815
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))
2819
2818
return false ;
2820
2819
2820
+ unsigned SA = (unsigned )RHS.getLimitedValue (Bits - 1 );
2821
2821
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);
2824
2826
} 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);
2827
2831
}
2828
2832
2829
2833
S.Stk .push <LT>(*Result);
@@ -2837,9 +2841,12 @@ inline bool Shr(InterpState &S, CodePtr OpPC) {
2837
2841
auto RHS = S.Stk .pop <RT>();
2838
2842
auto LHS = S.Stk .pop <LT>();
2839
2843
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);
2843
2850
} else {
2844
2851
LT Result;
2845
2852
return DoShift<LT, RT, ShiftDir::Right>(S, OpPC, LHS, RHS, &Result);
@@ -2852,9 +2859,13 @@ inline bool Shl(InterpState &S, CodePtr OpPC) {
2852
2859
using RT = typename PrimConv<NameR>::T;
2853
2860
auto RHS = S.Stk .pop <RT>();
2854
2861
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);
2858
2869
} else {
2859
2870
LT Result;
2860
2871
return DoShift<LT, RT, ShiftDir::Left>(S, OpPC, LHS, RHS, &Result);
0 commit comments