This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR 27528: Expanding constant asm operands


PR 27528 is about things like:

    asm volatile ("..." :: "i" ("String"));

not working with -fsection-anchors.  We emit code to load "String"
using section anchors, but the constraint needs a symbolic constant.

I think this is a bug in the asm expansion code.  It expands all
non-memory constraints using EXPAND_NORMAL, which gives expand_expr
no clue as to whether a constant is needed or not.  The patch below
uses EXPAND_INITIALIZER instead if the constraint doesn't allow
memories or registers.

Note that EXPAND_INITIALIZER doesn't actually cause non-initialisers
to be rejected, so we still deal gracefully with bogus code like:

   int x;
   asm volatile ("..." :: "i" (x));

(It might even be possible to pass EXPAND_INITIALIZER if allows_reg,
but that seems conceptually wrong, even if it does happen to work.)

Patch bootstrapped & regression-tested on x86_64-linux-gnu and
powerpc64-linux-gnu.  It fixes the c-torture case for the latter.
I also regression-tested on mips64-linux-gnu.  I then reverted
the recent inline changes and built a mips64-linux-gnu sysroot
(including glibc).  I also built a 64-bit MIPS linux kernel.

I've included a gcc.dg warning & error test.  This test passes before
and after the patch; it's there to check that the patch doesn't cause
a diagnostic regression for the tested cases.

OK for trunk and 4.2?

Richard


gcc/
	PR middle-end/27528
	* stmt.c (expand_asm_operands): Use EXPAND_INITIALIZER if the
	constraints accept neither registers or memories.

gcc/testsuite/
	PR middle-end/27528
	* gcc.c-torture/compile/pr27528.c: New test.
	* gcc.dg/pr27528.c: Likewise.

Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c	(revision 118576)
+++ gcc/stmt.c	(working copy)
@@ -886,8 +886,9 @@ expand_asm_operands (tree string, tree o
       val = TREE_VALUE (tail);
       type = TREE_TYPE (val);
       op = expand_expr (val, NULL_RTX, VOIDmode,
-			(allows_mem && !allows_reg
-			 ? EXPAND_MEMORY : EXPAND_NORMAL));
+			allows_reg ? EXPAND_NORMAL
+			: allows_mem ? EXPAND_MEMORY
+			: EXPAND_INITIALIZER);
 
       /* Never pass a CONCAT to an ASM.  */
       if (GET_CODE (op) == CONCAT)
Index: gcc/testsuite/gcc.c-torture/compile/pr27528.c
===================================================================
--- gcc/testsuite/gcc.c-torture/compile/pr27528.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr27528.c	(revision 0)
@@ -0,0 +1,9 @@
+int x[2] = { 1, 2 };
+void
+foo (void)
+{
+  asm volatile ("# %0 %1" :: "s" (x), "i" (x));
+  asm volatile ("# %0 %1" :: "s" ("string"), "i" ("string"));
+  asm volatile ("# %0 %1" :: "s" (__FILE__), "i" (__FILE__));
+  asm volatile ("# %0 %1" :: "s" (__FUNCTION__), "i" (__FUNCTION__));
+}
Index: gcc/testsuite/gcc.dg/pr27528.c
===================================================================
--- gcc/testsuite/gcc.dg/pr27528.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr27528.c	(revision 0)
@@ -0,0 +1,18 @@
+/* Check the warnings and errors generated for asm operands that aren't
+   obviously constant but that are constrained to be constants.  */
+/* { dg-options "" } */
+/* { dg-error "impossible constraint" "" { target *-*-* } 13 } */
+/* { dg-error "impossible constraint" "" { target *-*-* } 14 } */
+/* { dg-error "impossible constraint" "" { target *-*-* } 15 } */
+/* { dg-error "impossible constraint" "" { target *-*-* } 16 } */
+int bar (int);
+void
+foo (int *x, int y)
+{
+  int constant = 0;
+  asm ("# %0" :: "i" (x)); /* { dg-warning "probably doesn't match" } */
+  asm ("# %0" :: "i" (bar (*x))); /* { dg-warning "probably doesn't match" } */
+  asm ("# %0" :: "i" (*x + 0x11)); /* { dg-warning "probably doesn't match" } */
+  asm ("# %0" :: "i" (constant)); /* { dg-warning "probably doesn't match" } */
+  asm ("# %0" :: "i" (y * 0)); /* folded */
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]