[arm] Cleanup dead code - old support for DImode comparisons

Now that all the major patterns for DImode have been converted to
early expansion, we can safely clean up some dead code for the old way
of handling DImode.

	* config/arm/arm-modes.def (CC_NCV, CC_CZ): Delete CC modes.
	* config/arm/arm.c (arm_select_cc_mode): Remove old selection code
	for DImode operands.
	(arm_gen_dicompare_reg): Remove unreachable expansion code.
	(maybe_get_arm_condition_code): Remove support for CC_CZmode and
	CC_NCVmode.
	* config/arm/arm.md (arm_cmpdi_insn): Delete.
	(arm_cmpdi_unsigned): Delete.

From-SVN: r277181
This commit is contained in:
Richard Earnshaw 2019-10-18 19:03:58 +00:00 committed by Richard Earnshaw
parent af74bfeee1
commit f9f6247d14
4 changed files with 12 additions and 196 deletions

View File

@ -1,3 +1,14 @@
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm-modes.def (CC_NCV, CC_CZ): Delete CC modes.
* config/arm/arm.c (arm_select_cc_mode): Remove old selection code
for DImode operands.
(arm_gen_dicompare_reg): Remove unreachable expansion code.
(maybe_get_arm_condition_code): Remove support for CC_CZmode and
CC_NCVmode.
* config/arm/arm.md (arm_cmpdi_insn): Delete.
(arm_cmpdi_unsigned): Delete.
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.c (arm_const_double_prefer_rsbs_rsc): New function.

View File

@ -36,12 +36,9 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
CC_Nmode should be used if only the N (sign) flag is set correctly
CC_NVmode should be used if only the N and V bits are set correctly,
(used for signed comparisons when the carry is propagated in).
CC_CZmode should be used if only the C and Z flags are correct
(used for DImode unsigned comparisons).
CC_RSBmode should be used where the comparison is set by an RSB immediate,
or NEG instruction. The form of the comparison for (const - reg) will
be (COMPARE (not (reg)) (~const)).
CC_NCVmode should be used if only the N, C, and V flags are correct
CC_Bmode should be used if only the C flag is correct after a subtract
(eg after an unsigned borrow with carry-in propagation).
(used for DImode signed comparisons).
@ -49,8 +46,6 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
CC_MODE (CC_NOOV);
CC_MODE (CC_Z);
CC_MODE (CC_CZ);
CC_MODE (CC_NCV);
CC_MODE (CC_NV);
CC_MODE (CC_SWP);
CC_MODE (CC_RSB);

View File

