[committed,gcn] Fix scc clobber in movdi_symbol

Message ID 5e055469-10c1-f480-8cc3-d9a34b636abf@codesourcery.com
State New
Headers show
Series
  • [committed,gcn] Fix scc clobber in movdi_symbol
Related show

Commit Message

Andrew Stubbs March 27, 2019, 5:11 p.m.
This patch fixes a bug in which symbol load instructions created by LRA 
clobbered the SCC register, and therefore caused rare bad code bugs.

The patch now saves and restores SCC, if called during LRA. The save and 
restore instructions are later optimized away if SCC isn't actually live.

Tested for amdgcn-unknown-amdhsa with no regressions.

Andrew Stubbs
Mentor Graphics / CodeSourcery

Patch

Fix scc clobber in movdi_symbol.

2019-03-27  Andrew Stubbs  <ams@codesourcery.com>

	gcc/
	* config/gcn/gcn.md (CC_SAVE_REG): New constant.
	(movdi): Call gen_movdi_symbol_save_scc.
	(gen_movdi_symbol_save_scc): New insn and split.

diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md
index 4573a4ce32f..2b805a73c56 100644
--- a/gcc/config/gcn/gcn.md
+++ b/gcc/config/gcn/gcn.md
@@ -24,6 +24,7 @@ 
 ; Named registers
 (define_constants
   [(FIRST_SGPR_REG		 0)
+   (CC_SAVE_REG			 22)
    (LAST_SGPR_REG		 101)
    (FLAT_SCRATCH_REG		 102)
    (FLAT_SCRATCH_LO_REG		 102)
@@ -403,7 +404,10 @@ 
 	&& (GET_CODE (operands[1]) == SYMBOL_REF
 	    || GET_CODE (operands[1]) == LABEL_REF))
       {
-	emit_insn (gen_movdi_symbol (operands[0], operands[1]));
+	if (lra_in_progress)
+	  emit_insn (gen_movdi_symbol_save_scc (operands[0], operands[1]));
+	else
+	  emit_insn (gen_movdi_symbol (operands[0], operands[1]));
 	DONE;
       }
   })
@@ -826,6 +830,19 @@ 
  [(set_attr "type" "mult")
   (set_attr "length" "32")])
 
+(define_insn_and_split "movdi_symbol_save_scc"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=Sg")
+       (match_operand:DI 1 "general_operand" "Y"))
+  (clobber (reg:BI CC_SAVE_REG))]
+ "GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == LABEL_REF
+  && (lra_in_progress || reload_completed)"
+ "#"
+ "reload_completed"
+ [(set (reg:BI CC_SAVE_REG) (reg:BI SCC_REG))
+  (parallel [(set (match_dup 0) (match_dup 1))
+	     (clobber (reg:BI SCC_REG))])
+  (set (reg:BI SCC_REG) (reg:BI CC_SAVE_REG))])
+
 (define_insn "gcn_indirect_call"
   [(call (mem (match_operand:DI 0 "register_operand" "Sg"))
 	 (match_operand 1 "" ""))