| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc -global-isel=0 -mtriple=amdgpu9.00 < %s | FileCheck -check-prefixes=SDAG,CHECK %s | |
| ; RUN: llc -global-isel=1 -mtriple=amdgpu9.00 < %s | FileCheck -check-prefixes=GISEL,CHECK %s | |
| ; readfirstlane/readlane preserve the data operand's bits. Both SDAG's | |
| ; computeKnownBitsForTargetNode and GISel's computeKnownBitsForTargetInstr look | |
| ; through these intrinsics, so the trailing `and ..., 0xff` is folded away. | |
| declare i32 @llvm.amdgcn.readfirstlane.i32(i32) | |
| declare i32 @llvm.amdgcn.readlane.i32(i32, i32) | |
| declare i32 @llvm.amdgcn.workitem.id.x() | |
| define amdgpu_kernel void @readfirstlane_redundant_and(ptr addrspace(1) %out, ptr addrspace(1) %in) { | |
| ; SDAG-LABEL: readfirstlane_redundant_and: | |
| ; SDAG: ; %bb.0: | |
| ; SDAG-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 | |
| ; SDAG-NEXT: v_lshlrev_b32_e32 v0, 2, v0 | |
| ; SDAG-NEXT: v_mov_b32_e32 v1, 0 | |
| ; SDAG-NEXT: s_waitcnt lgkmcnt(0) | |
| ; SDAG-NEXT: global_load_dword v0, v0, s[2:3] | |
| ; SDAG-NEXT: s_waitcnt vmcnt(0) | |
| ; SDAG-NEXT: v_and_b32_e32 v0, 0xff, v0 | |
| ; SDAG-NEXT: v_readfirstlane_b32 s2, v0 | |
| ; SDAG-NEXT: v_mov_b32_e32 v0, s2 | |
| ; SDAG-NEXT: global_store_dword v1, v0, s[0:1] | |
| ; SDAG-NEXT: s_endpgm | |
| ; | |
| ; GISEL-LABEL: readfirstlane_redundant_and: | |
| ; GISEL: ; %bb.0: | |
| ; GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 | |
| ; GISEL-NEXT: v_lshlrev_b32_e32 v0, 2, v0 | |
| ; GISEL-NEXT: v_mov_b32_e32 v1, 0 | |
| ; GISEL-NEXT: s_waitcnt lgkmcnt(0) | |
| ; GISEL-NEXT: global_load_ubyte v0, v0, s[2:3] | |
| ; GISEL-NEXT: s_waitcnt vmcnt(0) | |
| ; GISEL-NEXT: v_readfirstlane_b32 s2, v0 | |
| ; GISEL-NEXT: v_mov_b32_e32 v0, s2 | |
| ; GISEL-NEXT: global_store_dword v1, v0, s[0:1] | |
| ; GISEL-NEXT: s_endpgm | |
| %tid = call i32 @llvm.amdgcn.workitem.id.x() | |
| %gep = getelementptr i32, ptr addrspace(1) %in, i32 %tid | |
| %v = load i32, ptr addrspace(1) %gep | |
| %m = and i32 %v, 255 | |
| %rfl = call i32 @llvm.amdgcn.readfirstlane.i32(i32 %m) | |
| %and = and i32 %rfl, 255 | |
| store i32 %and, ptr addrspace(1) %out | |
| ret void | |
| } | |
| define amdgpu_kernel void @readlane_redundant_and(ptr addrspace(1) %out, ptr addrspace(1) %in, i32 %lane) { | |
| ; SDAG-LABEL: readlane_redundant_and: | |
| ; SDAG: ; %bb.0: | |
| ; SDAG-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 | |
| ; SDAG-NEXT: s_load_dword s6, s[4:5], 0x34 | |
| ; SDAG-NEXT: v_lshlrev_b32_e32 v0, 2, v0 | |
| ; SDAG-NEXT: v_mov_b32_e32 v1, 0 | |
| ; SDAG-NEXT: s_waitcnt lgkmcnt(0) | |
| ; SDAG-NEXT: global_load_dword v0, v0, s[2:3] | |
| ; SDAG-NEXT: s_waitcnt vmcnt(0) | |
| ; SDAG-NEXT: v_and_b32_e32 v0, 0xff, v0 | |
| ; SDAG-NEXT: v_readlane_b32 s2, v0, s6 | |
| ; SDAG-NEXT: v_mov_b32_e32 v0, s2 | |
| ; SDAG-NEXT: global_store_dword v1, v0, s[0:1] | |
| ; SDAG-NEXT: s_endpgm | |
| ; | |
| ; GISEL-LABEL: readlane_redundant_and: | |
| ; GISEL: ; %bb.0: | |
| ; GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 | |
| ; GISEL-NEXT: s_load_dword s6, s[4:5], 0x34 | |
| ; GISEL-NEXT: v_lshlrev_b32_e32 v0, 2, v0 | |
| ; GISEL-NEXT: v_mov_b32_e32 v1, 0 | |
| ; GISEL-NEXT: s_waitcnt lgkmcnt(0) | |
| ; GISEL-NEXT: global_load_ubyte v0, v0, s[2:3] | |
| ; GISEL-NEXT: s_waitcnt vmcnt(0) | |
| ; GISEL-NEXT: v_readlane_b32 s2, v0, s6 | |
| ; GISEL-NEXT: v_mov_b32_e32 v0, s2 | |
| ; GISEL-NEXT: global_store_dword v1, v0, s[0:1] | |
| ; GISEL-NEXT: s_endpgm | |
| %tid = call i32 @llvm.amdgcn.workitem.id.x() | |
| %gep = getelementptr i32, ptr addrspace(1) %in, i32 %tid | |
| %v = load i32, ptr addrspace(1) %gep | |
| %m = and i32 %v, 255 | |
| %rl = call i32 @llvm.amdgcn.readlane.i32(i32 %m, i32 %lane) | |
| %and = and i32 %rl, 255 | |
| store i32 %and, ptr addrspace(1) %out | |
| ret void | |
| } | |
| ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: | |
| ; CHECK: {{.*}} |