Optimise NotDI AND/OR ZeroExtendSI for ARMv7A

[gcc]
	* config/arm/arm.md (*anddi_notdi_zesidi): New pattern.
	* config/arm/thumb2.md (*iordi_notdi_zesidi): New pattern.

[gcc/testsuite]
	* gcc.target/arm/anddi_notdi-1.c: New test.
	* gcc.target/arm/iordi_notdi-1.c: New test case.

From-SVN: r209614
This commit is contained in:
Ian Bolton 2014-04-22 09:59:50 +00:00 committed by Ian Bolton
parent 80d3417b69
commit a01be1aeb2
6 changed files with 139 additions and 7 deletions

View file

@ -1,3 +1,8 @@
2014-04-22 Ian Bolton <ian.bolton@arm.com>
* config/arm/arm.md (*anddi_notdi_zesidi): New pattern.
* config/arm/thumb2.md (*iordi_notdi_zesidi): New pattern.
2014-04-22 Ian Bolton <ian.bolton@arm.com>
* config/arm/thumb2.md (*iordi_notdi_di): New pattern.

View file

@ -2863,6 +2863,28 @@
(set_attr "type" "multiple")]
)
(define_insn_and_split "*anddi_notdi_zesidi"
[(set (match_operand:DI 0 "s_register_operand" "=r")
(and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
(zero_extend:DI
(match_operand:SI 1 "s_register_operand" "r"))))]
"TARGET_32BIT"
"#"
"TARGET_32BIT && reload_completed"
[(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
(set (match_dup 3) (const_int 0))]
"
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type" "multiple")]
)
(define_insn_and_split "*anddi_notsesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (not:DI (sign_extend:DI

View file

@ -1418,6 +1418,30 @@
(set_attr "type" "multiple")]
)
(define_insn_and_split "*iordi_notdi_zesidi"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
(zero_extend:DI
(match_operand:SI 1 "s_register_operand" "r,r"))))]
"TARGET_THUMB2"
"#"
"TARGET_THUMB2 && reload_completed"
[(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
(set (match_dup 3) (not:SI (match_dup 4)))]
"
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[4] = gen_highpart (SImode, operands[2]);
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type" "multiple")]
)
(define_insn_and_split "*iordi_notsesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (not:DI (sign_extend:DI

View file

@ -1,3 +1,8 @@
2014-04-22 Ian Bolton <ian.bolton@arm.com>
* gcc.target/arm/anddi_notdi-1.c: New test.
* gcc.target/arm/iordi_notdi-1.c: New test case.
2014-04-22 Ian Bolton <ian.bolton@arm.com>
* gcc.target/arm/iordi_notdi-1.c: New test.

View file

@ -0,0 +1,65 @@
/* { dg-do run } */
/* { dg-options "-O2 -fno-inline --save-temps" } */
extern void abort (void);
typedef long long s64int;
typedef int s32int;
typedef unsigned long long u64int;
typedef unsigned int u32int;
s64int
anddi_di_notdi (s64int a, s64int b)
{
return (a & ~b);
}
s64int
anddi_di_notzesidi (s64int a, u32int b)
{
return (a & ~(u64int) b);
}
s64int
anddi_notdi_zesidi (s64int a, u32int b)
{
return (~a & (u64int) b);
}
s64int
anddi_di_notsesidi (s64int a, s32int b)
{
return (a & ~(s64int) b);
}
int main ()
{
s64int a64 = 0xdeadbeef0000ffffll;
s64int b64 = 0x000000005f470112ll;
s64int c64 = 0xdeadbeef300f0000ll;
u32int c32 = 0x01124f4f;
s32int d32 = 0xabbaface;
s64int z = anddi_di_notdi (c64, b64);
if (z != 0xdeadbeef20080000ll)
abort ();
z = anddi_di_notzesidi (a64, c32);
if (z != 0xdeadbeef0000b0b0ll)
abort ();
z = anddi_notdi_zesidi (c64, c32);
if (z != 0x0000000001104f4fll)
abort ();
z = anddi_di_notsesidi (a64, d32);
if (z != 0x0000000000000531ll)
abort ();
return 0;
}
/* { dg-final { scan-assembler-times "bic\t" 6 } } */
/* { dg-final { cleanup-saved-temps } } */

View file

@ -9,19 +9,25 @@ typedef unsigned long long u64int;
typedef unsigned int u32int;
s64int
iordi_notdi (s64int a, s64int b)
iordi_di_notdi (s64int a, s64int b)
{
return (a | ~b);
}
s64int
iordi_notzesidi (s64int a, u32int b)
iordi_di_notzesidi (s64int a, u32int b)
{
return (a | ~(u64int) b);
}
s64int
iordi_notsesidi (s64int a, s32int b)
iordi_notdi_zesidi (s64int a, u32int b)
{
return (~a | (u64int) b);
}
s64int
iordi_di_notsesidi (s64int a, s32int b)
{
return (a | ~(s64int) b);
}
@ -30,25 +36,30 @@ int main ()
{
s64int a64 = 0xdeadbeef00000000ll;
s64int b64 = 0x000000004f4f0112ll;
s64int c64 = 0xdeadbeef000f0000ll;
u32int c32 = 0x01124f4f;
s32int d32 = 0xabbaface;
s64int z = iordi_notdi (a64, b64);
s64int z = iordi_di_notdi (a64, b64);
if (z != 0xffffffffb0b0feedll)
abort ();
z = iordi_notzesidi (a64, c32);
z = iordi_di_notzesidi (a64, c32);
if (z != 0xfffffffffeedb0b0ll)
abort ();
z = iordi_notsesidi (a64, d32);
z = iordi_notdi_zesidi (c64, c32);
if (z != 0x21524110fff2ffffll)
abort ();
z = iordi_di_notsesidi (a64, d32);
if (z != 0xdeadbeef54450531ll)
abort ();
return 0;
}
/* { dg-final { scan-assembler-times "orn\t" 5 { target arm_thumb2 } } } */
/* { dg-final { scan-assembler-times "orn\t" 6 { target arm_thumb2 } } } */
/* { dg-final { cleanup-saved-temps } } */