llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-llvm-ir Author: Fangrui Song (MaskRay) <details> <summary>Changes</summary> Printing the raw symbol is useful in inline asm (e.g. getting the C++ mangled name, referencing a symbol in a custom way while ensuring it is not optimized out even if internal). Similar constraints are available in other targets (e.g. "S" for aarch64/riscv, "Cs" for m68k). ``` namespace ns { extern int var; } asm (".pushsection .xxx,\"aw\"; .dc.a %p0; .popsection" :: "Ws"(&var)); asm (".reloc ., BFD_RELOC_NONE, %p0" :: "Ws"(&var)); ``` DO NOT SUBMIT wait for Ws patch https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105576 --- Full diff: https://github.com/llvm/llvm-project/pull/77886.diff 8 Files Affected: - (modified) clang/lib/Basic/Targets/X86.cpp (+11) - (modified) clang/test/CodeGen/X86/inline-asm-constraints.c (+8) - (modified) clang/test/Sema/inline-asm-validate-x86.c (+4) - (modified) llvm/docs/LangRef.rst (+2) - (modified) llvm/lib/Target/X86/X86AsmPrinter.cpp (+8) - (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+15-5) - (added) llvm/test/CodeGen/X86/inline-asm-Ws-constraint-error.ll (+9) - (added) llvm/test/CodeGen/X86/inline-asm-Ws-constraint.ll (+34) ``````````diff diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 64e281b888a95f..a68b662d9401aa 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -1418,6 +1418,14 @@ bool X86TargetInfo::validateAsmConstraint( case 'O': Info.setRequiresImmediate(0, 127); return true; + case 'W': + switch (*++Name) { + default: + return false; + case 's': + Info.setAllowsRegister(); + return true; + } // Register constraints. case 'Y': // 'Y' is the first character for several 2-character constraints. // Shift the pointer to the second character of the constraint. @@ -1715,6 +1723,9 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { return std::string("{st}"); case 'u': // second from top of floating point stack. return std::string("{st(1)}"); // second from top of floating point stack. + case 'W': + assert(Constraint[1] == 's'); + return '^' + std::string(Constraint++, 2); case 'Y': switch (Constraint[1]) { default: diff --git a/clang/test/CodeGen/X86/inline-asm-constraints.c b/clang/test/CodeGen/X86/inline-asm-constraints.c index b75a84d7a7bcbf..bfcbbca7c4f6bf 100644 --- a/clang/test/CodeGen/X86/inline-asm-constraints.c +++ b/clang/test/CodeGen/X86/inline-asm-constraints.c @@ -53,3 +53,11 @@ __m512 testZMM0(void) { #endif return zmm0; } + +extern int var; + +// CHECK-LABEL: test_Ws( +// CHECK: call void asm sideeffect "// ${0:p} ${1:p}", "^Ws,^Ws,~{dirflag},~{fpsr},~{flags}"(ptr @var, ptr @test_Ws) +void test_Ws(void) { + asm("// %p0 %p1" :: "Ws"(&var), "Ws"(test_Ws)); +} diff --git a/clang/test/Sema/inline-asm-validate-x86.c b/clang/test/Sema/inline-asm-validate-x86.c index 87b60a0955301a..032d76477c4ae6 100644 --- a/clang/test/Sema/inline-asm-validate-x86.c +++ b/clang/test/Sema/inline-asm-validate-x86.c @@ -130,3 +130,7 @@ void pr40890(void) { __asm__ __volatile__("\n#define BEEF abcd%0\n" : : "n"((int*)0xdeadbeeeeeef)); #endif } + +void test_W() { + asm("" : : "Wd"(test_W)); // expected-error{{invalid input constraint 'Wd' in asm}} +} diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index d881deb30049a2..076029976ffc5d 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -5336,6 +5336,7 @@ X86: operand in a SSE register. If AVX is also enabled, can also be a 256-bit vector operand in an AVX register. If AVX-512 is also enabled, can also be a 512-bit vector operand in an AVX512 register. Otherwise, an error. +- ``Ws``: A symbolic reference or label reference. - ``x``: The same as ``v``, except that when AVX-512 is enabled, the ``x`` code only allocates into the first 16 AVX-512 registers, while the ``v`` code allocates into any of the 32 AVX-512 registers. @@ -5518,6 +5519,7 @@ X86: the operand. (The behavior for relocatable symbol expressions is a target-specific behavior for this typically target-independent modifier) - ``H``: Print a memory reference with additional offset +8. +- ``p``: Print a raw symbol name (without syntax-specific prefixes). - ``P``: Print a memory reference used as the argument of a call instruction or used with explicit base reg and index reg as its offset. So it can not use additional regs to present the memory reference. (E.g. omit ``(rip)``, even diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index 15cfd247f125ca..9f0fd4d0938e97 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -774,6 +774,14 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, PrintOperand(MI, OpNo, O); return false; + case 'p': { + const MachineOperand &MO = MI->getOperand(OpNo); + if (MO.getType() != MachineOperand::MO_GlobalAddress) + return true; + PrintSymbolOperand(MO, O); + return false; + } + case 'P': // This is the operand of a call, treat specially. PrintPCRelImm(MI, OpNo, O); return false; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 700ab797b2f69f..aea8e8b40ff631 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -56676,6 +56676,10 @@ X86TargetLowering::getConstraintType(StringRef Constraint) const { switch (Constraint[0]) { default: break; + case 'W': + if (Constraint[1] != 's') + break; + return C_Other; case 'Y': switch (Constraint[1]) { default: @@ -56880,11 +56884,6 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op, std::vector<SDValue> &Ops, SelectionDAG &DAG) const { SDValue Result; - - // Only support length 1 constraints for now. - if (Constraint.size() > 1) - return; - char ConstraintLetter = Constraint[0]; switch (ConstraintLetter) { default: break; @@ -56966,6 +56965,17 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op, } return; } + case 'W': { + assert(Constraint[1] == 's'); + if (const auto *GA = dyn_cast<GlobalAddressSDNode>(Op)) { + Ops.push_back(DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(Op), + GA->getValueType(0))); + } else if (const auto *BA = dyn_cast<BlockAddressSDNode>(Op)) { + Ops.push_back(DAG.getTargetBlockAddress(BA->getBlockAddress(), + BA->getValueType(0))); + } + return; + } case 'Z': { // 32-bit unsigned value if (auto *C = dyn_cast<ConstantSDNode>(Op)) { diff --git a/llvm/test/CodeGen/X86/inline-asm-Ws-constraint-error.ll b/llvm/test/CodeGen/X86/inline-asm-Ws-constraint-error.ll new file mode 100644 index 00000000000000..38d0f08dfbd865 --- /dev/null +++ b/llvm/test/CodeGen/X86/inline-asm-Ws-constraint-error.ll @@ -0,0 +1,9 @@ +; RUN: not llc -mtriple=x86_64 < %s 2>&1 | FileCheck %s + +; CHECK: error: invalid operand for inline asm constraint 'Ws' +define void @test() { +entry: + %x = alloca i32, align 4 + call void asm sideeffect "// ${0:p}", "^Ws,~{dirflag},~{fpsr},~{flags}"(ptr %x) + ret void +} diff --git a/llvm/test/CodeGen/X86/inline-asm-Ws-constraint.ll b/llvm/test/CodeGen/X86/inline-asm-Ws-constraint.ll new file mode 100644 index 00000000000000..72fc13795f08ce --- /dev/null +++ b/llvm/test/CodeGen/X86/inline-asm-Ws-constraint.ll @@ -0,0 +1,34 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=i686 < %s | FileCheck %s +; RUN: llc -mtriple=x86_64 < %s | FileCheck %s + +@var = external dso_local global i32, align 4 + +define dso_local void @test() { +; CHECK-LABEL: test: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: #APP +; CHECK-NEXT: # var test +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: ret{{[l|q]}} +entry: + call void asm sideeffect "// ${0:p} ${1:p}", "^Ws,^Ws,~{dirflag},~{fpsr},~{flags}"(ptr @var, ptr @test) + ret void +} + +define dso_local void @test_label() { +; CHECK-LABEL: test_label: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: .Ltmp0: # Block address taken +; CHECK-NEXT: # %bb.1: # %label +; CHECK-NEXT: #APP +; CHECK-NEXT: # .Ltmp0 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: ret{{[l|q]}} +entry: + br label %label + +label: + tail call void asm sideeffect "// ${0:p}", "Ws,~{dirflag},~{fpsr},~{flags}"(ptr blockaddress(@test_label, %label)) + ret void +} `````````` </details> https://github.com/llvm/llvm-project/pull/77886 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits