re PR bootstrap/49964 (Bootstrap failed with AVX turned on)
authorRichard Henderson <rth@redhat.com>
Thu, 4 Aug 2011 15:47:42 +0000 (08:47 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 4 Aug 2011 15:47:42 +0000 (08:47 -0700)
PR target/49964
        * config/i386/i386.c (ix86_expand_call): Don't create nested
        PARALLELs for TARGET_VZEROUPPER.
        (ix86_split_call_vzeroupper): Fix extraction of the original call.
        * config/i386/i386.md (*call_rex64_ms_sysv_vzeroupper): Don't
        recognize nested PARALLELs.
        (*call_pop_vzeroupper, *sibcall_pop_vzeroupper,
        *call_value_rex64_ms_sysv_vzeroupper, *call_value_pop_vzeroupper,
        *sibcall_value_pop_vzeroupper): Likewise.

From-SVN: r177408

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md

index 861320b612b293d15456ee79bd39bb03a80a46c5..7b7967755886126db851909647320a6822fc00fc 100644 (file)
@@ -1,3 +1,15 @@
+2011-08-04  Richard Henderson  <rth@redhat.com>
+
+       PR target/49964
+       * config/i386/i386.c (ix86_expand_call): Don't create nested
+       PARALLELs for TARGET_VZEROUPPER.
+       (ix86_split_call_vzeroupper): Fix extraction of the original call.
+       * config/i386/i386.md (*call_rex64_ms_sysv_vzeroupper): Don't
+       recognize nested PARALLELs.
+       (*call_pop_vzeroupper, *sibcall_pop_vzeroupper,
+       *call_value_rex64_ms_sysv_vzeroupper, *call_value_pop_vzeroupper,
+       *sibcall_value_pop_vzeroupper): Likewise.
+
 2011-08-04  Richard Henderson  <rth@redhat.com>
 
        PR middle-end/49968
index 0e4f3f46de69f1921b9a562a6e8d5490e27b5e81..a7f8ee5bdf3e92e447fe0a5f56ceb6aedaf1726a 100644 (file)
@@ -21501,7 +21501,17 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
                  rtx callarg2,
                  rtx pop, bool sibcall)
 {
+  /* We need to represent that SI and DI registers are clobbered
+     by SYSV calls.  */
+  static int clobbered_registers[] = {
+       XMM6_REG, XMM7_REG, XMM8_REG,
+       XMM9_REG, XMM10_REG, XMM11_REG,
+       XMM12_REG, XMM13_REG, XMM14_REG,
+       XMM15_REG, SI_REG, DI_REG
+  };
+  rtx vec[ARRAY_SIZE (clobbered_registers) + 3];
   rtx use = NULL, call;
+  unsigned int vec_len;
 
   if (pop == const0_rtx)
     pop = NULL;
@@ -21545,52 +21555,40 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
       fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (Pmode, fnaddr));
     }
 
+  vec_len = 0;
   call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
   if (retval)
     call = gen_rtx_SET (VOIDmode, retval, call);
+  vec[vec_len++] = call;
+
   if (pop)
     {
       pop = gen_rtx_PLUS (Pmode, stack_pointer_rtx, pop);
       pop = gen_rtx_SET (VOIDmode, stack_pointer_rtx, pop);
-      call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, pop));
+      vec[vec_len++] = pop;
     }
+
   if (TARGET_64BIT_MS_ABI
       && (!callarg2 || INTVAL (callarg2) != -2))
     {
-      /* We need to represent that SI and DI registers are clobbered
-        by SYSV calls.  */
-      static int clobbered_registers[] = {
-       XMM6_REG, XMM7_REG, XMM8_REG,
-       XMM9_REG, XMM10_REG, XMM11_REG,
-       XMM12_REG, XMM13_REG, XMM14_REG,
-       XMM15_REG, SI_REG, DI_REG
-      };
-      unsigned int i;
-      rtx vec[ARRAY_SIZE (clobbered_registers) + 2];
-      rtx unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx),
-                                  UNSPEC_MS_TO_SYSV_CALL);
+      unsigned i;
 
-      vec[0] = call;
-      vec[1] = unspec;
-      for (i = 0; i < ARRAY_SIZE (clobbered_registers); i++)
-        vec[i + 2] = gen_rtx_CLOBBER (SSE_REGNO_P (clobbered_registers[i])
-                                     ? TImode : DImode,
-                                     gen_rtx_REG
-                                       (SSE_REGNO_P (clobbered_registers[i])
-                                                     ? TImode : DImode,
-                                        clobbered_registers[i]));
+      vec[vec_len++] = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx),
+                                      UNSPEC_MS_TO_SYSV_CALL);
 
