[PATCH] Fix ICE with inline asm "=@cc.." (PR target/92615)

Jakub Jelinek jakub@redhat.com
Sat Nov 23 01:15:00 GMT 2019


Hi!

The following testcase ICEs, because ix86_md_asm_adjust emits an invalid
insn that isn't matched.  setcc_qi output is nonimmediate_operand and so is
fine, but the problem is if we decide to do a ZERO_EXTEND, because
zero_extendqidi2 output must be register_operand, but dest could be MEM as
in the testcase.  All other cases look ok to me, including if dest_mode is
SImode and DEST_MODE is DImode (with -m32), because we then do zero_extend
into a temporary pseudo and final extension that can cope with nonimmediate
dest, or the movstrictqi which is also into a register.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and
release branches?

2019-11-23  Jakub Jelinek  <jakub@redhat.com>

	PR target/92615
	* config/i386/i386.c (ix86_md_asm_adjust): If dest_mode is
	GET_MODE (dest), is not QImode, using ZERO_EXTEND and dest is not
	register_operand, force x into register before storing it into dest.
	Formatting fix.

	* gcc.target/i386/pr92615.c: New test.

--- gcc/config/i386/i386.c.jj	2019-11-18 12:07:54.673405114 +0100
+++ gcc/config/i386/i386.c	2019-11-22 14:43:50.895674949 +0100
@@ -20819,11 +20819,15 @@ ix86_md_asm_adjust (vec<rtx> &outputs, v
 	    {
 	      x = force_reg (dest_mode, const0_rtx);
 
-	      emit_insn (gen_movstrictqi
-			 (gen_lowpart (QImode, x), destqi));
+	      emit_insn (gen_movstrictqi (gen_lowpart (QImode, x), destqi));
 	    }
 	  else
-	    x = gen_rtx_ZERO_EXTEND (dest_mode, destqi);
+	    {
+	      x = gen_rtx_ZERO_EXTEND (dest_mode, destqi);
+	      if (dest_mode == GET_MODE (dest)
+		  && !register_operand (dest, GET_MODE (dest)))
+		x = force_reg (dest_mode, x);
+	    }
 	}
 
       if (dest_mode != GET_MODE (dest))
--- gcc/testsuite/gcc.target/i386/pr92615.c.jj	2019-11-22 14:49:35.878541378 +0100
+++ gcc/testsuite/gcc.target/i386/pr92615.c	2019-11-22 14:52:49.658658923 +0100
@@ -0,0 +1,45 @@
+/* PR target/92615 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void *a;
+long long b;
+char c;
+
+void
+foo (void)
+{
+  void *p;
+  long long q;
+  char r;
+  __asm__ ("" : : "r" (&p), "r" (&q), "r" (&r));
+  __asm__ ("" : "=@cca" (p));
+  a = p;
+  __asm__ ("" : "=@cca" (q));
+  b = q;
+  __asm__ ("" : "=@cca" (r));
+  c = r;
+  __asm__ ("" : : "r" (&p), "r" (&q), "r" (&r));
+}
+
+void
+bar (void)
+{
+  void *p;
+  long long q;
+  char r;
+  __asm__ ("" : "=@cca" (p));
+  a = p;
+  __asm__ ("" : "=@cca" (q));
+  b = q;
+  __asm__ ("" : "=@cca" (r));
+  c = r;
+  __asm__ ("" : : "r" (p), "A" (q), "q" (r));
+}
+
+void
+baz (void)
+{
+  void *p = (void *) &p;
+  __asm__ __volatile__ ("" : "=@ccng" (p) : "r" (1));
+}

	Jakub



More information about the Gcc-patches mailing list