Commit e4c6a07a by Bernd Schmidt Committed by Bernd Schmidt

re PR tree-optimization/42172 (inefficient bit fields assignments)

	PR target/42172
	* config/arm/arm.c (thumb1_rtx_costs): Improve support for SIGN_EXTEND
	and ZERO_EXTEND.
	(arm_rtx_costs_1): Likewise.
	(arm_size_rtx_costs): Use arm_rtx_costs_1 for these codes.
	* config/arm/arm.md (is_arch6): New attribute.
	(zero_extendhisi2, zero_extendqisi2, extendhisi2,
	extendqisi2): Tighten the code somewhat, avoiding invalid
	RTL to occur in the expander patterns.
	(thumb1_zero_extendhisi2): Merge with thumb1_zero_extendhisi2_v6.
	(thumb1_zero_extendhisi2_v6): Delete.
	(thumb1_extendhisi2): Merge with thumb1_extendhisi2_v6.
	(thumb1_extendhisi2_v6): Delete.
	(thumb1_extendqisi2): Merge with thumb1_extendhisi2_v6.
	(thumb1_extendqisi2_v6): Delete.
	(zero_extendhisi2 for register input splitter): New.
	(zero_extendqisi2 for register input splitter): New.
	(thumb1_extendhisi2 for register input splitter): New.
	(extendhisi2 for register input splitter): New.
	(extendqisi2 for register input splitter): New.
	(TARGET_THUMB1 extendqisi2 for memory input splitter): New.
	(arm_zero_extendhisi2): Allow nonimmediate_operand for operand 1,
	and add support for a register alternative requiring a split.
	(thumb1_zero_extendqisi2): Likewise.
	(arm_zero_extendqisi2): Likewise.
	(arm_extendhisi2): Likewise.
	(arm_extendqisi2): Likewise.

testsuite/
	PR target/42172
	* gcc.target/arm/pr42172-1.c: New test.

