* [patch,avr,4.9] Fix PR63633 ICEs for expanders colliding hard-regs
@ 2014-10-28 12:34 Georg-Johann Lay
2014-10-28 12:55 ` Georg-Johann Lay
0 siblings, 1 reply; 5+ messages in thread
From: Georg-Johann Lay @ 2014-10-28 12:34 UTC (permalink / raw)
To: GCC Patches; +Cc: Jakub Jelinek, Denis Chertykov, Jeff Law
[-- Attachment #1: Type: text/plain, Size: 1261 bytes --]
Middle-end might come up with hard registers as operands for expanders which
clobber respective hard regs. This patch uses freshly created pseudos for
respective expander operands and emits pseudo <-> hard move insn.
Ok for 4.9.2?
It's not yet for trunk because avr trunk backend is currently broken.
Johann
gcc/
PR63633
* config/avr/avr-protos.h (regmask): New inline function.
(avr_fix_inputs, avr_emit3_fix_outputs): New protos.
* config/avr/avr.c (avr_fix_operands, avr_move_fixed_operands)
(avr_fix_inputs, avr_emit3_fix_outputs): New functions.
* config/avr/avr-fixed.md (mulqq3_nomul, muluqq3_nomul)
(mul<ALL2QA>3, mul<ALL4A>3, <usdiv><ALL1Q>3, <usdiv><ALL2QA>3)
(<usdiv><ALL4A>3, round<ALL124QA>3): Fix input operands.
* config/avr/avr-dimode.md (add<ALL8>3, sub<ALL8>3)
(<ss_addsub><ALL8S>3, <us_addsub><ALL8U>3, cbranch<ALL8>4)
(<di_shifts><ALL8>3, <any_extend>mulsidi3): Fix input operands.
* config/avr/avr.md (mulqi3_call, mulhi3_call, mulsi3, mulpsi3)
(mulu<QIHI>si3, muls<QIHI>si3, mulohisi3, <any_extend>mulhisi3)
(usmulhisi3, <any_extend>mulhi3_highpart, mulsqipsi3)
(fmul, fmuls, fmulsu): Fix operands. Turn insn into expander as
needed.
gcc/testsuite/
PR63633
* gcc.target/avr/torture/pr63633-ice-mult.c: New test.
[-- Attachment #2: pr63633-mulsi-ice-2.diff --]
[-- Type: text/x-patch, Size: 19292 bytes --]
Index: testsuite/gcc.target/avr/torture/pr63633-ice-mult.c
===================================================================
--- testsuite/gcc.target/avr/torture/pr63633-ice-mult.c (revision 0)
+++ testsuite/gcc.target/avr/torture/pr63633-ice-mult.c (revision 0)
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+
+void ice_mult32 (int x)
+{
+ register long reg __asm ("22");
+ __asm volatile (" " :: "r" (reg = 0x12345 * x));
+}
+
+void ice_mult24 (int x)
+{
+ register __int24 reg __asm ("20");
+ __asm volatile (" " :: "r" (reg = 0x12345 * x));
+}
+
+void ice_sh24 (__int24 x)
+{
+ register __int24 reg __asm ("20");
+ __asm volatile (" " :: "r" (reg = x << 3));
+}
+
+void ice_sh24b (__int24 x)
+{
+ register __int24 reg __asm ("20");
+ __asm volatile (" " :: "r" (reg = x << 22));
+}
+
+void ice_s16s16 (int x)
+{
+ register long reg __asm ("20");
+ __asm volatile (" " :: "r" (reg = (long) x*x));
+}
+
+void ice_u16s16 (int x)
+{
+ register long reg __asm ("20");
+ __asm volatile (" " :: "r" (reg = (long) x*0x1234u));
+}
Index: config/avr/avr-fixed.md
===================================================================
--- config/avr/avr-fixed.md (revision 215212)
+++ config/avr/avr-fixed.md (working copy)
@@ -231,7 +231,11 @@ (define_expand "mulqq3_nomul"
(clobber (reg:HI 24))])
(set (match_operand:QQ 0 "register_operand" "")
(reg:QQ 23))]
- "!AVR_HAVE_MUL")
+ "!AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (QQmode, 24));
+ })
+
(define_expand "muluqq3_nomul"
[(set (reg:UQQ 22)
@@ -246,7 +250,10 @@ (define_expand "muluqq3_nomul"
(clobber (reg:HI 22))])
(set (match_operand:UQQ 0 "register_operand" "")
(reg:UQQ 25))]
- "!AVR_HAVE_MUL")
+ "!AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (UQQmode, 22));
+ })
(define_insn "*mulqq3.call"
[(set (reg:QQ 23)
@@ -274,7 +281,10 @@ (define_expand "mul<mode>3"
(clobber (reg:HI 22))])
(set (match_operand:ALL2QA 0 "register_operand" "")
(reg:ALL2QA 24))]
- "AVR_HAVE_MUL")
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, 18));
+ })
;; "*mulhq3.call" "*muluhq3.call"
;; "*mulha3.call" "*muluha3.call"
@@ -302,7 +312,10 @@ (define_expand "mul<mode>3"
(reg:ALL4A 20)))
(set (match_operand:ALL4A 0 "register_operand" "")
(reg:ALL4A 24))]
- "AVR_HAVE_MUL")
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, 16));
+ })
;; "*mulsa3.call" "*mulusa3.call"
(define_insn "*mul<mode>3.call"
@@ -330,7 +343,12 @@ (define_expand "<code><mode>3"
(reg:ALL1Q 22)))
(clobber (reg:QI 25))])
(set (match_operand:ALL1Q 0 "register_operand" "")
- (reg:ALL1Q 24))])
+ (reg:ALL1Q 24))]
+ ""
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, 25));
+ })
+
;; "*divqq3.call" "*udivuqq3.call"
(define_insn "*<code><mode>3.call"
@@ -356,7 +374,11 @@ (define_expand "<code><mode>3"
(clobber (reg:HI 26))
(clobber (reg:QI 21))])
(set (match_operand:ALL2QA 0 "register_operand" "")
- (reg:ALL2QA 24))])
+ (reg:ALL2QA 24))]
+ ""
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, 26));
+ })
;; "*divhq3.call" "*udivuhq3.call"
;; "*divha3.call" "*udivuha3.call"
@@ -385,7 +407,11 @@ (define_expand "<code><mode>3"
(clobber (reg:HI 26))
(clobber (reg:HI 30))])
(set (match_operand:ALL4A 0 "register_operand" "")
- (reg:ALL4A 22))])
+ (reg:ALL4A 22))]
+ ""
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, 24));
+ })
;; "*divsa3.call" "*udivusa3.call"
(define_insn "*<code><mode>3.call"
@@ -435,6 +461,7 @@ (define_expand "round<mode>3"
operands[3] = gen_rtx_REG (<MODE>mode, regno_out[(size_t) GET_MODE_SIZE (<MODE>mode)]);
operands[4] = gen_rtx_REG (<MODE>mode, regno_in[(size_t) GET_MODE_SIZE (<MODE>mode)]);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, REGNO (operands[4])));
operands[5] = simplify_gen_subreg (QImode, force_reg (HImode, operands[2]), HImode, 0);
// $2 is no more needed, but is referenced for expand.
operands[2] = const0_rtx;
Index: config/avr/avr-dimode.md
===================================================================
--- config/avr/avr-dimode.md (revision 215212)
+++ config/avr/avr-dimode.md (working copy)
@@ -68,6 +68,7 @@ (define_expand "add<mode>3"
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (DImode == <MODE>mode
@@ -145,6 +146,7 @@ (define_expand "sub<mode>3"
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (const_operand (operands[2], GET_MODE (operands[2])))
@@ -201,6 +203,7 @@ (define_expand "<code_stdname><mode>3"
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (const_operand (operands[2], GET_MODE (operands[2])))
@@ -249,6 +252,7 @@ (define_expand "<code_stdname><mode>3"
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (const_operand (operands[2], GET_MODE (operands[2])))
@@ -338,6 +342,7 @@ (define_expand "cbranch<mode>4"
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
if (s8_operand (operands[2], VOIDmode))
@@ -424,6 +429,7 @@ (define_expand "<code_stdname><mode>3"
{
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
+ avr_fix_inputs (operands, 1 << 2, regmask (<MODE>mode, ACC_A));
emit_move_insn (acc_a, operands[1]);
emit_move_insn (gen_rtx_REG (QImode, 16), operands[2]);
emit_insn (gen_<code_stdname><mode>3_insn ());
@@ -457,6 +463,7 @@ (define_expand "<extend_u>mulsidi3"
(clobber (any_extend:SI (match_dup 1)))])]
"avr_have_dimode"
{
+ avr_fix_inputs (operands, 1 << 2, regmask (SImode, 22));
emit_move_insn (gen_rtx_REG (SImode, 22), operands[1]);
emit_move_insn (gen_rtx_REG (SImode, 18), operands[2]);
emit_insn (gen_<extend_u>mulsidi3_insn());
Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md (revision 215212)
+++ config/avr/avr.md (working copy)
@@ -1482,7 +1482,11 @@ (define_expand "mulqi3_call"
(set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
(parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
(clobber (reg:QI 22))])
- (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))])
+ (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
+ ""
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
+ })
(define_insn "*mulqi3_call"
[(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
@@ -2210,7 +2214,13 @@ (define_expand "mulhi3_call"
(parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
(clobber (reg:HI 22))
(clobber (reg:QI 21))])
- (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))])
+ (set (match_operand:HI 0 "register_operand" "")
+ (reg:HI 24))]
+ ""
+ {
+ avr_fix_inputs (operands, (1 << 2), regmask (HImode, 24));
+ })
+
(define_insn "*mulhi3_call"
[(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
@@ -2248,6 +2258,10 @@ (define_expand "mulsi3"
emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
DONE;
}
+
+ if (avr_emit3_fix_outputs (gen_mulsi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
})
(define_insn_and_split "*mulsi3"
@@ -2287,7 +2301,23 @@ (define_insn_and_split "*mulsi3"
;; "muluqisi3"
;; "muluhisi3"
-(define_insn_and_split "mulu<mode>si3"
+(define_expand "mulu<mode>si3"
+ [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
+ (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
+ (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
+ (clobber (reg:HI 26))
+ (clobber (reg:DI 18))])]
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
+ if (avr_emit3_fix_outputs (gen_mulu<mode>si3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
+
+;; "*muluqisi3"
+;; "*muluhisi3"
+(define_insn_and_split "*mulu<mode>si3"
[(set (match_operand:SI 0 "pseudo_register_operand" "=r")
(mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
(match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
@@ -2323,7 +2353,23 @@ (define_insn_and_split "mulu<mode>si3"
;; "mulsqisi3"
;; "mulshisi3"
-(define_insn_and_split "muls<mode>si3"
+(define_expand "muls<mode>si3"
+ [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
+ (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
+ (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
+ (clobber (reg:HI 26))
+ (clobber (reg:DI 18))])]
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
+ if (avr_emit3_fix_outputs (gen_muls<mode>si3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
+
+;; "*mulsqisi3"
+;; "*mulshisi3"
+(define_insn_and_split "*muls<mode>si3"
[(set (match_operand:SI 0 "pseudo_register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
(match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
@@ -2366,7 +2412,22 @@ (define_insn_and_split "muls<mode>si3"
;; One-extend operand 1
-(define_insn_and_split "mulohisi3"
+(define_expand "mulohisi3"
+ [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
+ (mult:SI (not:SI (zero_extend:SI
+ (not:HI (match_operand:HI 1 "pseudo_register_operand" ""))))
+ (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
+ (clobber (reg:HI 26))
+ (clobber (reg:DI 18))])]
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
+ if (avr_emit3_fix_outputs (gen_mulohisi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
+
+(define_insn_and_split "*mulohisi3"
[(set (match_operand:SI 0 "pseudo_register_operand" "=r")
(mult:SI (not:SI (zero_extend:SI
(not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
@@ -2394,7 +2455,12 @@ (define_expand "<extend_u>mulhisi3"
(any_extend:SI (match_operand:HI 2 "register_operand" ""))))
(clobber (reg:HI 26))
(clobber (reg:DI 18))])]
- "AVR_HAVE_MUL")
+ "AVR_HAVE_MUL"
+ {
+ if (avr_emit3_fix_outputs (gen_<extend_u>mulhisi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
(define_expand "usmulhisi3"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
@@ -2402,7 +2468,12 @@ (define_expand "usmulhisi3"
(sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
(clobber (reg:HI 26))
(clobber (reg:DI 18))])]
- "AVR_HAVE_MUL")
+ "AVR_HAVE_MUL"
+ {
+ if (avr_emit3_fix_outputs (gen_usmulhisi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
@@ -2474,7 +2545,10 @@ (define_expand "<extend_su>mulhi3_highpa
(clobber (reg:HI 22))])
(set (match_operand:HI 0 "register_operand" "")
(reg:HI 24))]
- "AVR_HAVE_MUL")
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, 1 << 2, regmask (HImode, 18));
+ })
(define_insn "*mulsi3_call"
@@ -2697,6 +2771,10 @@ (define_expand "mulpsi3"
emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
DONE;
}
+
+ if (avr_emit3_fix_outputs (gen_mulpsi3, operands, 1u << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
})
(define_insn "*umulqihipsi3"
@@ -2729,7 +2807,21 @@ (define_insn "*umulhiqipsi3"
[(set_attr "length" "7")
(set_attr "cc" "clobber")])
-(define_insn_and_split "mulsqipsi3"
+(define_expand "mulsqipsi3"
+ [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
+ (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" ""))
+ (match_operand:PSI 2 "pseudo_register_or_const_int_operand""")))
+ (clobber (reg:HI 26))
+ (clobber (reg:DI 18))])]
+ "AVR_HAVE_MUL"
+ {
+ avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
+ if (avr_emit3_fix_outputs (gen_mulsqipsi3, operands, 1 << 0,
+ regmask (DImode, 18) | regmask (HImode, 26)))
+ DONE;
+ })
+
+(define_insn_and_split "*mulsqipsi3"
[(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
(mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
(match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
@@ -6064,6 +6156,7 @@ (define_expand "fmul"
emit_insn (gen_fmul_insn (operand0, operand1, operand2));
DONE;
}
+ avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
})
(define_insn "fmul_insn"
@@ -6107,6 +6200,7 @@ (define_expand "fmuls"
emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
DONE;
}
+ avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
})
(define_insn "fmuls_insn"
@@ -6150,6 +6244,7 @@ (define_expand "fmulsu"
emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
DONE;
}
+ avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
})
(define_insn "fmulsu_insn"
Index: config/avr/avr-protos.h
===================================================================
--- config/avr/avr-protos.h (revision 215212)
+++ config/avr/avr-protos.h (working copy)
@@ -124,6 +124,15 @@ extern bool avr_mem_memx_p (rtx);
extern bool avr_load_libgcc_p (rtx);
extern bool avr_xload_libgcc_p (enum machine_mode);
+static inline unsigned
+regmask (enum machine_mode mode, unsigned regno)
+{
+ return ((1u << GET_MODE_SIZE (mode)) - 1) << regno;
+}
+
+extern void avr_fix_inputs (rtx*, unsigned, unsigned);
+extern bool avr_emit3_fix_outputs (rtx (*)(rtx,rtx,rtx), rtx*, unsigned, unsigned);
+
extern rtx lpm_reg_rtx;
extern rtx lpm_addr_reg_rtx;
extern rtx tmp_reg_rtx;
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c (revision 215212)
+++ config/avr/avr.c (working copy)
@@ -11118,6 +11118,115 @@ avr_convert_to_type (tree type, tree exp
}
+/* PR63633: The middle-end might come up with hard regs as input operands.
+
+ RMASK is a bit mask representing a subset of hard registers R0...R31:
+ Rn is an element of that set iff bit n of RMASK is set.
+ OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
+ OP[n] has to be fixed; otherwise OP[n] is left alone.
+
+ For each element of OPMASK which is a hard register overlapping RMASK,
+ replace OP[n] with a newly created pseudo register
+
+ HREG == 0: Also emit a move insn that copies the contents of that
+ hard register into the new pseudo.
+
+ HREG != 0: Also set HREG[n] to the hard register. */
+
+static void
+avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask)
+{
+ for (; opmask; opmask >>= 1, op++)
+ {
+ rtx reg = *op;
+
+ if (hreg)
+ *hreg = NULL_RTX;
+
+ if ((opmask & 1)
+ && REG_P (reg)
+ && REGNO (reg) < FIRST_PSEUDO_REGISTER
+ // This hard-reg overlaps other prohibited hard regs?
+ && (rmask & regmask (GET_MODE (reg), REGNO (reg))))
+ {
+ *op = gen_reg_rtx (GET_MODE (reg));
+ if (hreg == NULL)
+ emit_move_insn (*op, reg);
+ else
+ *hreg = reg;
+ }
+
+ if (hreg)
+ hreg++;
+ }
+}
+
+
+void
+avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask)
+{
+ avr_fix_operands (op, NULL, opmask, rmask);
+}
+
+
+/* Helper for the function below: If bit n of MASK is set and
+ HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n].
+ Otherwise do nothing for that n. Return TRUE. */
+
+static bool
+avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask)
+{
+ for (; mask; mask >>= 1, op++, hreg++)
+ if ((mask & 1)
+ && *hreg)
+ emit_move_insn (*hreg, *op);
+
+ return true;
+}
+
+
+/* PR63633: The middle-end might come up with hard regs as output operands.
+
+ GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[].
+ RMASK is a bit mask representing a subset of hard registers R0...R31:
+ Rn is an element of that set iff bit n of RMASK is set.
+ OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
+ OP[n] has to be fixed; otherwise OP[n] is left alone.
+
+ Emit the insn sequence as generated by GEN() with all elements of OPMASK
+ which are hard registers overlapping RMASK replaced by newly created
+ pseudo registers. After the sequence has been emitted, emit insns that
+ move the contents of respective pseudos to their hard regs. */
+
+bool
+avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
+ unsigned opmask, unsigned rmask)
+{
+ const int n = 3;
+ rtx hreg[n];
+
+ /* It is letigimate for GEN to call this function, and in order not to
+ get self-recursive we use the following static kludge. This is the
+ only way not to duplicate all expanders and to avoid ugly and
+ hard-to-maintain C-code instead of the much more appreciated RTL
+ representation as supplied by define_expand. */
+ static bool lock = false;
+
+ gcc_assert (opmask < (1u << n));
+
+ if (lock)
+ return false;
+
+ avr_fix_operands (op, hreg, opmask, rmask);
+
+ lock = true;
+ emit_insn (gen (op[0], op[1], op[2]));
+ lock = false;
+
+ return avr_move_fixed_operands (op, hreg, opmask);
+}
+
+
/* Worker function for movmemhi expander.
XOP[0] Destination as MEM:BLK
XOP[1] Source " "
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch,avr,4.9] Fix PR63633 ICEs for expanders colliding hard-regs
2014-10-28 12:34 [patch,avr,4.9] Fix PR63633 ICEs for expanders colliding hard-regs Georg-Johann Lay
@ 2014-10-28 12:55 ` Georg-Johann Lay
2014-10-30 7:25 ` Denis Chertykov
0 siblings, 1 reply; 5+ messages in thread
From: Georg-Johann Lay @ 2014-10-28 12:55 UTC (permalink / raw)
To: GCC Patches; +Cc: Jakub Jelinek, Denis Chertykov, Jeff Law
Am 10/28/2014 01:34 PM, schrieb Georg-Johann Lay:
> Middle-end might come up with hard registers as operands for expanders which
> clobber respective hard regs. This patch uses freshly created pseudos for
> respective expander operands and emits pseudo <-> hard move insn.
>
> Ok for 4.9.2?
p.s.: testsuite passes without new regressions
> It's not yet for trunk because avr trunk backend is currently broken.
>
> Johann
>
> gcc/
> PR63633
> * config/avr/avr-protos.h (regmask): New inline function.
> (avr_fix_inputs, avr_emit3_fix_outputs): New protos.
> * config/avr/avr.c (avr_fix_operands, avr_move_fixed_operands)
> (avr_fix_inputs, avr_emit3_fix_outputs): New functions.
> * config/avr/avr-fixed.md (mulqq3_nomul, muluqq3_nomul)
> (mul<ALL2QA>3, mul<ALL4A>3, <usdiv><ALL1Q>3, <usdiv><ALL2QA>3)
> (<usdiv><ALL4A>3, round<ALL124QA>3): Fix input operands.
> * config/avr/avr-dimode.md (add<ALL8>3, sub<ALL8>3)
> (<ss_addsub><ALL8S>3, <us_addsub><ALL8U>3, cbranch<ALL8>4)
> (<di_shifts><ALL8>3, <any_extend>mulsidi3): Fix input operands.
> * config/avr/avr.md (mulqi3_call, mulhi3_call, mulsi3, mulpsi3)
> (mulu<QIHI>si3, muls<QIHI>si3, mulohisi3, <any_extend>mulhisi3)
> (usmulhisi3, <any_extend>mulhi3_highpart, mulsqipsi3)
> (fmul, fmuls, fmulsu): Fix operands. Turn insn into expander as
> needed.
>
> gcc/testsuite/
> PR63633
> * gcc.target/avr/torture/pr63633-ice-mult.c: New test.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch,avr,4.9] Fix PR63633 ICEs for expanders colliding hard-regs
2014-10-28 12:55 ` Georg-Johann Lay
@ 2014-10-30 7:25 ` Denis Chertykov
2014-10-30 11:05 ` Georg-Johann Lay
0 siblings, 1 reply; 5+ messages in thread
From: Denis Chertykov @ 2014-10-30 7:25 UTC (permalink / raw)
To: Georg-Johann Lay; +Cc: GCC Patches, Jakub Jelinek, Jeff Law
2014-10-28 15:47 GMT+03:00 Georg-Johann Lay <avr@gjlay.de>:
> Am 10/28/2014 01:34 PM, schrieb Georg-Johann Lay:
>>
>> Middle-end might come up with hard registers as operands for expanders
>> which
>> clobber respective hard regs. This patch uses freshly created pseudos for
>> respective expander operands and emits pseudo <-> hard move insn.
>>
>> Ok for 4.9.2?
>
>
Ok.
Please apply.
Denis.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch,avr,4.9] Fix PR63633 ICEs for expanders colliding hard-regs
2014-10-30 7:25 ` Denis Chertykov
@ 2014-10-30 11:05 ` Georg-Johann Lay
2014-10-30 11:11 ` Jakub Jelinek
0 siblings, 1 reply; 5+ messages in thread
From: Georg-Johann Lay @ 2014-10-30 11:05 UTC (permalink / raw)
To: Denis Chertykov; +Cc: GCC Patches, Jakub Jelinek, Jeff Law
Am 10/30/2014 07:48 AM, schrieb Denis Chertykov:
>> Am 10/28/2014 01:34 PM, schrieb Georg-Johann Lay:
>>>
>>> Middle-end might come up with hard registers as operands for expanders
>>> which
>>> clobber respective hard regs. This patch uses freshly created pseudos for
>>> respective expander operands and emits pseudo <-> hard move insn.
>>>
>>> Ok for 4.9.2?
>>
>
> Ok.
> Please apply.
>
> Denis.
I am also waiting for approval from release manager.
Johann
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch,avr,4.9] Fix PR63633 ICEs for expanders colliding hard-regs
2014-10-30 11:05 ` Georg-Johann Lay
@ 2014-10-30 11:11 ` Jakub Jelinek
0 siblings, 0 replies; 5+ messages in thread
From: Jakub Jelinek @ 2014-10-30 11:11 UTC (permalink / raw)
To: Georg-Johann Lay; +Cc: Denis Chertykov, GCC Patches, Jeff Law
On Thu, Oct 30, 2014 at 11:41:26AM +0100, Georg-Johann Lay wrote:
> Am 10/30/2014 07:48 AM, schrieb Denis Chertykov:
> >>Am 10/28/2014 01:34 PM, schrieb Georg-Johann Lay:
> >>>
> >>>Middle-end might come up with hard registers as operands for expanders
> >>>which
> >>>clobber respective hard regs. This patch uses freshly created pseudos for
> >>>respective expander operands and emits pseudo <-> hard move insn.
> >>>
> >>>Ok for 4.9.2?
> >>
> >
> >Ok.
> >Please apply.
> >
> >Denis.
>
> I am also waiting for approval from release manager.
Too late, it has been already released. The branch is open again, you don't
need any RM approval now.
Jakub
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-10-30 10:52 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-28 12:34 [patch,avr,4.9] Fix PR63633 ICEs for expanders colliding hard-regs Georg-Johann Lay
2014-10-28 12:55 ` Georg-Johann Lay
2014-10-30 7:25 ` Denis Chertykov
2014-10-30 11:05 ` Georg-Johann Lay
2014-10-30 11:11 ` Jakub Jelinek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).