From 9b8bee2dc6bd290354b02639daf16850763a309d Mon Sep 17 00:00:00 2001 From: Fabian Ritter Date: Mon, 20 Jan 2025 06:10:18 -0500 Subject: [PATCH 1/3] [AMDGPU] Reject misaligned SGPR constraints for inline asm The indices of SGPR register pairs need to be 2-aligned and SGPR quadruplets need to be 4-aligned. With this patch, we report an error when inline asm register constraints specify a misaligned register index, instead of silently dropping the specified index. Fixes #123208 --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 6 +++ .../AMDGPU/inlineasm-mismatched-size-error.ll | 51 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index c4b1038b12d04..592a72e109543 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -15877,6 +15877,12 @@ SITargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI_, RC = TRI->getAGPRClassForBitWidth(Width); if (RC) { Reg = TRI->getMatchingSuperReg(Reg, AMDGPU::sub0, RC); + if (Reg == 0U) { + // The register class does not contain the requested register, + // e.g., because it is an SGPR pair that would violate alignment + // requirements. + return std::pair(0U, nullptr); + } return std::pair(Reg, RC); } } diff --git a/llvm/test/CodeGen/AMDGPU/inlineasm-mismatched-size-error.ll b/llvm/test/CodeGen/AMDGPU/inlineasm-mismatched-size-error.ll index 723e0f2e7152d..e8accc1c8a0f3 100644 --- a/llvm/test/CodeGen/AMDGPU/inlineasm-mismatched-size-error.ll +++ b/llvm/test/CodeGen/AMDGPU/inlineasm-mismatched-size-error.ll @@ -102,3 +102,54 @@ define <2 x i8> @inline_asm_2xi8_in_s_def() { %r = and <2 x i8> %phys, %virt ret <2 x i8> %r } + + +; The register is wide enough, but it does not satisfy alignment constraints: + +; ERR: error: couldn't allocate input reg for constraint '{s[1:2]}' +define void @misaligned_sgpr_2xi32_in(<2 x i32> inreg %arg0) { + call void asm sideeffect "; use $0", "{s[1:2]}"(<2 x i32> %arg0) + ret void +} + +; ERR: error: couldn't allocate input reg for constraint '{s[23:24]}' +define void @misaligned_sgpr_2xi32_in_23(<2 x i32> inreg %arg0) { + call void asm sideeffect "; use $0", "{s[23:24]}"(<2 x i32> %arg0) + ret void +} + +; ERR: error: couldn't allocate input reg for constraint '{s[1:4]}' +define void @misaligned_sgpr_4xi32_in(<4 x i32> inreg %arg0) { + call void asm sideeffect "; use $0", "{s[1:4]}"(<4 x i32> %arg0) + ret void +} + +; ERR: error: couldn't allocate input reg for constraint '{s[2:5]}' +define void @misaligned_sgpr_4xi32_in_2(<4 x i32> inreg %arg0) { + call void asm sideeffect "; use $0", "{s[2:5]}"(<4 x i32> %arg0) + ret void +} + +; ERR: error: couldn't allocate output register for constraint '{s[1:2]}' +define <2 x i32> @misaligned_sgpr_2xi32_out() { + %asm = call <2 x i32> asm sideeffect "; def $0", "={s[1:2]}"() + ret <2 x i32> %asm +} + +; ERR: error: couldn't allocate output register for constraint '{s[23:24]}' +define <2 x i32> @misaligned_sgpr_2xi32_out_23() { + %asm = call <2 x i32> asm sideeffect "; def $0", "={s[23:24]}"() + ret <2 x i32> %asm +} + +; ERR: error: couldn't allocate output register for constraint '{s[1:4]}' +define <4 x i32> @misaligned_sgpr_4xi32_out() { + %asm = call <4 x i32> asm sideeffect "; def $0", "={s[1:4]}"() + ret <4 x i32> %asm +} + +; ERR: error: couldn't allocate output register for constraint '{s[2:5]}' +define <4 x i32> @misaligned_sgpr_4xi32_out_2() { + %asm = call <4 x i32> asm sideeffect "; def $0", "={s[2:5]}"() + ret <4 x i32> %asm +} From 19512cbd27bd7fbd58e6700128f95d40cc8b698c Mon Sep 17 00:00:00 2001 From: Fabian Ritter Date: Mon, 20 Jan 2025 12:30:12 +0100 Subject: [PATCH 2/3] Update llvm/lib/Target/AMDGPU/SIISelLowering.cpp Co-authored-by: Matt Arsenault --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 592a72e109543..553ca9bb28467 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -15877,7 +15877,7 @@ SITargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI_, RC = TRI->getAGPRClassForBitWidth(Width); if (RC) { Reg = TRI->getMatchingSuperReg(Reg, AMDGPU::sub0, RC); - if (Reg == 0U) { + if (!Reg ) { // The register class does not contain the requested register, // e.g., because it is an SGPR pair that would violate alignment // requirements. From a7e5a7c08a2e8507598b9b02c38eafd34431dfcd Mon Sep 17 00:00:00 2001 From: Fabian Ritter Date: Mon, 20 Jan 2025 13:35:27 +0100 Subject: [PATCH 3/3] Update llvm/lib/Target/AMDGPU/SIISelLowering.cpp Co-authored-by: Matt Arsenault --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 553ca9bb28467..41a24a7793c1f 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -15877,7 +15877,7 @@ SITargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI_, RC = TRI->getAGPRClassForBitWidth(Width); if (RC) { Reg = TRI->getMatchingSuperReg(Reg, AMDGPU::sub0, RC); - if (!Reg ) { + if (!Reg) { // The register class does not contain the requested register, // e.g., because it is an SGPR pair that would violate alignment // requirements.