From-SVN: r161726
parent 18e8200f
...@@ -8,6 +8,34 @@ ...@@ -8,6 +8,34 @@
(compare_scc): Now a define_and_split. Add a number of extra (compare_scc): Now a define_and_split. Add a number of extra
splitters before it. splitters before it.
PR target/42172
* config/arm/arm.c (thumb1_rtx_costs): Improve support for SIGN_EXTEND
and ZERO_EXTEND.
(arm_rtx_costs_1): Likewise.
(arm_size_rtx_costs): Use arm_rtx_costs_1 for these codes.
* config/arm/arm.md (is_arch6): New attribute.
(zero_extendhisi2, zero_extendqisi2, extendhisi2,
extendqisi2): Tighten the code somewhat, avoiding invalid
RTL to occur in the expander patterns.
(thumb1_zero_extendhisi2): Merge with thumb1_zero_extendhisi2_v6.
(thumb1_zero_extendhisi2_v6): Delete.
(thumb1_extendhisi2): Merge with thumb1_extendhisi2_v6.
(thumb1_extendhisi2_v6): Delete.
(thumb1_extendqisi2): Merge with thumb1_extendhisi2_v6.
(thumb1_extendqisi2_v6): Delete.
(zero_extendhisi2 for register input splitter): New.
(zero_extendqisi2 for register input splitter): New.
(thumb1_extendhisi2 for register input splitter): New.
(extendhisi2 for register input splitter): New.
(extendqisi2 for register input splitter): New.
(TARGET_THUMB1 extendqisi2 for memory input splitter): New.
(arm_zero_extendhisi2): Allow nonimmediate_operand for operand 1,
and add support for a register alternative requiring a split.
(thumb1_zero_extendqisi2): Likewise.
(arm_zero_extendqisi2): Likewise.
(arm_extendhisi2): Likewise.
(arm_extendqisi2): Likewise.
2010-07-02 Sandra Loosemore <sandra@codesourcery.com> 2010-07-02 Sandra Loosemore <sandra@codesourcery.com>
* config/arm/arm.c (neon_vdup_constant): Expand into canonical RTL * config/arm/arm.c (neon_vdup_constant): Expand into canonical RTL
......
...@@ -6214,6 +6214,7 @@ static inline int ...@@ -6214,6 +6214,7 @@ static inline int
thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer) thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
{ {
enum machine_mode mode = GET_MODE (x); enum machine_mode mode = GET_MODE (x);
int total;
switch (code) switch (code)
{ {
...@@ -6312,24 +6313,20 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer) ...@@ -6312,24 +6313,20 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
return 14; return 14;
return 2; return 2;
case SIGN_EXTEND:
case ZERO_EXTEND: case ZERO_EXTEND:
/* XXX still guessing. */ total = mode == DImode ? COSTS_N_INSNS (1) : 0;
switch (GET_MODE (XEXP (x, 0))) total += thumb1_rtx_costs (XEXP (x, 0), GET_CODE (XEXP (x, 0)), code);
{
case QImode:
return (1 + (mode == DImode ? 4 : 0)
+ (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
case HImode: if (mode == SImode)
return (4 + (mode == DImode ? 4 : 0) return total;
+ (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
case SImode: if (arm_arch6)
return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0)); return total + COSTS_N_INSNS (1);
default: /* Assume a two-shift sequence. Increase the cost slightly so
return 99; we prefer actual shifts over an extend operation. */
} return total + 1 + COSTS_N_INSNS (2);
default: default:
return 99; return 99;
...@@ -6798,44 +6795,39 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) ...@@ -6798,44 +6795,39 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
return false; return false;
case SIGN_EXTEND: case SIGN_EXTEND:
if (GET_MODE_CLASS (mode) == MODE_INT)
{
*total = 0;
if (mode == DImode)
*total += COSTS_N_INSNS (1);
if (GET_MODE (XEXP (x, 0)) != SImode)
{
if (arm_arch6)
{
if (GET_CODE (XEXP (x, 0)) != MEM)
*total += COSTS_N_INSNS (1);
}
else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
*total += COSTS_N_INSNS (2);
}
return false;
}
/* Fall through */
case ZERO_EXTEND: case ZERO_EXTEND:
*total = 0; *total = 0;
if (GET_MODE_CLASS (mode) == MODE_INT) if (GET_MODE_CLASS (mode) == MODE_INT)
{ {
rtx op = XEXP (x, 0);
enum machine_mode opmode = GET_MODE (op);
if (mode == DImode) if (mode == DImode)
*total += COSTS_N_INSNS (1); *total += COSTS_N_INSNS (1);
if (GET_MODE (XEXP (x, 0)) != SImode) if (opmode != SImode)
{ {
if (arm_arch6) if (MEM_P (op))
{ {
if (GET_CODE (XEXP (x, 0)) != MEM) /* If !arm_arch4, we use one of the extendhisi2_mem
*total += COSTS_N_INSNS (1); or movhi_bytes patterns for HImode. For a QImode
sign extension, we first zero-extend from memory
and then perform a shift sequence. */
if (!arm_arch4 && (opmode != QImode || code == SIGN_EXTEND))
*total += COSTS_N_INSNS (2);
} }
else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM) else if (arm_arch6)
*total += COSTS_N_INSNS (GET_MODE (XEXP (x, 0)) == QImode ? *total += COSTS_N_INSNS (1);
1 : 2);
/* We don't have the necessary insn, so we need to perform some
other operation. */
else if (TARGET_ARM && code == ZERO_EXTEND && mode == QImode)
/* An and with constant 255. */
*total += COSTS_N_INSNS (1);
else
/* A shift sequence. Increase costs slightly to avoid
combining two shifts into an extend operation. */
*total += COSTS_N_INSNS (2) + 1;
} }
return false; return false;
...@@ -7191,41 +7183,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, ...@@ -7191,41 +7183,8 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
return false; return false;
case SIGN_EXTEND: case SIGN_EXTEND:
*total = 0;
if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) < 4)
{
if (!(arm_arch4 && MEM_P (XEXP (x, 0))))
*total += COSTS_N_INSNS (arm_arch6 ? 1 : 2);
}
if (mode == DImode)
*total += COSTS_N_INSNS (1);
return false;
case ZERO_EXTEND: case ZERO_EXTEND:
*total = 0; return arm_rtx_costs_1 (x, outer_code, total, 0);
if (!(arm_arch4 && MEM_P (XEXP (x, 0))))
{
switch (GET_MODE (XEXP (x, 0)))
{
case QImode:
*total += COSTS_N_INSNS (1);
break;
case HImode:
*total += COSTS_N_INSNS (arm_arch6 ? 1 : 2);
case SImode:
break;
default:
*total += COSTS_N_INSNS (2);
}
}
if (mode == DImode)
*total += COSTS_N_INSNS (1);
return false;
case CONST_INT: case CONST_INT:
if (const_ok_for_arm (INTVAL (x))) if (const_ok_for_arm (INTVAL (x)))
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
PR target/42835 PR target/42835
* gcc.target/arm/pr42835.c: New test. * gcc.target/arm/pr42835.c: New test.
PR target/42172
* gcc.target/arm/pr42172-1.c: New test.
2010-07-02 Paolo Carlini <paolo.carlini@oracle.com> 2010-07-02 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/template/crash98.C: Remove stray // from dg-error comment. * g++.dg/template/crash98.C: Remove stray // from dg-error comment.
......
/* { dg-options "-O2" } */
struct A {
unsigned int f1 : 3;
unsigned int f2 : 3;
unsigned int f3 : 1;
unsigned int f4 : 1;
};
void init_A (struct A *this)
{
this->f1 = 0;
this->f2 = 1;
this->f3 = 0;
this->f4 = 0;
}
/* { dg-final { scan-assembler-times "ldr" 1 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment