CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
140 lines
6.2 KiB
LLVM
140 lines
6.2 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 -O0 < %s | FileCheck %s
|
|
|
|
; Regression tests for scalar fshl/fshr with constant shift amounts that
|
|
; caused miscompilation via the scalar S_LSHR_B64 fast path:
|
|
;
|
|
; - fshl(scalar, const, 0): the FSHL->FSHR conversion computed ~0 = -1 as the
|
|
; inverted shift, which (being < 32 in a signed comparison) bypassed the
|
|
; S_AND_B32 masking and caused S_LSHR_B64 to shift by 63 instead of 0.
|
|
;
|
|
; - fshl(scalar, const, 1): same path computes -Z = -1 as the inverted shift;
|
|
; same buggy immediate pattern matched and skipped masking.
|
|
;
|
|
; - fshl(scalar, const, 16): same path computes -16 as the inverted shift;
|
|
; -16 also satisfies Imm < 32 signed and would bypass S_AND_B32 masking.
|
|
;
|
|
; - fshl(scalar, scalar, 8): same lowering applies when both inputs are uniform
|
|
; scalars; -8 would bypass S_AND_B32 masking.
|
|
;
|
|
; Correct behaviour:
|
|
; fshl(X, Y, 0) == X
|
|
; fshl(X, Y, 1) == (X << 1) | (Y >> 31)
|
|
; fshl(X, Y, 16) == (X << 16) | (Y >> 16)
|
|
; fshl(X, Y, 8) == (X << 8) | (Y >> 24)
|
|
|
|
; fshl(scalar, const, 0) must return scalar unchanged.
|
|
define void @fshl_scalar_const_shift0(ptr addrspace(1) %out, i32 %x) {
|
|
; CHECK-LABEL: fshl_scalar_const_shift0:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
|
; CHECK-NEXT: v_mov_b32_e32 v3, v1
|
|
; CHECK-NEXT: ; kill: def $vgpr0 killed $vgpr0 def $vgpr0_vgpr1 killed $exec
|
|
; CHECK-NEXT: v_mov_b32_e32 v1, v3
|
|
; CHECK-NEXT: v_readfirstlane_b32 s4, v2
|
|
; CHECK-NEXT: s_mov_b32 s3, 1
|
|
; CHECK-NEXT: s_lshr_b32 s2, s4, s3
|
|
; CHECK-NEXT: s_mov_b32 s0, 0x5040305
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 def $sgpr0_sgpr1
|
|
; CHECK-NEXT: s_mov_b32 s1, s4
|
|
; CHECK-NEXT: s_lshr_b64 s[0:1], s[0:1], s3
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 killed $sgpr0_sgpr1
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 def $sgpr0_sgpr1
|
|
; CHECK-NEXT: s_mov_b32 s1, s2
|
|
; CHECK-NEXT: s_mov_b32 s2, -1
|
|
; CHECK-NEXT: s_and_b32 s2, s2, 31
|
|
; CHECK-NEXT: s_lshr_b64 s[0:1], s[0:1], s2
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 killed $sgpr0_sgpr1
|
|
; CHECK-NEXT: v_mov_b32_e32 v2, s0
|
|
; CHECK-NEXT: global_store_dword v[0:1], v2, off
|
|
; CHECK-NEXT: s_waitcnt vmcnt(0)
|
|
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
|
%scalar = call i32 @llvm.amdgcn.readfirstlane(i32 %x)
|
|
%result = call i32 @llvm.fshl.i32(i32 %scalar, i32 84148997, i32 0)
|
|
store i32 %result, ptr addrspace(1) %out, align 4
|
|
ret void
|
|
}
|
|
|
|
; fshl(scalar, const, 1): inverted shift is 31 (= -1 masked to 31), which is
|
|
; correct. The bug was that -1 matched ShiftAmt32Imm (Imm < 32, signed) and
|
|
; skipped the S_AND_B32 masking, passing -1 raw to S_LSHR_B64.
|
|
define void @fshl_scalar_const_shift1(ptr addrspace(1) %out, i32 %x) {
|
|
; CHECK-LABEL: fshl_scalar_const_shift1:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
|
; CHECK-NEXT: v_mov_b32_e32 v3, v1
|
|
; CHECK-NEXT: ; kill: def $vgpr0 killed $vgpr0 def $vgpr0_vgpr1 killed $exec
|
|
; CHECK-NEXT: v_mov_b32_e32 v1, v3
|
|
; CHECK-NEXT: v_readfirstlane_b32 s2, v2
|
|
; CHECK-NEXT: s_mov_b32 s0, 0xf2f2f2f2
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 def $sgpr0_sgpr1
|
|
; CHECK-NEXT: s_mov_b32 s1, s2
|
|
; CHECK-NEXT: s_mov_b32 s2, -1
|
|
; CHECK-NEXT: s_and_b32 s2, s2, 31
|
|
; CHECK-NEXT: s_lshr_b64 s[0:1], s[0:1], s2
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 killed $sgpr0_sgpr1
|
|
; CHECK-NEXT: v_mov_b32_e32 v2, s0
|
|
; CHECK-NEXT: global_store_dword v[0:1], v2, off
|
|
; CHECK-NEXT: s_waitcnt vmcnt(0)
|
|
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
|
%scalar = call i32 @llvm.amdgcn.readfirstlane(i32 %x)
|
|
%result = call i32 @llvm.fshl.i32(i32 %scalar, i32 -218959118, i32 1)
|
|
store i32 %result, ptr addrspace(1) %out, align 4
|
|
ret void
|
|
}
|
|
|
|
; fshl(scalar, const, 16): inverted shift is -16, which also satisfied
|
|
; Imm < 32 signed and bypassed S_AND_B32 masking before the fix.
|
|
define void @fshl_scalar_const_shift16(ptr addrspace(1) %out, i32 %x) {
|
|
; CHECK-LABEL: fshl_scalar_const_shift16:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
|
; CHECK-NEXT: v_mov_b32_e32 v3, v1
|
|
; CHECK-NEXT: ; kill: def $vgpr0 killed $vgpr0 def $vgpr0_vgpr1 killed $exec
|
|
; CHECK-NEXT: v_mov_b32_e32 v1, v3
|
|
; CHECK-NEXT: v_readfirstlane_b32 s2, v2
|
|
; CHECK-NEXT: s_mov_b32 s0, 0xf2f2f2f2
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 def $sgpr0_sgpr1
|
|
; CHECK-NEXT: s_mov_b32 s1, s2
|
|
; CHECK-NEXT: s_mov_b32 s2, -16
|
|
; CHECK-NEXT: s_and_b32 s2, s2, 31
|
|
; CHECK-NEXT: s_lshr_b64 s[0:1], s[0:1], s2
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 killed $sgpr0_sgpr1
|
|
; CHECK-NEXT: v_mov_b32_e32 v2, s0
|
|
; CHECK-NEXT: global_store_dword v[0:1], v2, off
|
|
; CHECK-NEXT: s_waitcnt vmcnt(0)
|
|
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
|
%scalar = call i32 @llvm.amdgcn.readfirstlane(i32 %x)
|
|
%result = call i32 @llvm.fshl.i32(i32 %scalar, i32 -218959118, i32 16)
|
|
store i32 %result, ptr addrspace(1) %out, align 4
|
|
ret void
|
|
}
|
|
|
|
; fshl(scalar, scalar, 8): both inputs uniform; inverted shift is -8, which
|
|
; also satisfied Imm < 32 signed and bypassed S_AND_B32 masking before the fix.
|
|
define void @fshl_scalar_scalar_shift8(ptr addrspace(1) %out, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: fshl_scalar_scalar_shift8:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
|
; CHECK-NEXT: v_mov_b32_e32 v4, v1
|
|
; CHECK-NEXT: ; kill: def $vgpr0 killed $vgpr0 def $vgpr0_vgpr1 killed $exec
|
|
; CHECK-NEXT: v_mov_b32_e32 v1, v4
|
|
; CHECK-NEXT: v_readfirstlane_b32 s2, v2
|
|
; CHECK-NEXT: v_readfirstlane_b32 s0, v3
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 def $sgpr0_sgpr1
|
|
; CHECK-NEXT: s_mov_b32 s1, s2
|
|
; CHECK-NEXT: s_mov_b32 s2, -8
|
|
; CHECK-NEXT: s_and_b32 s2, s2, 31
|
|
; CHECK-NEXT: s_lshr_b64 s[0:1], s[0:1], s2
|
|
; CHECK-NEXT: ; kill: def $sgpr0 killed $sgpr0 killed $sgpr0_sgpr1
|
|
; CHECK-NEXT: v_mov_b32_e32 v2, s0
|
|
; CHECK-NEXT: global_store_dword v[0:1], v2, off
|
|
; CHECK-NEXT: s_waitcnt vmcnt(0)
|
|
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
|
%sx = call i32 @llvm.amdgcn.readfirstlane(i32 %x)
|
|
%sy = call i32 @llvm.amdgcn.readfirstlane(i32 %y)
|
|
%result = call i32 @llvm.fshl.i32(i32 %sx, i32 %sy, i32 8)
|
|
store i32 %result, ptr addrspace(1) %out, align 4
|
|
ret void
|
|
}
|