As mentioned in bugzilla, when e.g. sel-sched queries (indirectly) before reload
some attributes like get_attr_type that depend on alternatives, GCC attempts
to constrain the operands in non-strict mode, which implies that if
reg_class_for_constraint doesn't return NO_REGS, it is ok, otherwise the
constraint needs to match (the actual code is more complex of course).
The *float<SWI48:mode><MODEF:mode>2_mixed pattern has different type
attributes between different alternatives, uses nonimmediate_operand for the
input and uses "m" constraint for it in all but one alternative; in that
alternative it has "r" constraint for the input and "Yc" for output, which
depending on tuning is either same as "v" or NO_REGS.  So, on those tunings
even in non-strict mode, if the input is a REG we fail to constrain the insn
and ICE.

The following patch fixes it by reverting the offending patch (as asked in
the PR), even with the patch reverted the reported issue doesn't reproduce
and in theory there is nothing wrong on emitting direct conversions even in
these tunings in cold blocks, the hw supports it, just it is slow, but also

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

As mentioned in the PR, another alternative that works is adding another
alternative next to that Yc <- r, e.g. !???*v <- r, which will allow the
pre-reload attribute queries, but will very likely not be used otherwise.

2018-03-13  Jakub Jelinek  <ja...@redhat.com>

        PR target/84844
        2017-04-20  Uros Bizjak  <ubiz...@gmail.com>

        PR target/78090
        * config/i386/constraints.md (Yc): New register constraint.
        * config/i386/i386.md (*float<SWI48:mode><MODEF:mode>2_mixed):
        Use Yc constraint for alternative 2 of operand 0.  Remove
        preferred_for_speed attribute.

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

--- gcc/config/i386/constraints.md.jj   2018-02-26 20:49:57.299331387 +0100
+++ gcc/config/i386/constraints.md      2018-03-13 13:47:22.285093035 +0100
@@ -99,7 +99,6 @@ (define_register_constraint "w" "TARGET_
 ;; We use the Y prefix to denote any number of conditional register sets:
 ;;  z  First SSE register.
-;;  c  SSE inter-unit conversions enabled
 ;;  i  SSE2 inter-unit moves to SSE register enabled
 ;;  j  SSE2 inter-unit moves from SSE register enabled
 ;;  d  any EVEX encodable SSE register for AVX512BW target or any SSE register
@@ -124,10 +123,6 @@ (define_register_constraint "w" "TARGET_
 (define_register_constraint "Yz" "TARGET_SSE ? SSE_FIRST_REG : NO_REGS"
  "First SSE register (@code{%xmm0}).")
-(define_register_constraint "Yc"
- "@internal Any SSE register, when SSE and inter-unit conversions are 
 (define_register_constraint "Yi"
  "@internal Any SSE register, when SSE2 and inter-unit moves to vector 
registers are enabled.")
--- gcc/config/i386/i386.md.jj  2018-03-13 13:40:44.082903460 +0100
+++ gcc/config/i386/i386.md     2018-03-13 13:47:22.284093034 +0100
@@ -5325,7 +5325,7 @@ (define_expand "float<SWI48:mode><MODEF:
 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
-  [(set (match_operand:MODEF 0 "register_operand" "=f,Yc,v")
+  [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
          (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
@@ -5354,6 +5354,10 @@ (define_insn "*float<SWI48:mode><MODEF:m
                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
+           (symbol_ref "true")))
+   (set (attr "preferred_for_speed")
+     (cond [(eq_attr "alternative" "1")
+              (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
            (symbol_ref "true")))])
 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
--- gcc/testsuite/gcc.target/i386/pr84844.c.jj  2018-03-13 13:12:50.569130703 
+++ gcc/testsuite/gcc.target/i386/pr84844.c     2018-03-13 12:21:04.553643164 
@@ -0,0 +1,10 @@
+/* PR target/84844 */
+/* { dg-do compile } */
+/* { dg-options "-march=bdver1 -O2 -fschedule-insns -fselective-scheduling" } 
+foo (int *x, int y, int z)
+  *x = y;
+  return z;


Reply via email to