[llvm-bugs] [Bug 48605] New: Clang considers extended asm empty input constraint to be invalid

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Dec 27 04:16:46 PST 2020


https://bugs.llvm.org/show_bug.cgi?id=48605

            Bug ID: 48605
           Summary: Clang considers extended asm empty input constraint to
                    be invalid
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: nsajko at gmail.com
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org,
                    neeilans at live.com, richard-llvm at metafoo.co.uk

The issue is that Clang does not accept the GCC extended asm empty input
constraint, giving the error "error: invalid input constraint '' in asm".

Note that https://clang.llvm.org/compatibility.html#inline-asm says that all
constraints allowed by GCC are also allowed by Clang:

> In general, Clang is highly compatible with the GCC inline assembly extensions, allowing the same set of constraints, modifiers and operands as GCC inline assembly.

The use case for this feature is when the user wants to prevent the compiler
from optimizing away a piece of code (the relevant asm declaration effectively
pretends to be a live store), but without causing unnecessary additional code
generation. This is desirable in, e.g., benchmarking and testing.

The following code should illustrate the issue and the desired behavior:

> #include <vector>
>
> int
> main() {
>       // Greater than or equal to zero.
>       constexpr int asmV = ASM_V;
>
>       std::vector<char> v{7, 6, 9, 3, 2, 0};
>       for (int i{0}; i < (1 << 28); i++) {
>               for (int j{0}; j < 6; j++) {
>                       v[j]++;
>
>                       if constexpr (1 <= asmV) {
>                               asm volatile ("" :: ""(v.size()));
>                               for (auto x: v) {
>                                       asm volatile ("" :: ""(x));
>                               }
>                       }
>                       if constexpr (2 <= asmV) {
>                               asm volatile ("" :: ""(v.size()));
>                               for (auto x: v) {
>                                       asm volatile ("" :: ""(x));
>                               }
>                       }
>                       if constexpr (3 <= asmV) {
>                               asm volatile ("" :: ""(v.size()));
>                               for (auto x: v) {
>                                       asm volatile ("" :: ""(x));
>                               }
>                       }
>               }
>       }
>
>       return 0;
> }

Built with (try replacing "=0" with "=1", "=2", "=3":

> clang++ clang++ -std=c++20 -D ASM_V=0 asm.cc

This is the Radare2 graph view of the disassembly for the main function with
ASM_V defined as 1, 2 or 3:

[0x00001050]> 0x1050 # int main (int argc, char **argv, char **envp);
  ┌─────────────────────────────────────────────────────┐
  │ [0x1050]                                            │
  │ ; [13] -r-x section size 517 named .text            │
  │   ; DATA XREF from entry0 @ 0x1101                  │
  │   ;-- section..text:                                │
  │   ;-- .text:                                        │
  │ 129: int main (int argc, char **argv, char **envp); │
  │ movl $6, %edi                                       │
  │ subq $8, %rsp                                       │
  │ callq sym operator new(unsigned long);[oa]          │
  │ ; [0x3090607:4]=-1                                  │
  │ movl $0x3090607, (%rax)                             │
  │ movq %rax, %r9                                      │
  │ movl $2, %eax                                       │
  │ movw %ax, 4(%r9)                                    │
  │ movl $0x10000000, %r10d                             │
  │ movl $6, %r8d                                       │
  │ movl $9, %edi                                       │
  │ movl $3, %esi                                       │
  │ movl $2, %ecx                                       │
  │ xorl %edx, %edx                                     │
  │ nop                                                 │
  └─────────────────────────────────────────────────────┘
      v
      │
      └──────────────────────┐
                             │
                             │
                             │
                  ┌──────────┘
┌───────────────────┐
│                 │ │
│           ┌────────────────────────────────┐
│           │  0x1090 [oc]                   │
│           │ ; CODE XREF from main @ 0x10bb │
│           │ movzbl (%r9), %eax             │
│           │ incl %eax                      │
│           │ movb %al, (%r9)                │
│           │ incl %r8d                      │
│           │ movb %r8b, 1(%r9)              │
│           │ incl %edi                      │
│           │ movb %dil, 2(%r9)              │
│           │ incl %esi                      │
│           │ movb %sil, 3(%r9)              │
│           │ incl %ecx                      │
│           │ movb %cl, 4(%r9)               │
│           │ incl %edx                      │
│           │ movb %dl, 5(%r9)               │
│           │ decl %r10d                     │
│           │ jne 0x1090                     │
│           └────────────────────────────────┘
│                   f t
│                   │ │
└─────────────────────┘
     ┌──────────────┘
     │
 ┌──────────────────────────────────────────────────────┐
 │  0x10bd [oe]                                         │
 │ movl $6, %esi                                        │
 │ movq %r9, %rdi                                       │
 │ callq sym operator delete(void*, unsigned long);[od] │
 │ xorl %eax, %eax                                      │
 │ addq $8, %rsp                                        │
 │ retq                                                 │
 └──────────────────────────────────────────────────────┘

This is the main function with ASM_V defined as 0, notice how the loop is gone:

[0x00001050]> 0x1050 # int main (int argc, char **argv, char **envp);
 ┌──────────────────────────────────────────────────────┐
 │ [0x1050]                                             │
 │ ; [13] -r-x section size 437 named .text             │
 │   ; DATA XREF from entry0 @ 0x10b1                   │
 │   ;-- section..text:                                 │
 │   ;-- .text:                                         │
 │ 49: int main (int argc, char **argv, char **envp);   │
 │ subq $8, %rsp                                        │
 │ movl $6, %edi                                        │
 │ callq sym operator new(unsigned long);[oa]           │
 │ ; [0x3090607:4]=-1                                   │
 │ movl $0x3090607, (%rax)                              │
 │ movq %rax, %rdi                                      │
 │ movl $2, %eax                                        │
 │ movw %ax, 4(%rdi)                                    │
 │ movl $6, %esi                                        │
 │ callq sym operator delete(void*, unsigned long);[ob] │
 │ xorl %eax, %eax                                      │
 │ addq $8, %rsp                                        │
 │ retq                                                 │
 └──────────────────────────────────────────────────────┘

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201227/6574e531/attachment-0001.html>


More information about the llvm-bugs mailing list