-      call = gen_rtx_PARALLEL (VOIDmode,
-                              gen_rtvec_v (ARRAY_SIZE (clobbered_registers)
-                              + 2, vec));
+      for (i = 0; i < ARRAY_SIZE (clobbered_registers); i++)
+        vec[vec_len++]
+         = gen_rtx_CLOBBER (SSE_REGNO_P (clobbered_registers[i])
+                            ? TImode : DImode,
+                            gen_rtx_REG (SSE_REGNO_P (clobbered_registers[i])
+                                         ? TImode : DImode,
+                                         clobbered_registers[i]));
     }
 
   /* Add UNSPEC_CALL_NEEDS_VZEROUPPER decoration.  */
   if (TARGET_VZEROUPPER)
     {
-      rtx unspec;
       int avx256;
-
       if (cfun->machine->callee_pass_avx256_p)
        {
          if (cfun->machine->callee_return_avx256_p)
@@ -21606,15 +21604,13 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
       if (reload_completed)
        emit_insn (gen_avx_vzeroupper (GEN_INT (avx256)));
       else
-       {
-         unspec = gen_rtx_UNSPEC (VOIDmode,
-                                  gen_rtvec (1, GEN_INT (avx256)),
-                                  UNSPEC_CALL_NEEDS_VZEROUPPER);
-         call = gen_rtx_PARALLEL (VOIDmode,
-                                  gen_rtvec (2, call, unspec));
-       }
+       vec[vec_len++] = gen_rtx_UNSPEC (VOIDmode,
+                                        gen_rtvec (1, GEN_INT (avx256)),
+                                        UNSPEC_CALL_NEEDS_VZEROUPPER);
     }
 
+  if (vec_len > 1)
+    call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (vec_len, vec));
   call = emit_call_insn (call);
   if (use)
     CALL_INSN_FUNCTION_USAGE (call) = use;
@@ -21625,9 +21621,20 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
 void
 ix86_split_call_vzeroupper (rtx insn, rtx vzeroupper)
 {
-  rtx call = XVECEXP (PATTERN (insn), 0, 0);
+  rtx pat = PATTERN (insn);
+  rtvec vec = XVEC (pat, 0);
+  int len = GET_NUM_ELEM (vec) - 1;
+
+  /* Strip off the last entry of the parallel.  */
+  gcc_assert (GET_CODE (RTVEC_ELT (vec, len)) == UNSPEC);
+  gcc_assert (XINT (RTVEC_ELT (vec, len), 1) == UNSPEC_CALL_NEEDS_VZEROUPPER);
+  if (len == 1)
+    pat = RTVEC_ELT (vec, 0);
+  else
+    pat = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (len, &RTVEC_ELT (vec, 0)));
+
   emit_insn (gen_avx_vzeroupper (vzeroupper));
-  emit_call_insn (call);
+  emit_call_insn (pat);
 }
 
 /* Output the assembly for a call instruction.  */
index 3a07d4e3c00436c775d381429178c259f54e43f5..245ee54785c03acd3bdb03c46eeba258dfa2c3eb 100644 (file)
   [(set_attr "type" "call")])
 
 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
