https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/185590
>From 6d59200f6edcf635a5b61b4896d8e40df9ddc523 Mon Sep 17 00:00:00 2001 From: Fangrui Song <[email protected]> Date: Mon, 9 Mar 2026 23:46:36 -0700 Subject: [PATCH 1/2] [X86] Accept 'a' modifier for 'p' constraint in inline asm GCC requires the %a modifier with the p constraint (e.g., %a0), while Clang rejected it. The 'a' modifier means "print as address", which on a 'p' constraint memory operand is what the default path already does. Like GCC, reject 'a' with other memory constraints (e.g. 'm'). Close https://github.com/llvm/llvm-project/issues/185343 --- .../test/CodeGen/X86/inline-asm-constraints.c | 12 ++++++-- llvm/lib/Target/X86/X86AsmPrinter.cpp | 7 +++++ llvm/test/CodeGen/X86/asm-modifier-error.ll | 6 ++++ llvm/test/CodeGen/X86/asm-modifier.ll | 30 +++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/clang/test/CodeGen/X86/inline-asm-constraints.c b/clang/test/CodeGen/X86/inline-asm-constraints.c index c89d94cab946b..ab61e99103df5 100644 --- a/clang/test/CodeGen/X86/inline-asm-constraints.c +++ b/clang/test/CodeGen/X86/inline-asm-constraints.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -target-cpu x86-64 -o - |FileCheck %s --check-prefix SSE +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -target-cpu x86-64 -o - | FileCheck %s --check-prefixes=CHECK,SSE // RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -target-cpu skylake -D AVX -o - | FileCheck %s --check-prefixes AVX,SSE // RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -target-cpu skylake-avx512 -D AVX512 -D AVX -o - | FileCheck %s --check-prefixes AVX512,AVX,SSE // RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -target-cpu knl -D AVX -D AVX512 -o - | FileCheck %s --check-prefixes AVX512,AVX,SSE @@ -54,12 +54,18 @@ __m512 testZMM0(void) { return zmm0; } +// CHECK-LABEL: test_a_p( +// CHECK: call void asm sideeffect "lea ${0:a}, %eax", "p,~{eax},~{dirflag},~{fpsr},~{flags}"(ptr %0) +void test_a_p(int *ptr) { + asm("lea %a0, %%eax" :: "p"(ptr) : "eax"); +} + extern int var, arr[4]; struct Pair { int a, b; } pair; // CHECK-LABEL: test_Ws( -// CHECK: call void asm sideeffect "// ${0:p} ${1:p} ${2:p}", "^Ws,^Ws,^Ws,~{dirflag},~{fpsr},~{flags}"(ptr @var, ptr getelementptr inbounds ([4 x i32], ptr @arr, i64 0, i64 3), ptr @test_Ws) -// CHECK: call void asm sideeffect "// $0", "^Ws,~{dirflag},~{fpsr},~{flags}"(ptr getelementptr inbounds (%struct.Pair, ptr @pair, i32 0, i32 1)) +// CHECK: call void asm sideeffect "// ${0:p} ${1:p} ${2:p}", "^Ws,^Ws,^Ws,~{dirflag},~{fpsr},~{flags}"(ptr @var, ptr getelementptr inbounds nuw (i8, ptr @arr, i64 12), ptr @test_Ws) +// CHECK: call void asm sideeffect "// $0", "^Ws,~{dirflag},~{fpsr},~{flags}"(ptr getelementptr inbounds nuw (i8, ptr @pair, i64 4)) void test_Ws(void) { asm("// %p0 %p1 %p2" :: "Ws"(&var), "Ws"(&arr[3]), "Ws"(test_Ws)); asm("// %0" :: "Ws"(&pair.b)); diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index 84203c4b3da63..992040c46ceda 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -867,6 +867,13 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, switch (ExtraCode[0]) { default: return true; // Unknown modifier. + case 'a': { + // Print as address — only valid with 'p' constraint. + const InlineAsm::Flag Flags(MI->getOperand(OpNo - 1).getImm()); + if (Flags.getMemoryConstraintID() != InlineAsm::ConstraintCode::p) + return true; + break; + } case 'b': // Print QImode register case 'h': // Print QImode high register case 'w': // Print HImode register diff --git a/llvm/test/CodeGen/X86/asm-modifier-error.ll b/llvm/test/CodeGen/X86/asm-modifier-error.ll index 2d942c01fe0de..bea96a8253ddc 100644 --- a/llvm/test/CodeGen/X86/asm-modifier-error.ll +++ b/llvm/test/CodeGen/X86/asm-modifier-error.ll @@ -7,6 +7,12 @@ entry: ret void } +; CHECK: error: invalid operand in inline asm: '#TEST ${0:a}' +define void @test_a_m(ptr %p) { + call void asm sideeffect "#TEST ${0:a}", "*m,~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) %p) + ret void +} + ;CHECK: error: invalid operand in inline asm: 'vmovd ${1:k}, $0' define i32 @foo() { entry: diff --git a/llvm/test/CodeGen/X86/asm-modifier.ll b/llvm/test/CodeGen/X86/asm-modifier.ll index 7fa1e34a288da..e1aac95a1ff6a 100644 --- a/llvm/test/CodeGen/X86/asm-modifier.ll +++ b/llvm/test/CodeGen/X86/asm-modifier.ll @@ -23,6 +23,36 @@ define dso_local void @test_a() nounwind { ret void } +define dso_local void @test_a_p(ptr %p) nounwind { +; X86-LABEL: test_a_p: +; X86: # %bb.0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: #APP +; X86-NEXT: #TEST (%eax) +; X86-NEXT: #NO_APP +; X86-NEXT: #APP +; X86-EMPTY: +; X86-NEXT: #TEST [eax] +; X86-EMPTY: +; X86-NEXT: #NO_APP +; X86-NEXT: retl +; +; X64-LABEL: test_a_p: +; X64: # %bb.0: +; X64-NEXT: #APP +; X64-NEXT: #TEST (%rdi) +; X64-NEXT: #NO_APP +; X64-NEXT: #APP +; X64-EMPTY: +; X64-NEXT: #TEST [rdi] +; X64-EMPTY: +; X64-NEXT: #NO_APP +; X64-NEXT: retq + tail call void asm sideeffect "#TEST ${0:a}", "p,~{dirflag},~{fpsr},~{flags}"(ptr %p) + tail call void asm sideeffect inteldialect "#TEST ${0:a}", "p,~{dirflag},~{fpsr},~{flags}"(ptr %p) + ret void +} + define dso_local void @test_c() nounwind { ; CHECK-LABEL: test_c: ; CHECK: # %bb.0: >From c09f1ce8d31f8b882d144a27596d381e75136b39 Mon Sep 17 00:00:00 2001 From: Fangrui Song <[email protected]> Date: Tue, 10 Mar 2026 00:47:42 -0700 Subject: [PATCH 2/2] improve clang test --- clang/test/CodeGen/X86/inline-asm-constraints.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/CodeGen/X86/inline-asm-constraints.c b/clang/test/CodeGen/X86/inline-asm-constraints.c index ab61e99103df5..20c4e26ddffe5 100644 --- a/clang/test/CodeGen/X86/inline-asm-constraints.c +++ b/clang/test/CodeGen/X86/inline-asm-constraints.c @@ -56,8 +56,10 @@ __m512 testZMM0(void) { // CHECK-LABEL: test_a_p( // CHECK: call void asm sideeffect "lea ${0:a}, %eax", "p,~{eax},~{dirflag},~{fpsr},~{flags}"(ptr %0) -void test_a_p(int *ptr) { +// CHECK: call void asm sideeffect "lea ${0:a}, %eax", "p,~{eax},~{dirflag},~{fpsr},~{flags}"(i32 %add) +void test_a_p(int *ptr, int i) { asm("lea %a0, %%eax" :: "p"(ptr) : "eax"); + asm("lea %a0, %%eax" :: "p"(0x1480 + i * 8) : "eax"); } extern int var, arr[4]; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
