[committed,amdgcn] Fix issue with '0' constraints

Message ID faa5c8c6-1fcf-4b47-f617-394cba429ad8@codesourcery.com
State New
Headers show
Series
  • [committed,amdgcn] Fix issue with '0' constraints
Related show

Commit Message

Andrew Stubbs Jan. 6, 2020, 5:18 p.m.
This patch fixes a wrong-code bug that can occur with subv64di3.

The pattern uses '0' constraints to override the early-clobber modifier, 
meaning that the output can be in the same register as one of the 
inputs, whilst still disallowing overlapping pairs of registers (which 
are the real problem).

The problem was that, in GCC 9, it used to be possible to have a '0' in 
all the operands and have it match just one of them, but now it ends up 
forcing *all* the inputs to match, resulting in wrong code. (It's 
possible that this never gave the benefits intended, but just didn't 
produce bad code?)

Adding an alternatives for each permutation fixes the problem. This has 
already been done for many other patterns.

Andrew

Patch

Fix amdgcn issue with '0' constraints

2020-01-06  Andrew Stubbs  <ams@codesourcery.com>

	gcc/
	* config/gcn/gcn-valu.md (subv64di3): Use separate alternatives for
	'0' matching inputs.
	(subv64di3_exec): Likewise.

diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index 9baef24b1c8..e301a4356ec 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -1292,10 +1292,10 @@ 
    (set_attr "length" "8")])
 
 (define_insn_and_split "subv64di3"
-  [(set (match_operand:V64DI 0 "register_operand"  "=  &v,   &v")
-	(minus:V64DI
-	  (match_operand:V64DI 1 "gcn_alu_operand" "vSvB0,   v0")
-	  (match_operand:V64DI 2 "gcn_alu_operand" "   v0,vSvB0")))
+  [(set (match_operand:V64DI 0 "register_operand"  "= &v,   &v,   &v,  &v")
+	(minus:V64DI                                                 
+	  (match_operand:V64DI 1 "gcn_alu_operand" "vSvB,vSvB0,    v,  v0")
+	  (match_operand:V64DI 2 "gcn_alu_operand" "  v0,    v,vSvB0,vSvB")))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
@@ -1318,17 +1318,17 @@ 
     DONE;
   }
   [(set_attr "type" "vmult")
-   (set_attr "length" "8,8")])
+   (set_attr "length" "8")])
 
 (define_insn_and_split "subv64di3_exec"
-  [(set (match_operand:V64DI 0 "register_operand"	       "=  &v,   &v")
-	(vec_merge:V64DI
-	  (minus:V64DI
-	    (match_operand:V64DI 1 "gcn_alu_operand"	       "vSvB0,   v0")
-	    (match_operand:V64DI 2 "gcn_alu_operand"	       "   v0,vSvB0"))
+  [(set (match_operand:V64DI 0 "register_operand"    "= &v,   &v,   &v,  &v")
+	(vec_merge:V64DI                                                         
+	  (minus:V64DI                                                           
+	    (match_operand:V64DI 1 "gcn_alu_operand" "vSvB,vSvB0,    v,  v0")
+	    (match_operand:V64DI 2 "gcn_alu_operand" "  v0,    v,vSvB0,vSvB"))
 	  (match_operand:V64DI 3 "gcn_register_or_unspec_operand"
-							       "   U0,   U0")
-	  (match_operand:DI 4 "gcn_exec_reg_operand"	       "    e,    e")))
+						     "  U0,   U0,   U0,  U0")
+	  (match_operand:DI 4 "gcn_exec_reg_operand" "   e,    e,    e,   e")))
    (clobber (reg:DI VCC_REG))]
   "register_operand (operands[1], VOIDmode)
    || register_operand (operands[2], VOIDmode)"
@@ -1357,7 +1357,7 @@ 
     DONE;
   }
   [(set_attr "type" "vmult")
-   (set_attr "length" "8,8")])
+   (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_dup"
   [(set (match_operand:V64DI 0 "register_operand"   "= &v")