-  [(parallel
-    [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
-          (match_operand 1 "" ""))
-     (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
-     (clobber (reg:TI XMM6_REG))
-     (clobber (reg:TI XMM7_REG))
-     (clobber (reg:TI XMM8_REG))
-     (clobber (reg:TI XMM9_REG))
-     (clobber (reg:TI XMM10_REG))
-     (clobber (reg:TI XMM11_REG))
-     (clobber (reg:TI XMM12_REG))
-     (clobber (reg:TI XMM13_REG))
-     (clobber (reg:TI XMM14_REG))
-     (clobber (reg:TI XMM15_REG))
-     (clobber (reg:DI SI_REG))
-     (clobber (reg:DI DI_REG))])
+  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
+        (match_operand 1 "" ""))
+   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
+   (clobber (reg:TI XMM6_REG))
+   (clobber (reg:TI XMM7_REG))
+   (clobber (reg:TI XMM8_REG))
+   (clobber (reg:TI XMM9_REG))
+   (clobber (reg:TI XMM10_REG))
+   (clobber (reg:TI XMM11_REG))
+   (clobber (reg:TI XMM12_REG))
+   (clobber (reg:TI XMM13_REG))
+   (clobber (reg:TI XMM14_REG))
+   (clobber (reg:TI XMM15_REG))
+   (clobber (reg:DI SI_REG))
+   (clobber (reg:DI DI_REG))
    (unspec [(match_operand 2 "const_int_operand" "")]
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
 })
 
 (define_insn_and_split "*call_pop_vzeroupper"
-  [(parallel
-    [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
-          (match_operand:SI 1 "" ""))
-     (set (reg:SI SP_REG)
-         (plus:SI (reg:SI SP_REG)
-                  (match_operand:SI 2 "immediate_operand" "i")))])
+  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
+        (match_operand:SI 1 "" ""))
+   (set (reg:SI SP_REG)
+       (plus:SI (reg:SI SP_REG)
+                (match_operand:SI 2 "immediate_operand" "i")))
    (unspec [(match_operand 3 "const_int_operand" "")]
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
   [(set_attr "type" "call")])
 
 (define_insn_and_split "*sibcall_pop_vzeroupper"
- [(parallel
-   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
-         (match_operand 1 "" ""))
-     (set (reg:SI SP_REG)
-         (plus:SI (reg:SI SP_REG)
-                  (match_operand:SI 2 "immediate_operand" "i")))])
+  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
+        (match_operand 1 "" ""))
+   (set (reg:SI SP_REG)
+       (plus:SI (reg:SI SP_REG)
+                (match_operand:SI 2 "immediate_operand" "i")))
    (unspec [(match_operand 3 "const_int_operand" "")]
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
   [(set_attr "type" "callv")])
 
 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
-  [(parallel
-    [(set (match_operand 0 "" "")
-         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
-               (match_operand 2 "" "")))
-     (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
-     (clobber (reg:TI XMM6_REG))
-     (clobber (reg:TI XMM7_REG))
-     (clobber (reg:TI XMM8_REG))
-     (clobber (reg:TI XMM9_REG))
-     (clobber (reg:TI XMM10_REG))
-     (clobber (reg:TI XMM11_REG))
-     (clobber (reg:TI XMM12_REG))
-     (clobber (reg:TI XMM13_REG))
-     (clobber (reg:TI XMM14_REG))
-     (clobber (reg:TI XMM15_REG))
-     (clobber (reg:DI SI_REG))
-     (clobber (reg:DI DI_REG))])
+  [(set (match_operand 0 "" "")
+       (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
+             (match_operand 2 "" "")))
+   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
+   (clobber (reg:TI XMM6_REG))
+   (clobber (reg:TI XMM7_REG))
+   (clobber (reg:TI XMM8_REG))
+   (clobber (reg:TI XMM9_REG))
+   (clobber (reg:TI XMM10_REG))
+   (clobber (reg:TI XMM11_REG))
+   (clobber (reg:TI XMM12_REG))
+   (clobber (reg:TI XMM13_REG))
+   (clobber (reg:TI XMM14_REG))
+   (clobber (reg:TI XMM15_REG))
+   (clobber (reg:DI SI_REG))
+   (clobber (reg:DI DI_REG))
    (unspec [(match_operand 3 "const_int_operand" "")]
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
 })
 
 (define_insn_and_split "*call_value_pop_vzeroupper"
-  [(parallel
-    [(set (match_operand 0 "" "")
-         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
-               (match_operand 2 "" "")))
-     (set (reg:SI SP_REG)
-         (plus:SI (reg:SI SP_REG)
-                  (match_operand:SI 3 "immediate_operand" "i")))])
+  [(set (match_operand 0 "" "")
+       (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
+             (match_operand 2 "" "")))
+   (set (reg:SI SP_REG)
+       (plus:SI (reg:SI SP_REG)
+                (match_operand:SI 3 "immediate_operand" "i")))
    (unspec [(match_operand 4 "const_int_operand" "")]
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
   [(set_attr "type" "callv")])
 
 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
- [(parallel
-   [(set (match_operand 0 "" "")
-         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
-               (match_operand 2 "" "")))
-     (set (reg:SI SP_REG)
-         (plus:SI (reg:SI SP_REG)
-                  (match_operand:SI 3 "immediate_operand" "i")))])
+  [(set (match_operand 0 "" "")
+       (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
+             (match_operand 2 "" "")))
+   (set (reg:SI SP_REG)
+       (plus:SI (reg:SI SP_REG)
+                (match_operand:SI 3 "immediate_operand" "i")))
    (unspec [(match_operand 4 "const_int_operand" "")]
           UNSPEC_CALL_NEEDS_VZEROUPPER)]
   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"