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]

[patch] current_insn_predicate vs. inline asm


The Arm port uses %? in format strings to generate mnemonic suffixes for 
conditionally executed instructions. These expand to different things 
depending on the value of current_insn_predicate.

It turns out that there's a fair amount of kernel code that includes %? in 
inline assembly fragments. This is arguably a bug in the kernel. However, 
given gcc never conditionaly executes inline asm it's not entirely 
unreasonable to expect this to "work". i.e. should expand to the 
unconditional form.

Currently final_scan_insn doesn't set current_insn_predicate until after asm 
fragments have been output. This means inline asm incorrectly inherits its 
conditionalness from the previous insn.

The attached patch resets current_insn_predicate earlier, so inline asm output 
is unconditional. It fixes an arm-linux kernel miscompilation.

Tested with cross to arm-none-eabi.
Ok for mainline and 4.1?

Paul

2006-08-09  Paul Brook  <paul@codesourcery.com>

	gcc/
	* final.c (final_scan_insn): Clear current_insn_predicate before
	outputting inline asm.

	gcc/testsuite/
	* gcc.target/arm/cond-asm.c: New test.
Index: gcc/final.c
===================================================================
--- gcc/final.c	(revision 116034)
+++ gcc/final.c	(working copy)
@@ -1985,6 +1985,10 @@ final_scan_insn (rtx insn, FILE *file, i
 	int insn_code_number;
 	const char *template;
 
+#ifdef HAVE_conditional_execution
+	/* Reset this early so it is correct for ASM statements.  */
+	current_insn_predicate = NULL_RTX;
+#endif
 	/* An INSN, JUMP_INSN or CALL_INSN.
 	   First check for special kinds that recog doesn't recognize.  */
 
@@ -2419,8 +2423,6 @@ final_scan_insn (rtx insn, FILE *file, i
 #ifdef HAVE_conditional_execution
 	if (GET_CODE (PATTERN (insn)) == COND_EXEC)
 	  current_insn_predicate = COND_EXEC_TEST (PATTERN (insn));
-	else
-	  current_insn_predicate = NULL_RTX;
 #endif
 
 #ifdef HAVE_cc0
Index: gcc/testsuite/gcc.target/arm/cond-asm.c
===================================================================
--- gcc/testsuite/gcc.target/arm/cond-asm.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/cond-asm.c	(revision 0)
@@ -0,0 +1,13 @@
+/* Check that %? in inline asm expands to nothing.  */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target arm32 } */
+int b;
+int foo(int a)
+{
+  if (a)
+    b = 42;
+  asm ("test%?me":"=r"(a):"0"(a));
+  return a;
+}
+/* { dg-final { scan-assembler "testme" } } */

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