Skip to content

Long vector tests fail on x86 for 64-bit left/right shift operations #8178

@alsepkow

Description

@alsepkow

Issue description assisted by gh copilot.

Description

The x86 build of long vector tests fails for 64-bit left shift and right shift operations (LeftShift_int64_t, LeftShift_uint64_t, RightShift_int64_t, RightShift_uint64_t).

Root Cause

The BitShiftRhs test input sets include shift amounts equal to the bit width of the type:

  • int32_t/uint32_t: includes 32
  • int64_t/uint64_t: includes 64

This causes two problems:

  1. C++ undefined behavior: Per the C++ standard (expr.shift), shifting by an amount greater than or equal to the bit width is undefined behavior.

  2. Platform-dependent results: MSVC x86 64-bit shift implementation returns 0 for value << 64, while HLSL/DXIL (and GPU hardware) masks the shift amount to the low 6 bits, computing value << (64 & 63) = value << 0 = value.

Expected HLSL Behavior

DXBC (and by extension DXIL) explicitly masks shift amounts:

  • 32-bit shifts: mask with 0x1F (5 bits)
  • 64-bit shifts: mask with 0x3F (6 bits)

Reference: DxbcConverter.cpp line 5570

Why results vary by platform

Since shifting by >= bit width is undefined behavior in C++, results depend on compiler and platform:

  • x86 (32-bit build): MSVC generates a call to a helper routine for 64-bit shifts. That helper explicitly checks for shifts >= 64 and returns 0, which does not match GPU behavior.

  • x64 (64-bit build): Native shl/shr instructions use only the low 6 bits of the shift count. So shl rax, 64 executes as shl rax, 0 (since 64 & 63 = 0), returning the original value—which happens to match HLSL's defined behavior.

Either platform may pass or fail depending on compiler or future compiler changes. The observed failure was on x86, but this is ultimately undefined behavior and should not be relied upon.

Proposed Fix

Change the BitShiftRhs input sets to not include shift amounts >= bit width:

  • int32_t/uint32_t: 30, 31, 3229, 30, 31
  • int64_t/uint64_t: 62, 63, 6461, 62, 63

This matches the existing 16-bit pattern which correctly ends at 15.

Affected Files

  • tools/clang/unittests/HLSLExec/LongVectorTestData.h - BitShiftRhs input sets

Affected Tests

  • LeftShift_int64_t
  • RightShift_int64_t
  • LeftShift_uint64_t
  • RightShift_uint64_t

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug, regression, crashneeds-triageAwaiting triage

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions