| ; Test that .amdgcn_target directive includes xnack modifier based on module flag | |
| ; Tests xnack+ (on), xnack- (off), and absent (Any) cases | |
| ; Also tests that unsupported targets ignore the xnack module flag | |
| ; RUN: split-file %s %t | |
| ; RUN: llc -mtriple=amdgpu9.00-amd-amdhsa < %t/on.ll | FileCheck --check-prefix=XNACK-ON %s | |
| ; RUN: llc -mtriple=amdgpu9.00-amd-amdhsa < %t/off.ll | FileCheck --check-prefix=XNACK-OFF %s | |
| ; RUN: llc -mtriple=amdgpu9.00-amd-amdhsa < %t/absent.ll | FileCheck --check-prefix=XNACK-ANY %s | |
| ; Test that xnack module flag is ignored on targets that don't support it. gfx801 supports xnack, gfx803 does not. | |
| ; RUN: llc -mtriple=amdgpu8.01-amd-amdhsa < %t/on.ll | FileCheck --check-prefixes=CHECK,GFX801 %s | |
| ; RUN: llc -mtriple=amdgpu8.03-amd-amdhsa < %t/on.ll | FileCheck --check-prefixes=CHECK,GFX803 %s | |
| ; Target directives for xnack supported target | |
| ; XNACK-ON: .amdgcn_target "amdgpu9.00-amd-amdhsa-unknown-gfx900:xnack+" | |
| ; XNACK-OFF: .amdgcn_target "amdgpu9.00-amd-amdhsa-unknown-gfx900:xnack-" | |
| ; XNACK-ANY: .amdgcn_target "amdgpu9.00-amd-amdhsa-unknown-gfx900" | |
| ; GFX801: .amdgcn_target "amdgpu8.01-amd-amdhsa-unknown-gfx801:xnack+" | |
| ; GFX803: .amdgcn_target "amdgpu8.03-amd-amdhsa-unknown-gfx803" | |
| ; Check codegen impact - xnack affects register allocation | |
| ; When xnack is on, first load must not overwrite the pointer argument | |
| ; XNACK-ON-LABEL: {{^}}simple_clause: | |
| ; XNACK-ON: flat_load_dword v4, v[0:1] | |
| ; XNACK-ON-NEXT: flat_load_dword v5, v[2:3] | |
| ; When xnack is off, first load can overwrite the pointer argument | |
| ; XNACK-OFF-LABEL: {{^}}simple_clause: | |
| ; XNACK-OFF: flat_load_dword v0, v[0:1] | |
| ; XNACK-OFF-NEXT: flat_load_dword v1, v[2:3] | |
| ; When xnack is not specified (Any), behavior is conservative (like on) | |
| ; XNACK-ANY-LABEL: {{^}}simple_clause: | |
| ; XNACK-ANY: flat_load_dword v4, v[0:1] | |
| ; XNACK-ANY-NEXT: flat_load_dword v5, v[2:3] | |
| ; Codegen for supported vs unsupported targets | |
| ; CHECK-LABEL: {{^}}simple_clause: | |
| ; First load must not overwrite the pointer argument on gfx801 (xnack supported) | |
| ; GFX801: flat_load_dword v4, v[0:1] | |
| ; GFX801-NEXT: flat_load_dword v5, v[2:3] | |
| ; First load overwrites the pointer argument on gfx803 (xnack not supported) | |
| ; GFX803: flat_load_dword v0, v[0:1] | |
| ; GFX803-NEXT: flat_load_dword v1, v[2:3] | |
| ;--- on.ll | |
| define i32 @simple_clause(ptr %ptr0, ptr %ptr1) { | |
| %val0 = load i32, ptr %ptr0 | |
| %val1 = load i32, ptr %ptr1 | |
| %add = add i32 %val0, %val1 | |
| ret i32 %add | |
| } | |
| !llvm.module.flags = !{!0} | |
| !0 = !{i32 1, !"amdgpu.xnack", i32 1} | |
| ;--- off.ll | |
| define i32 @simple_clause(ptr %ptr0, ptr %ptr1) { | |
| %val0 = load i32, ptr %ptr0 | |
| %val1 = load i32, ptr %ptr1 | |
| %add = add i32 %val0, %val1 | |
| ret i32 %add | |
| } | |
| !llvm.module.flags = !{!0} | |
| !0 = !{i32 1, !"amdgpu.xnack", i32 0} | |
| ;--- absent.ll | |
| define i32 @simple_clause(ptr %ptr0, ptr %ptr1) { | |
| %val0 = load i32, ptr %ptr0 | |
| %val1 = load i32, ptr %ptr1 | |
| %add = add i32 %val0, %val1 | |
| ret i32 %add | |
| } |