Skip to content

[X86] Add "Ws" constraint and "p" modifier for symbolic address/label reference #77886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

MaskRay
Copy link
Member

@MaskRay MaskRay commented Jan 12, 2024

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, a[4]; }
void foo() {
  asm(".pushsection .xxx,\"aw\"; .dc.a %p0; .popsection" :: "Ws"(&ns::var));
  asm(".reloc ., BFD_RELOC_NONE, %p0" :: "Ws"(&ns::a[3]));
}

Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105576

Created using spr 1.3.4
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:X86 clang:frontend Language frontend issues, e.g. anything involving "Sema" llvm:ir labels Jan 12, 2024
@MaskRay MaskRay requested a review from RKSimon January 12, 2024 07:43
@llvmbot
Copy link
Member

llvmbot commented Jan 12, 2024

@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-llvm-ir

Author: Fangrui Song (MaskRay)

Changes

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 --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
+}

@llvmbot
Copy link
Member

llvmbot commented Jan 12, 2024

@llvm/pr-subscribers-clang

Author: Fangrui Song (MaskRay)

Changes

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"(&amp;var));
asm (".reloc ., BFD_RELOC_NONE, %p0" :: "Ws"(&amp;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 --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
+}

@@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason to choose Ws?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x86 has almost run out of uppercase and lowercase letters... The remaining ones are z and H.

I tried z but one GCC x86 maintainer considers W prefix better: https://gcc.gnu.org/pipermail/gcc-patches/2024-January/642596.html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for the link! Do we support the pointer offset like GCC &var + 1?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's supported (aarch64 "S" supports it but riscv "S" doesn't) I intend to support it for x86 "Ws".

OK, I've figured out how to do it in SelectionDAG... Updated.

Copy link
Contributor

@phoebewang phoebewang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with some nits.

@@ -130,3 +130,7 @@ void pr40890(void) {
__asm__ __volatile__("\n#define BEEF abcd%0\n" : : "n"((int*)0xdeadbeeeeeef));
#endif
}

void test_W(int i) {
asm("" : : "Wd"(test_W)); // expected-error{{invalid input constraint 'Wd' in asm}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use __asm__ for consistency?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And add a positive test?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The codegen tests asm("// %p0 %p1 %p2" :: "Ws"(&var), "Ws"(&arr[3]), "Ws"(test_Ws)); (and a struct test I am adding) provide positive tests:)

default:
return false;
case 's':
Info.setAllowsRegister();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it matters to a print constraint, should it be setAllowsMemory?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setAllowsRegister is somewhat confusing but its use is correct here (also used by aarch64/riscv S).

setAllowsMemory seems to not add extra checks.

Created using spr 1.3.4
@MaskRay MaskRay merged commit d4cb5d9 into main Jan 17, 2024
@MaskRay MaskRay deleted the users/MaskRay/spr/x86-add-ws-constraint-and-p-modifier-for-symbolic-addresslabel-reference branch January 17, 2024 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category llvm:ir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants