[llvm] [X86][MC] Keep backward compatibility in inline asm for constraints (PR #73529)
Shengchen Kan via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 27 17:27:53 PST 2023
https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/73529
>From 99d8ae2d9c90e7357a02d3687183ff75baf883ed Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Mon, 27 Nov 2023 16:42:08 +0800
Subject: [PATCH 1/2] [X86][MC] Keep backward compatibility in inline asm for
new registers
Not use r16-r31 with 'q','r','l' constraint for backward compatibility
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 16 ++++++-------
llvm/test/CodeGen/X86/apx/asm-constraint.ll | 24 +++++++++++++++++++
.../callbr-asm-outputs-indirect-isel-m32.ll | 20 +++++++++-------
.../X86/callbr-asm-outputs-indirect-isel.ll | 16 ++++++-------
4 files changed, 51 insertions(+), 25 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/apx/asm-constraint.ll
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d0e51301945ecb5..e1c627f97e393bc 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -56939,13 +56939,13 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
case 'q': // GENERAL_REGS in 64-bit mode, Q_REGS in 32-bit mode.
if (Subtarget.is64Bit()) {
if (VT == MVT::i8 || VT == MVT::i1)
- return std::make_pair(0U, &X86::GR8RegClass);
+ return std::make_pair(0U, &X86::GR8_NOREX2RegClass);
if (VT == MVT::i16)
- return std::make_pair(0U, &X86::GR16RegClass);
+ return std::make_pair(0U, &X86::GR16_NOREX2RegClass);
if (VT == MVT::i32 || VT == MVT::f32)
- return std::make_pair(0U, &X86::GR32RegClass);
+ return std::make_pair(0U, &X86::GR32_NOREX2RegClass);
if (VT != MVT::f80 && !VT.isVector())
- return std::make_pair(0U, &X86::GR64RegClass);
+ return std::make_pair(0U, &X86::GR64_NOREX2RegClass);
break;
}
[[fallthrough]];
@@ -56964,14 +56964,14 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
case 'r': // GENERAL_REGS
case 'l': // INDEX_REGS
if (VT == MVT::i8 || VT == MVT::i1)
- return std::make_pair(0U, &X86::GR8RegClass);
+ return std::make_pair(0U, &X86::GR8_NOREX2RegClass);
if (VT == MVT::i16)
- return std::make_pair(0U, &X86::GR16RegClass);
+ return std::make_pair(0U, &X86::GR16_NOREX2RegClass);
if (VT == MVT::i32 || VT == MVT::f32 ||
(!VT.isVector() && !Subtarget.is64Bit()))
- return std::make_pair(0U, &X86::GR32RegClass);
+ return std::make_pair(0U, &X86::GR32_NOREX2RegClass);
if (VT != MVT::f80 && !VT.isVector())
- return std::make_pair(0U, &X86::GR64RegClass);
+ return std::make_pair(0U, &X86::GR64_NOREX2RegClass);
break;
case 'R': // LEGACY_REGS
if (VT == MVT::i8 || VT == MVT::i1)
diff --git a/llvm/test/CodeGen/X86/apx/asm-constraint.ll b/llvm/test/CodeGen/X86/apx/asm-constraint.ll
new file mode 100644
index 000000000000000..894582cc180da74
--- /dev/null
+++ b/llvm/test/CodeGen/X86/apx/asm-constraint.ll
@@ -0,0 +1,24 @@
+; Check r16-r31 can not be used with 'q','r','l' constraint for backward compatibility.
+; RUN: not llc < %s -mtriple=x86_64-unknown-unknown -mattr=+egpr 2>&1 | FileCheck %s
+
+define dso_local void @q() {
+entry:
+; CHECK: error: inline assembly requires more registers than available
+ %0 = tail call i32 asm sideeffect "movq %rax, $0", "=q,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"()
+ ret void
+}
+
+define dso_local void @r() {
+entry:
+; CHECK: error: inline assembly requires more registers than available
+ %0 = tail call i32 asm sideeffect "movq %rax, $0", "=r,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"()
+ ret void
+}
+
+define dso_local void @l() {
+entry:
+; CHECK: error: inline assembly requires more registers than available
+ %0 = tail call i32 asm sideeffect "movq %rax, $0", "=l,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"()
+ ret void
+}
+
diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
index 2086f13095dea56..ee3889dec005abf 100644
--- a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
+++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
@@ -10,11 +10,12 @@ define i8 @emulator_cmpxchg_emulated() {
; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm $noreg, 1, $noreg, 0, $noreg :: (load (s32) from `ptr null`, align 8)
- ; CHECK-NEXT: INLINEASM_BR &"", 16 /* maystore attdialect */, 2359306 /* regdef:GR32 */, def %2, 2359306 /* regdef:GR32 */, def %3, 2147549193 /* reguse tiedto:$1 */, [[MOV32rm]](tied-def 5), 13 /* imm */, %bb.2
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $eflags
- ; CHECK-NEXT: $eflags = COPY [[COPY]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32_norex2 = COPY [[MOV32rm]]
+ ; CHECK-NEXT: INLINEASM_BR &"", 16 /* maystore attdialect */, 2359306 /* regdef:GR32 */, def %2, 2686986 /* regdef:GR32_NOREX2 */, def %3, 2147549193 /* reguse tiedto:$1 */, [[COPY]](tied-def 5), 13 /* imm */, %bb.2
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $eflags
+ ; CHECK-NEXT: $eflags = COPY [[COPY1]]
; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
- ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY %3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY %3
; CHECK-NEXT: JMP_1 %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.asm.fallthrough:
@@ -49,15 +50,16 @@ define i32 @emulator_cmpxchg_emulated2() {
; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm $noreg, 1, $noreg, 0, $noreg :: (load (s32) from `ptr null`, align 8)
- ; CHECK-NEXT: INLINEASM_BR &"", 16 /* maystore attdialect */, 2359306 /* regdef:GR32 */, def %2, 2359306 /* regdef:GR32 */, def %3, 2147549193 /* reguse tiedto:$1 */, [[MOV32rm]](tied-def 5), 13 /* imm */, %bb.2
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $eflags
- ; CHECK-NEXT: $eflags = COPY [[COPY]]
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32_norex2 = COPY [[MOV32rm]]
+ ; CHECK-NEXT: INLINEASM_BR &"", 16 /* maystore attdialect */, 2359306 /* regdef:GR32 */, def %2, 2686986 /* regdef:GR32_NOREX2 */, def %3, 2147549193 /* reguse tiedto:$1 */, [[COPY]](tied-def 5), 13 /* imm */, %bb.2
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $eflags
+ ; CHECK-NEXT: $eflags = COPY [[COPY1]]
; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
- ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY %3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY %3
; CHECK-NEXT: JMP_1 %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.asm.fallthrough:
- ; CHECK-NEXT: $eax = COPY [[COPY1]]
+ ; CHECK-NEXT: $eax = COPY [[COPY2]]
; CHECK-NEXT: RET 0, $eax
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.efaultu64.split (machine-block-address-taken, inlineasm-br-indirect-target):
diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
index ead0230a1c89cbf..34f822ef5285037 100644
--- a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
+++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
@@ -10,7 +10,7 @@ define i32 @test0() {
; CHECK: bb.0 (%ir-block.0):
; CHECK-NEXT: successors: %bb.1(0x80000000), %bb.2(0x00000000)
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 2359306 /* regdef:GR32 */, def %1, 13 /* imm */, %bb.2
+ ; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 2686986 /* regdef:GR32_NOREX2 */, def %1, 13 /* imm */, %bb.2
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY %1
; CHECK-NEXT: JMP_1 %bb.1
; CHECK-NEXT: {{ $}}
@@ -39,7 +39,7 @@ define i32 @test1() {
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
- ; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 2359306 /* regdef:GR32 */, def %4, 13 /* imm */, %bb.1
+ ; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 2686986 /* regdef:GR32_NOREX2 */, def %4, 13 /* imm */, %bb.1
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY %4
; CHECK-NEXT: JMP_1 %bb.2
; CHECK-NEXT: {{ $}}
@@ -72,7 +72,7 @@ define i32 @test2() {
; CHECK-NEXT: successors: %bb.2(0x80000000), %bb.1(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
- ; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 2359306 /* regdef:GR32 */, def %5, 2359306 /* regdef:GR32 */, def %6, 13 /* imm */, %bb.1
+ ; CHECK-NEXT: INLINEASM_BR &"", 0 /* attdialect */, 2686986 /* regdef:GR32_NOREX2 */, def %5, 2686986 /* regdef:GR32_NOREX2 */, def %6, 13 /* imm */, %bb.1
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY %6
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY %5
; CHECK-NEXT: JMP_1 %bb.2
@@ -232,7 +232,7 @@ define i64 @test6() {
; CHECK-NEXT: liveins: $rdx
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr64 = COPY $rdx
- ; CHECK-NEXT: %3:gr64 = COPY [[COPY4]]
+ ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gr64 = COPY [[COPY4]]
; CHECK-NEXT: JMP_1 %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4.foo.split2 (machine-block-address-taken, inlineasm-br-indirect-target):
@@ -240,7 +240,7 @@ define i64 @test6() {
; CHECK-NEXT: liveins: $rbx
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY6:%[0-9]+]]:gr64 = COPY $rbx
- ; CHECK-NEXT: %4:gr64 = COPY [[COPY6]]
+ ; CHECK-NEXT: [[COPY7:%[0-9]+]]:gr64 = COPY [[COPY6]]
; CHECK-NEXT: JMP_1 %bb.2
entry:
%0 = callbr i64 asm "", "={dx},!i"()
@@ -291,7 +291,7 @@ define i32 @test7() {
; CHECK-NEXT: liveins: $edx
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr32 = COPY $edx
- ; CHECK-NEXT: %2:gr32 = COPY [[COPY3]]
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr32 = COPY [[COPY3]]
; CHECK-NEXT: JMP_1 %bb.1
entry:
br label %retry
@@ -317,8 +317,8 @@ define i32 @test8() {
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x80000000)
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: INLINEASM_BR &"# $0", 0 /* attdialect */, 2359306 /* regdef:GR32 */, def %1, 13 /* imm */, %bb.1
- ; CHECK-NEXT: %0:gr32 = COPY %1
+ ; CHECK-NEXT: INLINEASM_BR &"# $0", 0 /* attdialect */, 2686986 /* regdef:GR32_NOREX2 */, def %1, 13 /* imm */, %bb.1
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY %1
; CHECK-NEXT: JMP_1 %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.cleanup (machine-block-address-taken, inlineasm-br-indirect-target):
>From 737a1f5c57f3c28668ff8c971f597f7fab903a59 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Tue, 28 Nov 2023 09:27:21 +0800
Subject: [PATCH 2/2] Simplify the test
---
llvm/test/CodeGen/X86/apx/asm-constraint.ll | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/llvm/test/CodeGen/X86/apx/asm-constraint.ll b/llvm/test/CodeGen/X86/apx/asm-constraint.ll
index 894582cc180da74..9b81cbf29c25b93 100644
--- a/llvm/test/CodeGen/X86/apx/asm-constraint.ll
+++ b/llvm/test/CodeGen/X86/apx/asm-constraint.ll
@@ -1,24 +1,21 @@
; Check r16-r31 can not be used with 'q','r','l' constraint for backward compatibility.
; RUN: not llc < %s -mtriple=x86_64-unknown-unknown -mattr=+egpr 2>&1 | FileCheck %s
-define dso_local void @q() {
-entry:
+define void @q() {
; CHECK: error: inline assembly requires more registers than available
- %0 = tail call i32 asm sideeffect "movq %rax, $0", "=q,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"()
+ %a = call i32 asm sideeffect "movq %rax, $0", "=q,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
ret void
}
-define dso_local void @r() {
-entry:
+define void @r() {
; CHECK: error: inline assembly requires more registers than available
- %0 = tail call i32 asm sideeffect "movq %rax, $0", "=r,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"()
+ %a = call i32 asm sideeffect "movq %rax, $0", "=r,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
ret void
}
-define dso_local void @l() {
-entry:
+define void @l() {
; CHECK: error: inline assembly requires more registers than available
- %0 = tail call i32 asm sideeffect "movq %rax, $0", "=l,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"()
+ %a = call i32 asm sideeffect "movq %rax, $0", "=l,~{rax},~{rbx},~{rcx},~{rdx},~{rdi},~{rsi},~{rbp},~{rsp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
ret void
}
More information about the llvm-commits
mailing list