re PR rtl-optimization/60501 (LRA emits add patterns which might clobber cc)

2014-03-24  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	PR rtl-optimization/60501
	* optabs.def (addptr3_optab): New optab.
	* optabs.c (gen_addptr3_insn, have_addptr3_insn): New function.
	* doc/md.texi ("addptrm3"): Document new RTL standard expander.
	* expr.h (gen_addptr3_insn, have_addptr3_insn): Add prototypes.

	* lra.c (emit_add3_insn): Use the addptr pattern if available.

	* config/s390/s390.md ("addptrdi3", "addptrsi3"): New expanders.

From-SVN: r208796
This commit is contained in:
Andreas Krebbel 2014-03-24 17:38:09 +00:00 committed by Andreas Krebbel
parent 2b2384e8c1
commit 72a4ddf2b5
7 changed files with 127 additions and 0 deletions

View File

@ -1,3 +1,15 @@
2014-03-24 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
PR rtl-optimization/60501
* optabs.def (addptr3_optab): New optab.
* optabs.c (gen_addptr3_insn, have_addptr3_insn): New function.
* doc/md.texi ("addptrm3"): Document new RTL standard expander.
* expr.h (gen_addptr3_insn, have_addptr3_insn): Add prototypes.
* lra.c (emit_add3_insn): Use the addptr pattern if available.
* config/s390/s390.md ("addptrdi3", "addptrsi3"): New expanders.
2014-03-24 Ulrich Drepper <drepper@gmail.com>
* config/i386/avx512fintrin.h: Define _mm512_set1_ps and

View File

@ -5034,6 +5034,57 @@
[(set_attr "op_type" "<RRer>,RXE")
(set_attr "type" "fsimp<mode>")])
;
; Pointer add instruction patterns
;
; This will match "*la_64"
(define_expand "addptrdi3"
[(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "nonmemory_operand" "")))]
"TARGET_64BIT"
{
HOST_WIDE_INT c = INTVAL (operands[2]);
if (GET_CODE (operands[2]) == CONST_INT)
{
if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
&& !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
{
operands[2] = force_const_mem (DImode, operands[2]);
operands[2] = force_reg (DImode, operands[2]);
}
else if (!DISP_IN_RANGE (INTVAL (operands[2])))
operands[2] = force_reg (DImode, operands[2]);
}
})
; For 31 bit we have to prevent the generated pattern from matching
; normal ADDs since la only does a 31 bit add. This is supposed to
; match "force_la_31".
(define_expand "addptrsi3"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))
(use (const_int 0))])]
"!TARGET_64BIT"
{
HOST_WIDE_INT c = INTVAL (operands[2]);
if (GET_CODE (operands[2]) == CONST_INT)
{
if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
&& !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
{
operands[2] = force_const_mem (SImode, operands[2]);
operands[2] = force_reg (SImode, operands[2]);
}
else if (!DISP_IN_RANGE (INTVAL (operands[2])))
operands[2] = force_reg (SImode, operands[2]);
}
})
;;
;;- Subtract instructions.

View File

@ -4720,6 +4720,17 @@ Add operand 2 and operand 1, storing the result in operand 0. All operands
must have mode @var{m}. This can be used even on two-address machines, by
means of constraints requiring operands 1 and 0 to be the same location.
@cindex @code{addptr@var{m}3} instruction pattern
@item @samp{addptr@var{m}3}
Like @code{add@var{m}3} but is guaranteed to only be used for address
calculations. The expanded code is not allowed to clobber the
condition code. It only needs to be defined if @code{add@var{m}3}
sets the condition code. If adds used for address calculations and
normal adds are not compatible it is required to expand a distinct
pattern (e.g. using an unspec). The pattern is used by LRA to emit
address calculations. @code{add@var{m}3} is used if
@code{addptr@var{m}3} is not defined.
@cindex @code{ssadd@var{m}3} instruction pattern
@cindex @code{usadd@var{m}3} instruction pattern
@cindex @code{sub@var{m}3} instruction pattern

View File

@ -180,10 +180,12 @@ extern void emit_libcall_block (rtx, rtx, rtx, rtx);
Likewise for subtraction and for just copying. */
extern rtx gen_add2_insn (rtx, rtx);
extern rtx gen_add3_insn (rtx, rtx, rtx);
extern rtx gen_addptr3_insn (rtx, rtx, rtx);
extern rtx gen_sub2_insn (rtx, rtx);
extern rtx gen_sub3_insn (rtx, rtx, rtx);
extern rtx gen_move_insn (rtx, rtx);
extern int have_add2_insn (rtx, rtx);
extern int have_addptr3_insn (rtx, rtx, rtx);
extern int have_sub2_insn (rtx, rtx);
/* Emit a pair of rtl insns to compare two rtx's and to jump

View File

@ -254,6 +254,19 @@ emit_add3_insn (rtx x, rtx y, rtx z)
rtx insn, last;
last = get_last_insn ();
if (have_addptr3_insn (x, y, z))
{
insn = gen_addptr3_insn (x, y, z);
/* If the target provides an "addptr" pattern it hopefully does
for a reason. So falling back to the normal add would be
a bug. */
lra_assert (insn != NULL_RTX);
emit_insn (insn);
return insn;
}
insn = emit_insn (gen_rtx_SET (VOIDmode, x,
gen_rtx_PLUS (GET_MODE (y), y, z)));
if (recog_memoized (insn) < 0)

View File

@ -4755,6 +4755,43 @@ have_add2_insn (rtx x, rtx y)
return 1;
}
/* Generate and return an insn body to add Y to X. */
rtx
gen_addptr3_insn (rtx x, rtx y, rtx z)
{
enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
gcc_assert (insn_operand_matches (icode, 0, x));
gcc_assert (insn_operand_matches (icode, 1, y));
gcc_assert (insn_operand_matches (icode, 2, z));
return GEN_FCN (icode) (x, y, z);
}
/* Return true if the target implements an addptr pattern and X, Y,
and Z are valid for the pattern predicates. */
int
have_addptr3_insn (rtx x, rtx y, rtx z)
{
enum insn_code icode;
gcc_assert (GET_MODE (x) != VOIDmode);
icode = optab_handler (addptr3_optab, GET_MODE (x));
if (icode == CODE_FOR_nothing)
return 0;
if (!insn_operand_matches (icode, 0, x)
|| !insn_operand_matches (icode, 1, y)
|| !insn_operand_matches (icode, 2, z))
return 0;
return 1;
}
/* Generate and return an insn body to subtract Y from X. */
rtx

View File

@ -191,6 +191,7 @@ OPTAB_D (addv4_optab, "addv$I$a4")
OPTAB_D (subv4_optab, "subv$I$a4")
OPTAB_D (mulv4_optab, "mulv$I$a4")
OPTAB_D (negv3_optab, "negv$I$a3")
OPTAB_D (addptr3_optab, "addptr$a3")
OPTAB_D (smul_highpart_optab, "smul$a3_highpart")
OPTAB_D (umul_highpart_optab, "umul$a3_highpart")