[PATCH] D69876: Allow output constraints on "asm goto"

2020-02-15 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 244841.
void added a comment.
Herald added a subscriber: martong.

Typo


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/Features.def
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,38 +1,38 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
+void test1(int n) {
 // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  S s1;
 
 DirectJump:
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
+  S s2;
 // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
 // expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
 // expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
+T t;
 void *p = &
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
+asm goto("jmp %l0;" BAR);
 // expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
@@ -45,9 +45,7 @@
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int test3(int x) {
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : "=r" (x) : "m" (x) : "memory" : a);
+a:
+  return -x;
+}
+
+int test4(int x) {
+  int y;
+  if (x > 42)
+__asm__ volatile goto ("decl %0; jnz %l[a]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : a);
+  else
+__asm__ volatile goto ("decl %0; jnz %l[b]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : b);
+  x = y + 42;
+a:
+  return -x;
+b:
+  return +x;
+}
+
+int test5(void) {
   int x,cond,*e;
   // expected-error@+1 {{expected ')'}}
   asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
-  // expected-error@+1  {{'asm goto' cannot have output constraints}}
-  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
-  // expected-error@+1 {{expected identifie}}
+  // expected-error@+1 {{expected identifier}}
   asm goto ("decl %0;" :: "m"(x) : "memory" : );
   // expected-error@+1  {{expected ':'}}
   asm goto ("decl %0;" :: "m"(x) : "memory" );
@@ -26,28 +66,24 @@
   return 0;
 }
 
-
-int a, b, c, d, e, f, g, h, i, j, k, l;
-
-void
-fgoto1 (void)
-{
-  __asm__ volatile goto (""
-:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
-   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
-   [i] "r" (i), [j] "r" (j), 

[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-27 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 240720.
void added a comment.

Merge "__has_extension" patch into this patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/Features.def
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,38 +1,38 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
+void test1(int n) {
 // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  S s1;
 
 DirectJump:
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
+  S s2;
 // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
 // expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
 // expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
+T t;
 void *p = &
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
+asm goto("jmp %l0;" BAR);
 // expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
@@ -45,9 +45,7 @@
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int test3(int x) {
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : "=r" (x) : "m" (x) : "memory" : a);
+a:
+  return -x;
+}
+
+int test4(int x) {
+  int y;
+  if (x > 42)
+__asm__ volatile goto ("decl %0; jnz %l[a]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : a);
+  else
+__asm__ volatile goto ("decl %0; jnz %l[b]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : b);
+  x = y + 42;
+a:
+  return -x;
+b:
+  return +x;
+}
+
+int test5(void) {
   int x,cond,*e;
   // expected-error@+1 {{expected ')'}}
   asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
-  // expected-error@+1  {{'asm goto' cannot have output constraints}}
-  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
-  // expected-error@+1 {{expected identifie}}
+  // expected-error@+1 {{expected identifier}}
   asm goto ("decl %0;" :: "m"(x) : "memory" : );
   // expected-error@+1  {{expected ':'}}
   asm goto ("decl %0;" :: "m"(x) : "memory" );
@@ -26,28 +66,24 @@
   return 0;
 }
 
-
-int a, b, c, d, e, f, g, h, i, j, k, l;
-
-void
-fgoto1 (void)
-{
-  __asm__ volatile goto (""
-:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
-   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
-   [i] "r" (i), [j] "r" 

[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-27 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

In D69876#1843199 , @MaskRay wrote:

> Does this depend on D69868 ?


Yes. I added it as a parent.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-27 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 240692.
void added a comment.

Fix extension example, found by eagle-eye @maskray!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,38 +1,38 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
+void test1(int n) {
 // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  S s1;
 
 DirectJump:
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
+  S s2;
 // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
 // expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
 // expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
+T t;
 void *p = &
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
+asm goto("jmp %l0;" BAR);
 // expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
@@ -45,9 +45,7 @@
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int test3(int x) {
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : "=r" (x) : "m" (x) : "memory" : a);
+a:
+  return -x;
+}
+
+int test4(int x) {
+  int y;
+  if (x > 42)
+__asm__ volatile goto ("decl %0; jnz %l[a]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : a);
+  else
+__asm__ volatile goto ("decl %0; jnz %l[b]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : b);
+  x = y + 42;
+a:
+  return -x;
+b:
+  return +x;
+}
+
+int test5(void) {
   int x,cond,*e;
   // expected-error@+1 {{expected ')'}}
   asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
-  // expected-error@+1  {{'asm goto' cannot have output constraints}}
-  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
-  // expected-error@+1 {{expected identifie}}
+  // expected-error@+1 {{expected identifier}}
   asm goto ("decl %0;" :: "m"(x) : "memory" : );
   // expected-error@+1  {{expected ':'}}
   asm goto ("decl %0;" :: "m"(x) : "memory" );
@@ -26,28 +66,24 @@
   return 0;
 }
 
-
-int a, b, c, d, e, f, g, h, i, j, k, l;
-
-void
-fgoto1 (void)
-{
-  __asm__ volatile goto (""
-:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
-   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
-   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
-   

[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-27 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added a comment.

Does this depend on D69868 ?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-09 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 237223.
void added a comment.

Move plus constraints to after the label constraints.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,38 +1,38 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
+void test1(int n) {
 // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  S s1;
 
 DirectJump:
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
+  S s2;
 // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
 // expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
 // expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
+T t;
 void *p = &
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
+asm goto("jmp %l0;" BAR);
 // expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
@@ -45,9 +45,7 @@
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int test3(int x) {
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : "=r" (x) : "m" (x) : "memory" : a);
+a:
+  return -x;
+}
+
+int test4(int x) {
+  int y;
+  if (x > 42)
+__asm__ volatile goto ("decl %0; jnz %l[a]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : a);
+  else
+__asm__ volatile goto ("decl %0; jnz %l[b]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : b);
+  x = y + 42;
+a:
+  return -x;
+b:
+  return +x;
+}
+
+int test5(void) {
   int x,cond,*e;
   // expected-error@+1 {{expected ')'}}
   asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
-  // expected-error@+1  {{'asm goto' cannot have output constraints}}
-  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
-  // expected-error@+1 {{expected identifie}}
+  // expected-error@+1 {{expected identifier}}
   asm goto ("decl %0;" :: "m"(x) : "memory" : );
   // expected-error@+1  {{expected ':'}}
   asm goto ("decl %0;" :: "m"(x) : "memory" );
@@ -26,28 +66,24 @@
   return 0;
 }
 
-
-int a, b, c, d, e, f, g, h, i, j, k, l;
-
-void
-fgoto1 (void)
-{
-  __asm__ volatile goto (""
-:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
-   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
-   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
- 

[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-09 Thread Bill Wendling via Phabricator via cfe-commits
void marked an inline comment as done.
void added a comment.

In D69876#1812724 , @jyknight wrote:

> Reopening, since this didn't actually land yet. BTW, this review still has 
> the wrong contents in the latest uploaded-diff (showing llvm changes, not 
> clang changes).


*Pinches bridge of nose*
*Curses under breath*




Comment at: clang/lib/AST/Stmt.cpp:646-648
+  // Labels are placed after "InOut" operands. Adjust accordingly.
+  if (IsLabel)
+N += getNumPlusOperands();

jyknight wrote:
> void wrote:
> > jyknight wrote:
> > > I'm confused about this part. Why isn't the "N" specified in the assembly 
> > > string already the correct value for the labels? Is the ordering we use 
> > > internally and that users use externally not the same? I'm assuming your 
> > > code here is correct, just I'm not understanding, so probably an improved 
> > > comment would be nice.
> > The LLVM-specific ordering that I saw was something like:
> > 
> >   `,,, > X>,`
> > 
> > The `` is empty when there are no output constraints. 
> > This just makes up for this. It's probably better to reverse the ` > X>` and `` parts, but I didn't know how pervasive the 
> > order's assumption is in the code.
> Oh, right -- in llvm IR, the "plus" constraints don't exist -- we specify 
> those as separate-but-linked output and input constraints.
> 
> But thinking about this more...I think this code is actually incorrect. It 
> should be translating the numbers based on where it finds the matching 
> argument-number, not on the 'l' character being present. (And it should do so 
> for named-arguments too).
> 
> So, yes, I think it'd be better to just swap the order, and move the 
> plus-operand tied-inputs to the end of the arglist, where they don't affect 
> numbering. I don't _think_ reversing the order will cause other issues.
I agree that moving them would make the most sense. Let me do some experiments 
to see if it breaks anything.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-09 Thread James Y Knight via Phabricator via cfe-commits
jyknight added inline comments.



Comment at: clang/lib/AST/Stmt.cpp:646-648
+  // Labels are placed after "InOut" operands. Adjust accordingly.
+  if (IsLabel)
+N += getNumPlusOperands();

void wrote:
> jyknight wrote:
> > I'm confused about this part. Why isn't the "N" specified in the assembly 
> > string already the correct value for the labels? Is the ordering we use 
> > internally and that users use externally not the same? I'm assuming your 
> > code here is correct, just I'm not understanding, so probably an improved 
> > comment would be nice.
> The LLVM-specific ordering that I saw was something like:
> 
>   `,,, X>,`
> 
> The `` is empty when there are no output constraints. This 
> just makes up for this. It's probably better to reverse the `` 
> and `` parts, but I didn't know how pervasive the order's 
> assumption is in the code.
Oh, right -- in llvm IR, the "plus" constraints don't exist -- we specify those 
as separate-but-linked output and input constraints.

But thinking about this more...I think this code is actually incorrect. It 
should be translating the numbers based on where it finds the matching 
argument-number, not on the 'l' character being present. (And it should do so 
for named-arguments too).

So, yes, I think it'd be better to just swap the order, and move the 
plus-operand tied-inputs to the end of the arglist, where they don't affect 
numbering. I don't _think_ reversing the order will cause other issues.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-09 Thread James Y Knight via Phabricator via cfe-commits
jyknight reopened this revision.
jyknight added a comment.
This revision is now accepted and ready to land.

Reopening, since this didn't actually land yet. BTW, this review still has the 
wrong contents in the latest uploaded-diff (showing llvm changes, not clang 
changes).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D69876: Allow output constraints on "asm goto"

2020-01-07 Thread Bill Wendling via cfe-commits
Yeah. I reverted the push. The correct code should be in Phabricator now.
:-(

On Tue, Jan 7, 2020 at 2:45 PM James Y Knight via Phabricator <
revi...@reviews.llvm.org> wrote:

> jyknight added a comment.
>
> I think you pushed the incorrect change? This was the clang half, but now
> it's showing the LLVM half. Can you re-upload the diff for the clang half?
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D69876/new/
>
> https://reviews.llvm.org/D69876
>
>
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-07 Thread James Y Knight via Phabricator via cfe-commits
jyknight added a comment.

I think you pushed the incorrect change? This was the clang half, but now it's 
showing the LLVM half. Can you re-upload the diff for the clang half?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-07 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 236683.
void added a comment.

Push the correct changes to Phabricator.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,38 +1,38 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
+void test1(int n) {
 // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  S s1;
 
 DirectJump:
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
+  S s2;
 // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
 // expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
 // expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
+T t;
 void *p = &
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
+asm goto("jmp %l0;" BAR);
 // expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
@@ -45,9 +45,7 @@
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int test3(int x) {
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : "=r" (x) : "m" (x) : "memory" : a);
+a:
+  return -x;
+}
+
+int test4(int x) {
+  int y;
+  if (x > 42)
+__asm__ volatile goto ("decl %0; jnz %l[a]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : a);
+  else
+__asm__ volatile goto ("decl %0; jnz %l[b]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : b);
+  x = y + 42;
+a:
+  return -x;
+b:
+  return +x;
+}
+
+int test5(void) {
   int x,cond,*e;
   // expected-error@+1 {{expected ')'}}
   asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
-  // expected-error@+1  {{'asm goto' cannot have output constraints}}
-  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
-  // expected-error@+1 {{expected identifie}}
+  // expected-error@+1 {{expected identifier}}
   asm goto ("decl %0;" :: "m"(x) : "memory" : );
   // expected-error@+1  {{expected ':'}}
   asm goto ("decl %0;" :: "m"(x) : "memory" );
@@ -26,28 +66,24 @@
   return 0;
 }
 
-
-int a, b, c, d, e, f, g, h, i, j, k, l;
-
-void
-fgoto1 (void)
-{
-  __asm__ volatile goto (""
-:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
-   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
-   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
-

[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-07 Thread Bill Wendling via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG52366088a8e4: Allow output constraints on asm 
goto (authored by void).

Changed prior to commit:
  https://reviews.llvm.org/D69876?vs=236683=236684#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  llvm/docs/LangRef.rst
  llvm/include/llvm/CodeGen/MachineBasicBlock.h
  llvm/lib/AsmParser/LLParser.cpp
  llvm/lib/CodeGen/MachineBasicBlock.cpp
  llvm/lib/CodeGen/MachineVerifier.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/test/CodeGen/X86/callbr-asm-outputs.ll
  llvm/test/CodeGen/X86/callbr-asm.ll

Index: llvm/test/CodeGen/X86/callbr-asm.ll
===
--- llvm/test/CodeGen/X86/callbr-asm.ll
+++ llvm/test/CodeGen/X86/callbr-asm.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=i686-- -O3 | FileCheck %s
+; RUN: llc < %s -mtriple=i686-- -O3 -verify-machineinstrs | FileCheck %s
 
 ; Tests for using callbr as an asm-goto wrapper
 
@@ -159,3 +159,54 @@
 cleanup:  ; preds = %asm.fallthrough, %quux
   ret void
 }
+
+define i32 @test5(i32 %out1, i32 %out2) {
+; Test 5 - asm-goto with output constraints.
+; CHECK-LABEL: test5:
+; CHECK:   # %bb.0: # %entry
+; CHECK-NEXT:  movl $-1, %eax
+; CHECK-NEXT:  movl 4(%esp), %ecx
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  testl %ecx, %ecx
+; CHECK-NEXT:  testl %edx, %ecx
+; CHECK-NEXT:  jne .Ltmp6
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB4_1:
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  testl %ecx, %edx
+; CHECK-NEXT:  testl %ecx, %edx
+; CHECK-NEXT:  jne .Ltmp7
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB4_2:
+; CHECK-NEXT:  addl %edx, %ecx
+; CHECK-NEXT:  movl %ecx, %eax
+; CHECK-NEXT:  retl
+; CHECK-NEXT:  .Ltmp6:
+; CHECK-NEXT:  .LBB4_3:
+; CHECK-NEXT:  movl $-2, %eax
+; CHECK-NEXT:  .Ltmp7:
+; CHECK-NEXT:  .LBB4_4:
+; CHECK-NEXT:  retl
+entry:
+  %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "=r,=r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i8* blockaddress(@test5, %label_true), i8* blockaddress(@test5, %return))
+  to label %asm.fallthrough [label %label_true, label %return]
+
+asm.fallthrough:  ; preds = %entry
+  %asmresult = extractvalue { i32, i32 } %0, 0
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "=r,=r,r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %asmresult, i32 %asmresult1, i8* blockaddress(@test5, %label_true), i8* blockaddress(@test5, %return))
+  to label %asm.fallthrough2 [label %label_true, label %return]
+
+asm.fallthrough2: ; preds = %asm.fallthrough
+  %asmresult3 = extractvalue { i32, i32 } %1, 0
+  %asmresult4 = extractvalue { i32, i32 } %1, 1
+  %add = add nsw i32 %asmresult3, %asmresult4
+  br label %return
+
+label_true:   ; preds = %asm.fallthrough, %entry
+  br label %return
+
+return:   ; preds = %entry, %asm.fallthrough, %label_true, %asm.fallthrough2
+  %retval.0 = phi i32 [ %add, %asm.fallthrough2 ], [ -2, %label_true ], [ -1, %asm.fallthrough ], [ -1, %entry ]
+  ret i32 %retval.0
+}
Index: llvm/test/CodeGen/X86/callbr-asm-outputs.ll
===
--- llvm/test/CodeGen/X86/callbr-asm-outputs.ll
+++ llvm/test/CodeGen/X86/callbr-asm-outputs.ll
@@ -1,18 +1,118 @@
-; RUN: not llc -mtriple=i686-- < %s 2> %t
-; RUN: FileCheck %s < %t
+; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s
 
-; CHECK: error: asm-goto outputs not supported
+; A test for asm-goto output
 
-; A test for asm-goto output prohibition
-
-define i32 @test(i32 %a) {
+; CHECK-LABEL: test1:
+; CHECK:   movl 4(%esp), %eax
+; CHECK-NEXT:  addl $4, %eax
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  xorl %eax, %eax
+; CHECK-NEXT:  jmp .Ltmp0
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB0_1:
+; CHECK-NEXT:  retl
+; CHECK-NEXT:  .Ltmp0:
+define i32 @test1(i32 %x) {
 entry:
-  %0 = add i32 %a, 4
-  %1 = callbr i32 asm "xorl $1, $1; jmp ${1:l}", "=,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %0, i8* blockaddress(@test, %fail)) to label %normal [label %fail]
+  %add = add nsw i32 %x, 4
+  %ret = callbr i32 asm "xorl $1, $0; jmp ${2:l}", "=r,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %add, i8* blockaddress(@test1, %abnormal))
+  to label %normal [label %abnormal]
 
 normal:
-  ret i32 %1
+  ret i32 %ret
 
-fail:
+abnormal:
   ret i32 1
 }
+
+; CHECK-LABEL: test2:
+; CHECK:   # %bb.1: # %if.then
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  testl %esi, %esi
+; CHECK-NEXT:  testl 

[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-06 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 236482.
void marked 2 inline comments as done.
void added a comment.

Reword the extension explanation to be more readable.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  llvm/docs/LangRef.rst
  llvm/include/llvm/CodeGen/MachineBasicBlock.h
  llvm/lib/AsmParser/LLParser.cpp
  llvm/lib/CodeGen/MachineBasicBlock.cpp
  llvm/lib/CodeGen/MachineVerifier.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/test/CodeGen/X86/callbr-asm-outputs.ll
  llvm/test/CodeGen/X86/callbr-asm.ll

Index: llvm/test/CodeGen/X86/callbr-asm.ll
===
--- llvm/test/CodeGen/X86/callbr-asm.ll
+++ llvm/test/CodeGen/X86/callbr-asm.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=i686-- -O3 | FileCheck %s
+; RUN: llc < %s -mtriple=i686-- -O3 -verify-machineinstrs | FileCheck %s
 
 ; Tests for using callbr as an asm-goto wrapper
 
@@ -159,3 +159,54 @@
 cleanup:  ; preds = %asm.fallthrough, %quux
   ret void
 }
+
+define i32 @test5(i32 %out1, i32 %out2) {
+; Test 5 - asm-goto with output constraints.
+; CHECK-LABEL: test5:
+; CHECK:   # %bb.0: # %entry
+; CHECK-NEXT:  movl $-1, %eax
+; CHECK-NEXT:  movl 4(%esp), %ecx
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  testl %ecx, %ecx
+; CHECK-NEXT:  testl %edx, %ecx
+; CHECK-NEXT:  jne .Ltmp6
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB4_1:
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  testl %ecx, %edx
+; CHECK-NEXT:  testl %ecx, %edx
+; CHECK-NEXT:  jne .Ltmp7
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB4_2:
+; CHECK-NEXT:  addl %edx, %ecx
+; CHECK-NEXT:  movl %ecx, %eax
+; CHECK-NEXT:  retl
+; CHECK-NEXT:  .Ltmp6:
+; CHECK-NEXT:  .LBB4_3:
+; CHECK-NEXT:  movl $-2, %eax
+; CHECK-NEXT:  .Ltmp7:
+; CHECK-NEXT:  .LBB4_4:
+; CHECK-NEXT:  retl
+entry:
+  %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "=r,=r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i8* blockaddress(@test5, %label_true), i8* blockaddress(@test5, %return))
+  to label %asm.fallthrough [label %label_true, label %return]
+
+asm.fallthrough:  ; preds = %entry
+  %asmresult = extractvalue { i32, i32 } %0, 0
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "=r,=r,r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %asmresult, i32 %asmresult1, i8* blockaddress(@test5, %label_true), i8* blockaddress(@test5, %return))
+  to label %asm.fallthrough2 [label %label_true, label %return]
+
+asm.fallthrough2: ; preds = %asm.fallthrough
+  %asmresult3 = extractvalue { i32, i32 } %1, 0
+  %asmresult4 = extractvalue { i32, i32 } %1, 1
+  %add = add nsw i32 %asmresult3, %asmresult4
+  br label %return
+
+label_true:   ; preds = %asm.fallthrough, %entry
+  br label %return
+
+return:   ; preds = %entry, %asm.fallthrough, %label_true, %asm.fallthrough2
+  %retval.0 = phi i32 [ %add, %asm.fallthrough2 ], [ -2, %label_true ], [ -1, %asm.fallthrough ], [ -1, %entry ]
+  ret i32 %retval.0
+}
Index: llvm/test/CodeGen/X86/callbr-asm-outputs.ll
===
--- llvm/test/CodeGen/X86/callbr-asm-outputs.ll
+++ llvm/test/CodeGen/X86/callbr-asm-outputs.ll
@@ -1,18 +1,118 @@
-; RUN: not llc -mtriple=i686-- < %s 2> %t
-; RUN: FileCheck %s < %t
+; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s
 
-; CHECK: error: asm-goto outputs not supported
+; A test for asm-goto output
 
-; A test for asm-goto output prohibition
-
-define i32 @test(i32 %a) {
+; CHECK-LABEL: test1:
+; CHECK:   movl 4(%esp), %eax
+; CHECK-NEXT:  addl $4, %eax
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  xorl %eax, %eax
+; CHECK-NEXT:  jmp .Ltmp0
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB0_1:
+; CHECK-NEXT:  retl
+; CHECK-NEXT:  .Ltmp0:
+define i32 @test1(i32 %x) {
 entry:
-  %0 = add i32 %a, 4
-  %1 = callbr i32 asm "xorl $1, $1; jmp ${1:l}", "=,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %0, i8* blockaddress(@test, %fail)) to label %normal [label %fail]
+  %add = add nsw i32 %x, 4
+  %ret = callbr i32 asm "xorl $1, $0; jmp ${2:l}", "=r,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %add, i8* blockaddress(@test1, %abnormal))
+  to label %normal [label %abnormal]
 
 normal:
-  ret i32 %1
+  ret i32 %ret
 
-fail:
+abnormal:
   ret i32 1
 }
+
+; CHECK-LABEL: test2:
+; CHECK:   # %bb.1: # %if.then
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  testl %esi, %esi
+; CHECK-NEXT:  testl %edi, %esi
+; CHECK-NEXT:  jne .Ltmp1
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  

[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-06 Thread Bill Wendling via Phabricator via cfe-commits
void added inline comments.



Comment at: clang/lib/AST/Stmt.cpp:646-648
+  // Labels are placed after "InOut" operands. Adjust accordingly.
+  if (IsLabel)
+N += getNumPlusOperands();

jyknight wrote:
> I'm confused about this part. Why isn't the "N" specified in the assembly 
> string already the correct value for the labels? Is the ordering we use 
> internally and that users use externally not the same? I'm assuming your code 
> here is correct, just I'm not understanding, so probably an improved comment 
> would be nice.
The LLVM-specific ordering that I saw was something like:

  ``

The `` is empty when there are no output constraints. This 
just makes up for this. It's probably better to reverse the `` and 
`` parts, but I didn't know how pervasive the order's 
assumption is in the code.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-06 Thread James Y Knight via Phabricator via cfe-commits
jyknight accepted this revision.
jyknight added a comment.

LGTM modulo some minor wording.




Comment at: clang/docs/LanguageExtensions.rst:1256-1258
+Clang provides support for the `goto form of GCC's extended
+assembly`_ with output
+constraints.

I find that sentence confusing. Maybe,
"In addition to the functionality provided by , Clang 
also supports output constraints with the goto form."



Comment at: clang/lib/AST/Stmt.cpp:646-648
+  // Labels are placed after "InOut" operands. Adjust accordingly.
+  if (IsLabel)
+N += getNumPlusOperands();

I'm confused about this part. Why isn't the "N" specified in the assembly 
string already the correct value for the labels? Is the ordering we use 
internally and that users use externally not the same? I'm assuming your code 
here is correct, just I'm not understanding, so probably an improved comment 
would be nice.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2020-01-06 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers accepted this revision.
nickdesaulniers added a comment.
This revision is now accepted and ready to land.

No, thanks for the work on this @void !


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-20 Thread Bill Wendling via Phabricator via cfe-commits
void marked an inline comment as done.
void added inline comments.



Comment at: clang/test/CodeGen/asm-goto.c:91
+  return 1;
+}

nickdesaulniers wrote:
> Thanks for adding this test.  I think it doesn't test that `addr` is 
> *clobbered* though?
The `+` modifier indicates that `addr` is used for both input and output, in 
effect being clobbered. Otherwise, we would need to add a "clobber" list, but 
from what I understand that seems to be restricted to registers, memory, and 
`cc`. I wouldn't be able to specify a specific register for `addr` (e.g. 
`"+D"(addr)`) and also have `%rdx` in the clobber list.

Was there something else you were thinking of?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-20 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers added inline comments.



Comment at: clang/test/CodeGen/asm-goto.c:91
+  return 1;
+}

Thanks for adding this test.  I think it doesn't test that `addr` is 
*clobbered* though?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-20 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 234852.
void marked 5 inline comments as done.
void added a comment.

- Improve the asm goto note in the language extensions doc.

- Include another testcase.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,38 +1,38 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
+void test1(int n) {
 // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  S s1;
 
 DirectJump:
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
 // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
+  S s2;
 // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
 // expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
 // expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
+T t;
 void *p = &
 // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
+asm goto("jmp %l0;" BAR);
 // expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
@@ -45,9 +45,7 @@
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int test3(int x) {
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : "=r" (x) : "m" (x) : "memory" : a);
+a:
+  return -x;
+}
+
+int test4(int x) {
+  int y;
+  if (x > 42)
+__asm__ volatile goto ("decl %0; jnz %l[a]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : a);
+  else
+__asm__ volatile goto ("decl %0; jnz %l[b]"
+   : "=r" (x), "=r" (y) : "m" (x) : "memory" : b);
+  x = y + 42;
+a:
+  return -x;
+b:
+  return +x;
+}
+
+int test5(void) {
   int x,cond,*e;
   // expected-error@+1 {{expected ')'}}
   asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
-  // expected-error@+1  {{'asm goto' cannot have output constraints}}
-  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
-  // expected-error@+1 {{expected identifie}}
+  // expected-error@+1 {{expected identifier}}
   asm goto ("decl %0;" :: "m"(x) : "memory" : );
   // expected-error@+1  {{expected ':'}}
   asm goto ("decl %0;" :: "m"(x) : "memory" );
@@ -26,28 +66,24 @@
   return 0;
 }
 
-
-int a, b, c, d, e, f, g, h, i, j, k, l;
-
-void
-fgoto1 (void)
-{
-  __asm__ volatile goto (""
-:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
-   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" 

[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-20 Thread Bill Wendling via Phabricator via cfe-commits
void added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:1275
+It's important to note that outputs are valid only on the "fallthrough" branch.
+For example, the value assigned to `y` is not valid in the above `err` block.
+

nickdesaulniers wrote:
> Would you mind removing the `above` in this sentence. I initially parsed this 
> as `the block above err`, which is not correct.
I changed it.



Comment at: clang/test/Sema/asm-goto.cpp:35
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of 
its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to 
one of its possible targets}}

nickdesaulniers wrote:
> what's going on with the indentation?
Not sure. I blame emacs. :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-19 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

In D69876#1791989 , @nickdesaulniers 
wrote:

> In D69876#1791663 , @void wrote:
>
> > I'm not getting the `Undefined temporary symbol` in your example (even with 
> > optimizations):
> >
> >   [morbo@fawn:llvm-project] clang -o - -S ../bug.c
> >
>
>
> `-S` is going the AsmPrinter route. I observe the error with `-c`. The error 
> goes away with `-c -no-integrated-as` pointing to an issue with LLVM.


Okay. I'll check into it.

> In D69876#1791655 , @void wrote:
> 
>> In D69876#1791475 , 
>> @nickdesaulniers wrote:
>>
>> > 2. asm redirects control flow AFTER assigning to output. ie. ``` int 
>> > foo(void) { int y; asm volatile goto ("mov 42, %0; ja %l1" : "=d"(y) ::: 
>> > err); return y; err: return y; } ``` Why is this not valid in the case the 
>> > indirect branch is taken?
>>
>>
>> I'm not saying that it's *always* invalid, but we won't be able to guarantee 
>> correctness during code gen.
> 
> 
> The language added in this patch states:
> 
>> It's important to note that outputs are valid only on the "fallthrough" 
>> branch.
> 
> So maybe `only` should be replaced?  Or maybe an additional statement 
> informing the user that they must take care not to write inline assembly in 
> such a way that transfers control flow to an indirect target from the inline 
> asm, then expect to use the output?  Or states that it's explicitly undefined 
> behavior whether the output is usable after the indirect branch is taken?

I'm afraid that if we open the door for people to use outputs on indirect 
branches when it's not fully supported then we'll have to support that 
"feature" forever, when in reality it's an accident of implementation. It might 
just be best to say that it's undefined behavior.

> In D69876#1791475 , @nickdesaulniers 
> wrote:
> 
>> I need to think more about this, but I feel like people may see #2 as a 
>> reason to not use this feature and I have serious concerns about that.
> 
> 
> I tried to dig up some prior art for this.  I found two cases that I think 
> calm my concerns:
> 
> 1. GCC bugs (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59615, 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52381) particularly 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52381#c2, copied inline for 
> emphasis:
> 
>>> Note that if output was only reliable on the fall-through path, it would 
>>> already be useful.
> 
> 
> 
> 2. LKML posts (https://lkml.org/lkml/2018/2/14/625, 
> https://lkml.org/lkml/2018/2/14/656) particularly:
> 
>>> But extending on what gcc does, and allowing outputs (possibly valid
>>>  in the fall-through case only, not in the cases where it jumps away to
>>>  a label) would be a big improvement on what gcc does.
> 
> So I guess I should shelve my concerns for the minimum viable product.  It 
> might be good to reach out to luto about what that `__get_user` 
> implementation looks like, and how we might wire up support in the kernel for 
> detecting compiler support for asm goto w/ output constraints, then being 
> able to use it.  I'd be happy to help implement that.

I think clang normally uses something like `has_attribute` for things like 
this. Could you contact luto and ask for an example?

> One test I think it would be worthwhile to add here is to address the concern 
> from the description of this bug 
> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59615); ie. that an output was 
> properly clobbered.  None of the existing or added test cases seem to test 
> this.  I'd expect such a test to read from a variable, use it as an output to 
> an asm goto, then in the fallthrough use it, and we'd check that the updated 
> value was used.  But I don't see any such tests in llvm/test/...

I'll add some tests for these.

>> Note that we're not going to be able to fix all of clang's inline assembly 
>> bugs with this feature. :-)
> 
> :P


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-19 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers added a comment.

In D69876#1791663 , @void wrote:

> I'm not getting the `Undefined temporary symbol` in your example (even with 
> optimizations):
>
>   [morbo@fawn:llvm-project] clang -o - -S ../bug.c
>


`-S` is going the AsmPrinter route. I observe the error with `-c`. The error 
goes away with `-c -no-integrated-as` pointing to an issue with LLVM.

In D69876#1791655 , @void wrote:

> In D69876#1791475 , @nickdesaulniers 
> wrote:
>
> > 2. asm redirects control flow AFTER assigning to output. ie. ``` int 
> > foo(void) { int y; asm volatile goto ("mov 42, %0; ja %l1" : "=d"(y) ::: 
> > err); return y; err: return y; } ``` Why is this not valid in the case the 
> > indirect branch is taken?
>
>
> I'm not saying that it's *always* invalid, but we won't be able to guarantee 
> correctness during code gen.


The language added in this patch states:

> It's important to note that outputs are valid only on the "fallthrough" 
> branch.

So maybe `only` should be replaced?  Or maybe an additional statement informing 
the user that they must take care not to write inline assembly in such a way 
that transfers control flow to an indirect target from the inline asm, then 
expect to use the output?  Or states that it's explicitly undefined behavior 
whether the output is usable after the indirect branch is taken?

In D69876#1791475 , @nickdesaulniers 
wrote:

> I need to think more about this, but I feel like people may see #2 as a 
> reason to not use this feature and I have serious concerns about that.


I tried to dig up some prior art for this.  I found two cases that I think calm 
my concerns:

1. GCC bugs (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59615, 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52381) particularly 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52381#c2, copied inline for 
emphasis:

>> Note that if output was only reliable on the fall-through path, it would 
>> already be useful.



2. LKML posts (https://lkml.org/lkml/2018/2/14/625, 
https://lkml.org/lkml/2018/2/14/656) particularly:

>> But extending on what gcc does, and allowing outputs (possibly valid
>>  in the fall-through case only, not in the cases where it jumps away to
>>  a label) would be a big improvement on what gcc does.

So I guess I should shelve my concerns for the minimum viable product.  It 
might be good to reach out to luto about what that `__get_user` implementation 
looks like, and how we might wire up support in the kernel for detecting 
compiler support for asm goto w/ output constraints, then being able to use it. 
 I'd be happy to help implement that.

One test I think it would be worthwhile to add here is to address the concern 
from the description of this bug 
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59615); ie. that an output was 
properly clobbered.  None of the existing or added test cases seem to test 
this.  I'd expect such a test to read from a variable, use it as an output to 
an asm goto, then in the fallthrough use it, and we'd check that the updated 
value was used.  But I don't see any such tests in llvm/test/...

> Note that we're not going to be able to fix all of clang's inline assembly 
> bugs with this feature. :-)

:P




Comment at: clang/test/Sema/asm-goto.cpp:35
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of 
its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to 
one of its possible targets}}

what's going on with the indentation?



Comment at: clang/test/Sema/asm-goto.cpp:44
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
   return;

Maybe the formatting changes to the tests (that don't add new tests or 
meaningfully change existing ones) above can just be pre-committed?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-19 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

I'm not getting the `Undefined temporary symbol` in your example (even with 
optimizations):

  [morbo@fawn:llvm-project] cat ../bug.c
  void baz(void) {
  int y;
  asm volatile goto ("mov 42, %0; ja %1": "=d"(y) ::: quux);
  asm volatile goto ("mov 42, %0; ja %1": "=c"(y) ::: quux);
  return;
  quux:
  return;
  }
  [morbo@fawn:llvm-project] clang -o - -S ../bug.c
.text
.file   "bug.c"
.globl  baz # -- Begin function baz
.p2align4, 0x90
.type   baz,@function
  baz:# @baz
.cfi_startproc
  # %bb.0:# %entry
pushq   %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq%rsp, %rbp
.cfi_def_cfa_register %rbp
#APP
movl42, %edx
ja  .Ltmp00
#NO_APP
movl%edx, -8(%rbp)  # 4-byte Spill
jmp .LBB0_1
  .LBB0_1:# %asm.fallthrough
movl-8(%rbp), %eax  # 4-byte Reload
movl%eax, -4(%rbp)
#APP
movl42, %ecx
ja  .Ltmp00
#NO_APP
movl%ecx, -12(%rbp) # 4-byte Spill
jmp .LBB0_2
  .LBB0_2:# %asm.fallthrough1
movl-12(%rbp), %eax # 4-byte Reload
movl%eax, -4(%rbp)
jmp .LBB0_4
  .Ltmp0: # Block address taken
  .LBB0_3:# %quux
jmp .LBB0_4
  .LBB0_4:# %return
popq%rbp
.cfi_def_cfa %rsp, 8
retq
  .Lfunc_end0:
.size   baz, .Lfunc_end0-baz
.cfi_endproc
  # -- End function
.ident  "clang version 10.0.0 (https://github.com/llvm/llvm-project.git 
5b71b09a54edbb20900e6d13de35d2592f788330)"
.section".note.GNU-stack","",@progbits
.addrsig
.addrsig_sym baz


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-19 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

In D69876#1791475 , @nickdesaulniers 
wrote:

> Thinking hard about this, I think there's four cases we really need to think 
> hard about:
>
> 1. asm redirects control flow BEFORE assigning to output. ie.
>
>   ``` int foo(void) { int y; asm volatile goto ("ja %l1" : "=r"(y) ::: err); 
> return y; err: return y; } ```
>
>   I think we can chalk this up to user error; stupid asm in, stupid asm out.  
> If the inline asm never assigns to the output, regardless of how the assembly 
> block is exited, there's nothing we can do.  Your child patch 
> (https://reviews.llvm.org/D71314) warns in the second return, though the 
> first return is equally invalid.


Right. This is human error. Unless we can parse the inline assembly (not 
something I'm suggesting) we won't be able to help them here.

> 2. asm redirects control flow AFTER assigning to output. ie. ``` int 
> foo(void) { int y; asm volatile goto ("mov 42, %0; ja %l1" : "=d"(y) ::: 
> err); return y; err: return y; } ``` Why is this not valid in the case the 
> indirect branch is taken?

I'm not saying that it's *always* invalid, but we won't be able to guarantee 
correctness during code gen. For example, if you have something like:

  int foo(int x) {
int y;
if (x < 42)
  asm volatile goto ("mov 42, %0; ja %l1" : "=D"(y) ::: err);
else
  asm volatile goto ("mov 0, %0; ja %l1" : "=S"(y) ::: err);
return y;
  err:
return y;
  }

we can't necessarily code gen this correctly for the `err` block. There was a 
long thread on ways we could try to do this, but they were all very 
sub-standard.

> The two other cases I can think of are in regards to conflicting constraints. 
>  Consider for example the x86 machine specific output constraints 
> (https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints):
> 
> 3. shared indirect destinations with differing/conflicting constraints ``` 
> void foo(void) { int y; asm volatile ("mov 42, %0" : "=d"(y)); } void 
> bar(void) { int y; asm volatile ("mov 42, %0" : "=c"(y)); } void baz(void) { 
> int y; asm volatile goto ("mov 42, %0; ja %1": "=d"(y) ::: quux); asm 
> volatile goto ("mov 42, %0; ja %1": "=c"(y) ::: quux); return; quux: return; 
> } ``` `foo` puts `42` in `%edx`. `bar` puts `42` in `%ecx`.  Where should 
> `baz` put `42`? Your current patch set produces: `error: Undefined temporary 
> symbol`.

Whatever is done for inline assembly that's not "goto" is done here. Or at 
least should be. I'll fix the error message. But in essence it will move the 
correct value into the correct register. In this case, it should move 42 into 
both `%edx` and `%ecx`. The temporary symbol issue is most likely unrelated.

> 4. conflicts between `register` variables and output constraints. ``` void 
> foo(void) { register int y asm("edx") = 0; asm volatile goto ("mov 42, %0; ja 
> %l1" : "=c"(y) ::: bar); bar: return; } void baz(void) { register int y 
> asm("edx") = 0; asm volatile ("mov 42, %0" : "=c"(y)); } ``` The output 
> constraint for `asm goto` says put the output in `%ecx`, yet the variable was 
> declared as having register storage in `%edx`.
> 
>   Looks like Clang already has bugs or at least disagrees with GCC (for the 
> simpler case of `baz`, but the problem still exists for `foo`). Filed 
> https://bugs.llvm.org/show_bug.cgi?id=44328.
> 
>   I need to think more about this, but I feel like people may see #2 as a 
> reason to not use this feature and I have serious concerns about that.

Both functions generate the same output for me:

  foo:# @foo
.cfi_startproc
  # %bb.0:# %entry
#APP
movl42, %edx
ja  .Ltmp0
#NO_APP
  .Ltmp0: # Block address taken
  .LBB0_1:# %bar
retq
  .Lfunc_end0:
.size   foo, .Lfunc_end0-foo
.cfi_endproc
  # -- End function
.globl  baz # -- Begin function baz
.p2align4, 0x90
.type   baz,@function
  baz:# @baz
.cfi_startproc
  # %bb.0:# %entry
#APP
movl42, %edx
#NO_APP
retq

Note that we're not going to be able to fix all of clang's inline assembly bugs 
with this feature. :-)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-19 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers requested changes to this revision.
nickdesaulniers added a comment.
This revision now requires changes to proceed.

Thinking hard about this, I think there's four cases we really need to think 
hard about:

1. asm redirects control flow BEFORE assigning to output. ie.

  int foo(void) {
int y;
asm volatile goto ("ja %l1" : "=r"(y) ::: err);
return y;
  err:
return y;
  }

I think we can chalk this up to user error; stupid asm in, stupid asm out.  If 
the inline asm never assigns to the output, regardless of how the assembly 
block is exited, there's nothing we can do.  Your child patch 
(https://reviews.llvm.org/D71314) warns in the second return, though the first 
return is equally invalid.

2. asm redirects control flow AFTER assigning to output. ie.

  int foo(void) {
int y;
asm volatile goto ("mov 42, %0; ja %l1" : "=r"(y) ::: err);
return y;
  err:
return y;
  }

Why is this not valid in the case the indirect branch is taken?

The two other cases I can think of are in regards to conflicting constraints.  
Consider for example the x86 machine specific output constraints 
(https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints):

3. shared indirect destinations with differing/conflicting constraints

  void foo(void) {
  int y;
  asm volatile ("mov 42, %0" : "=d"(y));
  }
  void bar(void) {
  int y;
  asm volatile ("mov 42, %0" : "=c"(y));
  }
  void baz(void) {
  int y;
  asm volatile goto ("mov 42, %0; ja %1": "=d"(y) ::: quux);
  asm volatile goto ("mov 42, %0; ja %1": "=c"(y) ::: quux);
  return;
  quux:
  return;
  }

`foo` puts `42` in `%edx`. `bar` puts `42` in `%ecx`.  Where should `baz` put 
`42`? Your current patch set produces: `error: Undefined temporary symbol`.

4. conflicts between `register` variables and output constraints.

  void foo(void) {
  register int y asm("edx") = 0;
  asm volatile goto ("mov 42, %0; ja %l1" : "=c"(y) ::: bar);
  bar:
  return;
  }
  void baz(void) {
  register int y asm("edx") = 0;
  asm volatile ("mov 42, %0" : "=c"(y));
  }

The output constraint for `asm goto` says put the output in `%ecx`, yet the 
variable was declared as having register storage in `%edx`.

Looks like Clang already has bugs or at least disagrees with GCC (for the 
simpler case of `baz`, but the problem still exists for `foo`). Filed 
https://bugs.llvm.org/show_bug.cgi?id=44328.

I need to think more about this, but I feel like people may see #2 as a reason 
to not use this feature and I have serious concerns about that.




Comment at: clang/docs/LanguageExtensions.rst:1275
+It's important to note that outputs are valid only on the "fallthrough" branch.
+For example, the value assigned to `y` is not valid in the above `err` block.
+

Would you mind removing the `above` in this sentence. I initially parsed this 
as `the block above err`, which is not correct.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-13 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

Note to reviewers: I would *really* like to get this feature into the 10.0.0 
release. That's coming up in January. Do you think you'll have your reviews 
finished by then?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-03 Thread Bill Wendling via Phabricator via cfe-commits
void marked an inline comment as done.
void added inline comments.



Comment at: clang/test/Analysis/uninit-asm-goto.cpp:10
+return -1;
+}

rnk wrote:
> This could use a test for the case where an input is uninitialized, and where 
> an uninitialized value is used along the error path.
I have a follow-up patch that I'll upload soon that warns about uninitialized 
variable use on the indirect paths. I wanted to separate it to keep this patch 
size down. If you'd prefer I can just add it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-12-03 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a subscriber: rsmith.
rnk added a comment.

Changes seem fine to me, FWIW.
+@rsmith




Comment at: clang/test/Analysis/uninit-asm-goto.cpp:10
+return -1;
+}

This could use a test for the case where an input is uninitialized, and where 
an uninitialized value is used along the error path.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-24 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

Any further comments?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-18 Thread Bill Wendling via Phabricator via cfe-commits
void marked 2 inline comments as done.
void added inline comments.



Comment at: clang/lib/Analysis/UninitializedValues.cpp:831
+  for (auto i = as->begin_outputs(), e = as->end_outputs(); i != e; ++i)
+if (const VarDecl *VD = findVar(*i).getDecl())
+  vals[VD] = Initialized;

nickdesaulniers wrote:
> this is still not a range based for loop.
> 
> Does:
> 
> ```
> for (const auto  : as->outputs())
>   if (const VarDecl *VD = findVar(O).getDecl())
> vals[VD] = Initialized;
> ```
> not work?
Done.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-18 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 229921.
void added a comment.

Adjust loop.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,53 +1,51 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
-// expected-error@+1 {{cannot jump from this goto statement to its label}}
+void test1(int n) {
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s1;
 
 DirectJump:
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s2;
+  // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
-// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
-// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
-void *p = &
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
-// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+T t;
+void *p = &
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
 goto *p;
 return;
   }
-// expected-note@+2 {{possible target of asm goto statement}}
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
+  // expected-note@+2 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of indirect goto statement}}
+bar:
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
@@ -57,7 +55,7 @@
   return ({int a[n];label_true: 2;});
   // expected-note@+1 {{jump bypasses initialization of variable length array}}
   int b[n];
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of asm goto statement}}
 loop:
   return 0;
 }
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int 

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-18 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers added inline comments.



Comment at: clang/lib/Analysis/UninitializedValues.cpp:831
+  for (auto i = as->begin_outputs(), e = as->end_outputs(); i != e; ++i)
+if (const VarDecl *VD = findVar(*i).getDecl())
+  vals[VD] = Initialized;

this is still not a range based for loop.

Does:

```
for (const auto  : as->outputs())
  if (const VarDecl *VD = findVar(O).getDecl())
vals[VD] = Initialized;
```
not work?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-18 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

Changes made. PTAL


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-18 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 229904.
void marked 2 inline comments as done.
void added a comment.

Remove a "const_cast" and use iterators for output constraints.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,53 +1,51 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
-// expected-error@+1 {{cannot jump from this goto statement to its label}}
+void test1(int n) {
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s1;
 
 DirectJump:
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s2;
+  // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
-// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
-// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
-void *p = &
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
-// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+T t;
+void *p = &
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
 goto *p;
 return;
   }
-// expected-note@+2 {{possible target of asm goto statement}}
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
+  // expected-note@+2 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of indirect goto statement}}
+bar:
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
@@ -57,7 +55,7 @@
   return ({int a[n];label_true: 2;});
   // expected-note@+1 {{jump bypasses initialization of variable length array}}
   int b[n];
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of asm goto statement}}
 loop:
   return 0;
 }
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] 

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-18 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers added inline comments.



Comment at: clang/lib/Analysis/UninitializedValues.cpp:830
+
+  for (unsigned i = 0, e = as->getNumOutputs(); i != e; ++i) {
+FindVarResult Var = findVar(as->getOutputExpr(i));

`GCCAsmStmt` inherits from `AsmStmt` which has an `outputs()` method for 
returning an iterator. Please use that an a range based for loop.



Comment at: clang/lib/Analysis/UninitializedValues.cpp:877
+if (as->isAsmGoto())
+  tf.Visit(const_cast(as));
   return vals.updateValueVectorWithScratch(block);

Don't declare `as` as `const`, then you won't need this `const_cast`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-14 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

Friendly ping. :-)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-13 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 229166.
void added a comment.

Move adjustment before error check.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,53 +1,51 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
-// expected-error@+1 {{cannot jump from this goto statement to its label}}
+void test1(int n) {
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s1;
 
 DirectJump:
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s2;
+  // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
-// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
-// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
-void *p = &
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
-// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+T t;
+void *p = &
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
 goto *p;
 return;
   }
-// expected-note@+2 {{possible target of asm goto statement}}
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
+  // expected-note@+2 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of indirect goto statement}}
+bar:
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
@@ -57,7 +55,7 @@
   return ({int a[n];label_true: 2;});
   // expected-note@+1 {{jump bypasses initialization of variable length array}}
   int b[n];
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of asm goto statement}}
 loop:
   return 0;
 }
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-13 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 229021.
void added a comment.

Adjust label references to account for in/out constraints.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,53 +1,51 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
-// expected-error@+1 {{cannot jump from this goto statement to its label}}
+void test1(int n) {
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s1;
 
 DirectJump:
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s2;
+  // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
-// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
-// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
-void *p = &
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
-// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+T t;
+void *p = &
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
 goto *p;
 return;
   }
-// expected-note@+2 {{possible target of asm goto statement}}
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
+  // expected-note@+2 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of indirect goto statement}}
+bar:
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
@@ -57,7 +55,7 @@
   return ({int a[n];label_true: 2;});
   // expected-note@+1 {{jump bypasses initialization of variable length array}}
   int b[n];
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of asm goto statement}}
 loop:
   return 0;
 }
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+   

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 228777.
void added a comment.

Add blurb about asm goto with output constraints to the "language extensions"
documentation.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,53 +1,51 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
-// expected-error@+1 {{cannot jump from this goto statement to its label}}
+void test1(int n) {
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s1;
 
 DirectJump:
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s2;
+  // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
-// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
-// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
-void *p = &
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
-// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+T t;
+void *p = &
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
 goto *p;
 return;
   }
-// expected-note@+2 {{possible target of asm goto statement}}
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
+  // expected-note@+2 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of indirect goto statement}}
+bar:
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
@@ -57,7 +55,7 @@
   return ({int a[n];label_true: 2;});
   // expected-note@+1 {{jump bypasses initialization of variable length array}}
   int b[n];
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of asm goto statement}}
 loop:
   return 0;
 }
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" 

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 228775.
void added a comment.

the real update this time.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Analysis/uninit-asm-goto.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,53 +1,51 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
-// expected-error@+1 {{cannot jump from this goto statement to its label}}
+void test1(int n) {
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s1;
 
 DirectJump:
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s2;
+  // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
-// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
-// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
-void *p = &
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
-// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+T t;
+void *p = &
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
 goto *p;
 return;
   }
-// expected-note@+2 {{possible target of asm goto statement}}
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
+  // expected-note@+2 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of indirect goto statement}}
+bar:
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
@@ -57,7 +55,7 @@
   return ({int a[n];label_true: 2;});
   // expected-note@+1 {{jump bypasses initialization of variable length array}}
   int b[n];
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of asm goto statement}}
 loop:
   return 0;
 }
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int test3(int x) {
+  

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

In D69876#1741381 , @nickdesaulniers 
wrote:

> > Nice catch! I updated the patch with a fix. PTAL.
>
> Please add a test for that!


I did, but the "arc" program pushed the wrong change. :-( Fixed.

When are we going to use GitHub's PRs?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers added a comment.

In D69876#1741294 , @void wrote:

> In D69876#1740286 , @jyknight wrote:
>
> > I think -Wuninitialized (UninitializedValues.cpp) should be taught how to 
> > detect the use of output variables in error blocks, at least for trivial 
> > cases.
> >
> > Actually, for some reason -- it looks like the warning is failing the wrong 
> > way right now, and emits an uninitialized use warning even where there 
> > shouldn't be one.
>
>
> Nice catch! I updated the patch with a fix. PTAL.


Please add a test for that!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

In D69876#1740289 , @jyknight wrote:

> Also, since this means we are no longer simply implementing according to 
> GCC's documentation, I think this means we'll need a brand new section in the 
> Clang docs for its inline-asm support.


Sure. Which file do we list such things in?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Bill Wendling via Phabricator via cfe-commits
void added a comment.

In D69876#1740286 , @jyknight wrote:

> I think -Wuninitialized (UninitializedValues.cpp) should be taught how to 
> detect the use of output variables in error blocks, at least for trivial 
> cases.
>
> Actually, for some reason -- it looks like the warning is failing the wrong 
> way right now, and emits an uninitialized use warning even where there 
> shouldn't be one.


Nice catch! I updated the patch with a fix. PTAL.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 228762.
void added a comment.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

Analyze "asm goto" for initialized variables.

An "asm goto" statement is a terminator and thus doesn't indicate variable
assignments like normal inline assembly. Handle them specially.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  llvm/docs/LangRef.rst
  llvm/lib/AsmParser/LLParser.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/test/CodeGen/X86/callbr-asm-outputs.ll
  llvm/test/CodeGen/X86/callbr-asm.ll

Index: llvm/test/CodeGen/X86/callbr-asm.ll
===
--- llvm/test/CodeGen/X86/callbr-asm.ll
+++ llvm/test/CodeGen/X86/callbr-asm.ll
@@ -131,3 +131,54 @@
   %1 = load i32, i32* %a.addr, align 4
   ret i32 %1
 }
+
+define i32 @test4(i32 %out1, i32 %out2) {
+; Test 4 - asm-goto with output constraints.
+; CHECK-LABEL: test4:
+; CHECK:   # %bb.0: # %entry
+; CHECK-NEXT:  movl $-1, %eax
+; CHECK-NEXT:  movl 4(%esp), %ecx
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  testl %ecx, %ecx
+; CHECK-NEXT:  testl %edx, %ecx
+; CHECK-NEXT:  jne .Ltmp5
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB3_1:
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  testl %ecx, %edx
+; CHECK-NEXT:  testl %ecx, %edx
+; CHECK-NEXT:  jne .Ltmp6
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB3_2:
+; CHECK-NEXT:  addl %edx, %ecx
+; CHECK-NEXT:  movl %ecx, %eax
+; CHECK-NEXT:  retl
+; CHECK-NEXT:  .Ltmp5:
+; CHECK-NEXT:  .LBB3_3:
+; CHECK-NEXT:  movl $-2, %eax
+; CHECK-NEXT:  .Ltmp6:
+; CHECK-NEXT:  .LBB3_4:
+; CHECK-NEXT:  retl
+entry:
+  %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "=r,=r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i8* blockaddress(@test4, %label_true), i8* blockaddress(@test4, %return))
+  to label %asm.fallthrough [label %label_true, label %return]
+
+asm.fallthrough:  ; preds = %entry
+  %asmresult = extractvalue { i32, i32 } %0, 0
+  %asmresult1 = extractvalue { i32, i32 } %0, 1
+  %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "=r,=r,r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %asmresult, i32 %asmresult1, i8* blockaddress(@test4, %label_true), i8* blockaddress(@test4, %return))
+  to label %asm.fallthrough2 [label %label_true, label %return]
+
+asm.fallthrough2: ; preds = %asm.fallthrough
+  %asmresult3 = extractvalue { i32, i32 } %1, 0
+  %asmresult4 = extractvalue { i32, i32 } %1, 1
+  %add = add nsw i32 %asmresult3, %asmresult4
+  br label %return
+
+label_true:   ; preds = %asm.fallthrough, %entry
+  br label %return
+
+return:   ; preds = %entry, %asm.fallthrough, %label_true, %asm.fallthrough2
+  %retval.0 = phi i32 [ %add, %asm.fallthrough2 ], [ -2, %label_true ], [ -1, %asm.fallthrough ], [ -1, %entry ]
+  ret i32 %retval.0
+}
Index: llvm/test/CodeGen/X86/callbr-asm-outputs.ll
===
--- llvm/test/CodeGen/X86/callbr-asm-outputs.ll
+++ llvm/test/CodeGen/X86/callbr-asm-outputs.ll
@@ -1,18 +1,26 @@
-; RUN: not llc -mtriple=i686-- < %s 2> %t
-; RUN: FileCheck %s < %t
+; RUN: llc -mtriple=i686-- < %s | FileCheck %s
 
-; CHECK: error: asm-goto outputs not supported
+; A test for asm-goto output
 
-; A test for asm-goto output prohibition
-
-define i32 @test(i32 %a) {
+; CHECK-LABEL: test1:
+; CHECK:   movl 4(%esp), %eax
+; CHECK-NEXT:  addl $4, %eax
+; CHECK-NEXT:  #APP
+; CHECK-NEXT:  xorl %eax, %eax
+; CHECK-NEXT:  jmp .Ltmp0
+; CHECK-NEXT:  #NO_APP
+; CHECK-NEXT:  .LBB0_1:
+; CHECK-NEXT:  retl
+; CHECK-NEXT:  .Ltmp0:
+define i32 @test1(i32 %x) {
 entry:
-  %0 = add i32 %a, 4
-  %1 = callbr i32 asm "xorl $1, $1; jmp ${1:l}", "=,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %0, i8* blockaddress(@test, %fail)) to label %normal [label %fail]
+  %add = add nsw i32 %x, 4
+  %ret = callbr i32 asm "xorl $1, $0; jmp ${2:l}", "=r,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %add, i8* blockaddress(@test1, %abnormal))
+  to label %normal [label %abnormal]
 
 normal:
-  ret i32 %1
+  ret i32 %ret
 
-fail:
+abnormal:
   ret i32 1
 }
Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -2492,8 +2492,6 @@
 void Verifier::visitCallBrInst(CallBrInst ) {
   Assert(CBI.isInlineAsm(), "Callbr is currently only used for asm-goto!",
  );
-  Assert(CBI.getType()->isVoidTy(), "Callbr return value is not supported!",
- );
   for (unsigned i = 0, e = CBI.getNumSuccessors(); i != e; ++i)
 Assert(CBI.getSuccessor(i)->getType()->isLabelTy(),

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread James Y Knight via Phabricator via cfe-commits
jyknight added a comment.

Also, since this means we are no longer simply implementing according to GCC's 
documentation, I think this means we'll need a brand new section in the Clang 
docs for its inline-asm support.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Bill Wendling via Phabricator via cfe-commits
void marked an inline comment as done.
void added a comment.

This change is ready for review. PTAL.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread James Y Knight via Phabricator via cfe-commits
jyknight added a comment.

I think -Wuninitialized (UninitializedValues.cpp) should be taught how to 
detect the use of output variables in error blocks, at least for trivial cases.

Actually, for some reason -- it looks like the warning is failing the wrong way 
right now, and emits an uninitialized use warning even where there shouldn't be 
one.

E.g. this example should be okay:

  int foo(int x) {
int y;
asm goto("# %0 %1 %2" : "=r"(y) : "r"(x) : : err);
return y;
  err:
return -1;
  }

But now warns:

  $ clang -Wall -fsyntax-only foo.c
  foo.c:4:10: warning: variable 'y' is uninitialized when used here 
[-Wuninitialized]
return y;
   ^
  foo.c:2:8: note: initialize the variable 'y' to silence this warning
int y;
 ^
  = 0
  1 warning generated.

I'd expect a warning only if the code was modified to say "return y" in the err 
block.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-11 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 228595.
void added a comment.

Adjust the ASM so that it references labels.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,53 +1,51 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
-// expected-error@+1 {{cannot jump from this goto statement to its label}}
+void test1(int n) {
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s1;
 
 DirectJump:
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s2;
+  // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
-// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
-// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
-void *p = &
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
-// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+T t;
+void *p = &
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
 goto *p;
 return;
   }
-// expected-note@+2 {{possible target of asm goto statement}}
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
+  // expected-note@+2 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of indirect goto statement}}
+bar:
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
@@ -57,7 +55,7 @@
   return ({int a[n];label_true: 2;});
   // expected-note@+1 {{jump bypasses initialization of variable length array}}
   int b[n];
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of asm goto statement}}
 loop:
   return 0;
 }
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int test3(int x) {
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : 

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-09 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 228594.
void added a comment.

Emit asm goto fallthrough early so that any value extracts will show up in the
fallthrough block and not directly after the callbr.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69876/new/

https://reviews.llvm.org/D69876

Files:
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/CodeGen/asm-goto.c
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp
  clang/test/Sema/asm-goto.cpp

Index: clang/test/Sema/asm-goto.cpp
===
--- clang/test/Sema/asm-goto.cpp
+++ clang/test/Sema/asm-goto.cpp
@@ -1,53 +1,51 @@
 // RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
 // RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -verify -fsyntax-only
 
-struct NonTrivial {
-  ~NonTrivial();
+struct S {
+  ~S();
   int f(int);
 private:
   int k;
 };
-void JumpDiagnostics(int n) {
-// expected-error@+1 {{cannot jump from this goto statement to its label}}
+void test1(int n) {
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
   goto DirectJump;
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp1;
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s1;
 
 DirectJump:
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
   asm goto("jmp %l0;" Later);
-// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
-  NonTrivial tnp2;
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  S s2;
+  // expected-note@+1 {{possible target of asm goto statement}}
 Later:
   return;
 }
 
-struct S { ~S(); };
-void foo(int a) {
+struct T { ~T(); };
+void test2(int a) {
   if (a) {
 FOO:
-// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
-// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
-S s;
-void *p = &
-// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
-  asm goto("jmp %l0;" BAR);
-// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+T t;
+void *p = &
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" bar);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
 goto *p;
 p = &
 goto *p;
 return;
   }
-// expected-note@+2 {{possible target of asm goto statement}}
-// expected-note@+1 {{possible target of indirect goto statement}}
-BAR:
+  // expected-note@+2 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of indirect goto statement}}
+bar:
   return;
 }
 
-
-//Asm goto:
-int test16(int n)
+int test3(int n)
 {
   // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
   // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
@@ -57,7 +55,7 @@
   return ({int a[n];label_true: 2;});
   // expected-note@+1 {{jump bypasses initialization of variable length array}}
   int b[n];
-// expected-note@+1 {{possible target of asm goto statement}}
+  // expected-note@+1 {{possible target of asm goto statement}}
 loop:
   return 0;
 }
Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -1,14 +1,54 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
-int zoo ()
-{
+int a, b, c, d, e, f, g, h, i, j, k, l;
+
+void test1(void) {
+  __asm__ volatile goto (""
+:: [a] "r" (a), [b] "r" (b), [c] "r" (c), [d] "r" (d),
+   [e] "r" (e), [f] "r" (f), [g] "r" (g), [h] "r" (h),
+   [i] "r" (i), [j] "r" (j), [k] "r" (k), [l] "r" (l)
+::lab1,lab2);
+lab1: return;
+lab2: return;
+}
+
+void test2(void) {
+  __asm__ volatile goto (""
+:: [a] "r,m" (a), [b] "r,m" (b), [c] "r,m" (c), [d] "r,m" (d),
+   [e] "r,m" (e), [f] "r,m" (f), [g] "r,m" (g), [h] "r,m" (h),
+   [i] "r,m" (i), [j] "r,m" (j), [k] "r,m" (k), [l] "r,m" (l)
+:: lab);
+  lab: return;
+}
+
+int 

[PATCH] D69876: Allow output constraints on "asm goto"

2019-11-05 Thread Bill Wendling via Phabricator via cfe-commits
void created this revision.
void added reviewers: jyknight, nickdesaulniers, hfinkel.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

THIS IS A WIP!

Remove the restrictions that preventing "asm goto" from returning non-void
values. The value returned by "asm goto" is only valid on the "normal" path.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69876

Files:
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp
  clang/lib/Parse/ParseStmtAsm.cpp
  clang/lib/Sema/SemaStmtAsm.cpp
  clang/test/Parser/asm-goto.c
  clang/test/Parser/asm-goto.cpp

Index: clang/test/Parser/asm-goto.cpp
===
--- clang/test/Parser/asm-goto.cpp
+++ clang/test/Parser/asm-goto.cpp
@@ -6,9 +6,7 @@
   int x,cond,*e;
   // expected-error@+1 {{expected ')'}}
   asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
-  // expected-error@+1  {{'asm goto' cannot have output constraints}}
-  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
-  // expected-error@+1 {{expected identifie}}
+  // expected-error@+1 {{expected identifier}}
   asm goto ("decl %0;" :: "m"(x) : "memory" : );
   // expected-error@+1  {{expected ':'}}
   asm goto ("decl %0;" :: "m"(x) : "memory" );
@@ -51,3 +49,12 @@
 :: lab);
   lab: return;
 }
+
+int
+fgoto3 (int x)
+{
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : "=r" (x) : "m" (x) : "memory" : a);
+a:
+  return -x;
+}
Index: clang/test/Parser/asm-goto.c
===
--- clang/test/Parser/asm-goto.c
+++ clang/test/Parser/asm-goto.c
@@ -31,14 +31,22 @@
   lab: return;
 }
 
-int zoo ()
+int
+fgoto3 (int x)
+{
+  __asm__ volatile goto ("decl %0; jnz %l[a]"
+ : "=r" (x) : "m" (x) : "memory" : a);
+a:
+  return -x;
+}
+
+int
+zoo (void)
 {
   int x,cond,*e;
   // expected-error@+1 {{expected ')'}}
   asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
-  // expected-error@+1 {{'asm goto' cannot have output constraints}}
-  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
-  // expected-error@+1 {{expected identifie}}
+  // expected-error@+1 {{expected identifier}}
   asm goto ("decl %0;" :: "m"(x) : "memory" : );
   // expected-error@+1 {{expected ':'}}
   asm goto ("decl %0;" :: "m"(x) : "memory" );
Index: clang/lib/Sema/SemaStmtAsm.cpp
===
--- clang/lib/Sema/SemaStmtAsm.cpp
+++ clang/lib/Sema/SemaStmtAsm.cpp
@@ -473,10 +473,10 @@
 
 // Look for the correct constraint index.
 unsigned ConstraintIdx = Piece.getOperandNo();
-// Labels are the last in the Exprs list.
-if (NS->isAsmGoto() && ConstraintIdx >= NS->getNumInputs())
-  continue;
 unsigned NumOperands = NS->getNumOutputs() + NS->getNumInputs();
+// Labels are the last in the Exprs list.
+if (NS->isAsmGoto() && ConstraintIdx >= NumOperands)
+  continue;
 // Look for the (ConstraintIdx - NumOperands + 1)th constraint with
 // modifier '+'.
 if (ConstraintIdx >= NumOperands) {
Index: clang/lib/Parse/ParseStmtAsm.cpp
===
--- clang/lib/Parse/ParseStmtAsm.cpp
+++ clang/lib/Parse/ParseStmtAsm.cpp
@@ -764,12 +764,6 @@
 AteExtraColon = Tok.is(tok::coloncolon);
 ConsumeToken();
 
-if (!AteExtraColon && isGotoAsm && Tok.isNot(tok::colon)) {
-  Diag(Tok, diag::err_asm_goto_cannot_have_output);
-  SkipUntil(tok::r_paren, StopAtSemi);
-  return StmtError();
-}
-
 if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
   return StmtError();
   }
Index: clang/lib/AST/Stmt.cpp
===
--- clang/lib/AST/Stmt.cpp
+++ clang/lib/AST/Stmt.cpp
@@ -456,7 +456,7 @@
 }
 
 AddrLabelExpr *GCCAsmStmt::getLabelExpr(unsigned i) const {
-  return cast(Exprs[i + NumInputs]);
+  return cast(Exprs[i + NumOutputs + NumInputs]);
 }
 
 StringRef GCCAsmStmt::getLabelName(unsigned i) const {
@@ -522,7 +522,7 @@
 
   for (unsigned i = 0, e = getNumLabels(); i != e; ++i)
 if (getLabelName(i) == SymbolicName)
-  return i + getNumInputs();
+  return i + getNumOutputs() + getNumInputs();
 
   // Not found.
   return -1;
Index: clang/include/clang/AST/Stmt.h
===
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -3013,7 +3013,7 @@
   }
 
   IdentifierInfo *getLabelIdentifier(unsigned i) const {
-return Names[i + NumInputs];
+return Names[i + NumOutputs + NumInputs];
   }
 
   AddrLabelExpr *getLabelExpr(unsigned i) const;
@@ -3024,11 +3024,11 @@
   using labels_const_range = llvm::iterator_range;
 
   labels_iterator begin_labels() {
-return [0] + NumInputs;
+return [0] + NumOutputs + NumInputs;
   }
 
   labels_iterator end_labels() {
-return [0] + NumInputs +