@ -15403,56 +15403,6 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
|| arm_borrow_operation (y, DImode)))
return CC_Bmode;
if (GET_MODE (x) == DImode || GET_MODE (y) == DImode)
{
switch (op)
{
case EQ:
case NE:
/* A DImode comparison against zero can be implemented by
or'ing the two halves together. We can also handle
immediates where one word of that value is zero by
subtracting the non-zero word from the corresponding word
in the other register and then ORRing it with the other
word. */
if (CONST_INT_P (y)
&& ((UINTVAL (y) & 0xffffffff) == 0
|| (UINTVAL (y) >> 32) == 0))
return CC_Zmode;
/* We can do an equality test in three Thumb instructions. */
if (!TARGET_32BIT)
return CC_Zmode;
/* FALLTHROUGH */
case LTU:
case LEU:
case GTU:
case GEU:
/* DImode unsigned comparisons can be implemented by cmp +
cmpeq without a scratch register. Not worth doing in
Thumb-2. */
if (TARGET_32BIT)
return CC_CZmode;
/* FALLTHROUGH */
case LT:
case LE:
case GT:
case GE:
/* DImode signed and unsigned comparisons can be implemented
by cmp + sbcs with a scratch register, but that does not
set the Z flag - we must reverse GT/LE/GTU/LEU. */
gcc_assert (op != EQ && op != NE);
return CC_NCVmode;
default:
gcc_unreachable ();
}
}
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
return GET_MODE (x);
@ -15673,81 +15623,8 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch)
}
default:
break;
gcc_unreachable ();
}
/* We might have X as a constant, Y as a register because of the predicates
used for cmpdi. If so, force X to a register here. */
if (!REG_P (x))
x = force_reg (DImode, x);
mode = SELECT_CC_MODE (code, x, y);
cc_reg = gen_rtx_REG (mode, CC_REGNUM);
if (mode != CC_CZmode)
{
rtx clobber, set;
/* To compare two non-zero values for equality, XOR them and
then compare against zero. Not used for ARM mode; there
CC_CZmode is cheaper. */
if (mode == CC_Zmode)
{
mode = CC_NOOVmode;
PUT_MODE (cc_reg, mode);
if (y != const0_rtx)
{
gcc_assert (CONST_INT_P (y));
rtx xlo, xhi, ylo, yhi;
arm_decompose_di_binop (x, y, &xlo, &xhi, &ylo, &yhi);
if (!scratch)
scratch = gen_reg_rtx (SImode);
if (ylo == const0_rtx)
{
yhi = gen_int_mode (-INTVAL (yhi), SImode);
if (!arm_add_operand (yhi, SImode))
yhi = force_reg (SImode, yhi);
emit_insn (gen_addsi3 (scratch, xhi, yhi));
y = xlo;
}
else
{
gcc_assert (yhi == const0_rtx);
ylo = gen_int_mode (-INTVAL (ylo), SImode);
if (!arm_add_operand (ylo, SImode))
ylo = force_reg (SImode, ylo);
emit_insn (gen_addsi3 (scratch, xlo, ylo));
y = xhi;
}
x = gen_rtx_IOR (SImode, scratch, y);
y = const0_rtx;
}
else
x = gen_rtx_IOR (SImode, gen_lowpart (SImode, x),
gen_highpart (SImode, x));
}
else if (!cmpdi_operand (y, mode))
y = force_reg (DImode, y);
/* A scratch register is required. */
if (reload_completed)
gcc_assert (scratch != NULL && GET_MODE (scratch) == SImode);
else
scratch = gen_rtx_SCRATCH (SImode);
clobber = gen_rtx_CLOBBER (VOIDmode, scratch);
set = gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y));
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber)));
}
else
{
if (!cmpdi_operand (y, mode))
y = force_reg (DImode, y);
emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y));
}
return cc_reg;
}
/* X and Y are two things to compare using CODE. Emit the compare insn and
@ -24051,28 +23928,6 @@ maybe_get_arm_condition_code (rtx comparison)
default: return ARM_NV;
}
case E_CC_CZmode:
switch (comp_code)
{
case NE: return ARM_NE;
case EQ: return ARM_EQ;
case GEU: return ARM_CS;
case GTU: return ARM_HI;
case LEU: return ARM_LS;
case LTU: return ARM_CC;
default: return ARM_NV;
}
case E_CC_NCVmode:
switch (comp_code)
{
case GE: return ARM_GE;
case LT: return ARM_LT;
case GEU: return ARM_CS;
case LTU: return ARM_CC;
default: return ARM_NV;
}
case E_CC_NVmode:
switch (comp_code)
{

View File

@ -6545,51 +6545,6 @@
(set_attr "predicable" "yes")]
)
;; DImode comparisons. The generic code generates branches that
;; if-conversion cannot reduce to a conditional compare, so we do
;; that directly.
(define_insn "*arm_cmpdi_insn"
[(set (reg:CC_NCV CC_REGNUM)
(compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
(match_operand:DI 1 "arm_di_operand" "rDi")))
(clobber (match_scratch:SI 2 "=r"))]
"TARGET_32BIT"
"cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
[(set_attr "conds" "set")
(set_attr "length" "8")
(set_attr "type" "multiple")]
)
(define_insn_and_split "*arm_cmpdi_unsigned"
[(set (reg:CC_CZ CC_REGNUM)
(compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
(match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
"TARGET_32BIT"
"#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
"&& reload_completed"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 2) (match_dup 3)))
(cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 0) (match_dup 1))))]
{
operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
if (CONST_INT_P (operands[1]))
operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
else
operands[3] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "set")
(set_attr "enabled_for_short_it" "yes,yes,no,*")
(set_attr "arch" "t2,t2,t2,a")
(set_attr "length" "6,6,10,8")
(set_attr "type" "multiple")]
)
; This insn allows redundant compares to be removed by cse, nothing should
; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
; is deleted later on. The match_dup will match the mode here, so that