File tree Expand file tree Collapse file tree
tools/clang/unittests/HLSLExec Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -755,8 +755,17 @@ template <typename T> uint32_t FirstBitLow(T A) {
755755DEFAULT_OP_2 (OpType::And, (A & B));
756756DEFAULT_OP_2 (OpType::Or, (A | B));
757757DEFAULT_OP_2 (OpType::Xor, (A ^ B));
758- DEFAULT_OP_2 (OpType::LeftShift, (A << B));
759- DEFAULT_OP_2 (OpType::RightShift, (A >> B));
758+
759+ // HLSL/DXIL masks shift amounts to the low bits (4 bits for 16-bit, 5 bits for
760+ // 32-bit, 6 bits for 64-bit). We must do the same in C++ to avoid undefined
761+ // behavior when shift amount >= bit width, and to match GPU results.
762+ template <typename T> T MaskShiftAmount (T ShiftAmount) {
763+ constexpr T ShiftMask = static_cast <T>(sizeof (T) * 8 - 1 );
764+ return ShiftAmount & ShiftMask;
765+ }
766+
767+ DEFAULT_OP_2 (OpType::LeftShift, (A << MaskShiftAmount(B)));
768+ DEFAULT_OP_2 (OpType::RightShift, (A >> MaskShiftAmount (B)));
760769DEFAULT_OP_1 (OpType::Saturate, (Saturate(A)));
761770DEFAULT_OP_1 (OpType::ReverseBits, (ReverseBits(A)));
762771
You can’t perform that action at this time.
0 commit comments