Alpha: Permit constant zero source for "insvmisaligndi"
Eliminate a redundant bitwise inclusive OR operation on the insertion of constant zero into a bit-field, improving code produced at `-O2' from an output sequence such as: mov $31,$3 # Redundant! ldq_u $1,7($16) insqh $3,$16,$3 # Redundant! ldq_u $2,0($16) mskqh $1,$16,$1 mskql $2,$16,$2 bis $1,$3,$1 # Redundant! stq_u $1,7($16) stq_u $2,0($16) ret $31,($26),1 to: ldq_u $2,7($16) ldq_u $1,0($16) mskqh $2,$16,$2 stq_u $2,7($16) mskql $1,$16,$1 stq_u $1,0($16) ret $31,($26),1 for a quadword unaligned store operation. As shown in the example this only triggers for the high-part store (and therefore only for 2-byte, 4-byte, and 8-byte stores), because `insXl' insns are fully expressed in terms of RTL and therefore the insertion of zero is eliminated in later RTL passes, however corresponding `insXh' insns are unspecs only, making them impossible to see through. We can get this optimal right from expand though, given that our handler for "insvmisaligndi", i.e. `alpha_expand_unaligned_store', has explicit provisions for `const0_rtx' source. gcc/ * config/alpha/alpha.md (insvmisaligndi): Use "reg_or_0_operand" rather than "register_operand" for operand 3. gcc/testsuite/ * gcc.target/alpha/stlx0.c: New file. * gcc.target/alpha/stqx0.c: New file. * gcc.target/alpha/stwx0.c: New file. * gcc.target/alpha/stwx0-bwx.c: New file.
This commit is contained in:
parent
665e0f9c08
commit
3c99ea19d2
5 changed files with 104 additions and 1 deletions
|
@ -4626,7 +4626,7 @@
|
|||
[(set (zero_extract:DI (match_operand:BLK 0 "memory_operand")
|
||||
(match_operand:DI 1 "const_int_operand")
|
||||
(match_operand:DI 2 "const_int_operand"))
|
||||
(match_operand:DI 3 "register_operand"))]
|
||||
(match_operand:DI 3 "reg_or_0_operand"))]
|
||||
""
|
||||
{
|
||||
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
||||
|
|
28
gcc/testsuite/gcc.target/alpha/stlx0.c
Normal file
28
gcc/testsuite/gcc.target/alpha/stlx0.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" } } */
|
||||
|
||||
typedef struct { int v __attribute__ ((packed)); } intx;
|
||||
|
||||
void
|
||||
stlx0 (intx *p)
|
||||
{
|
||||
p->v = 0;
|
||||
}
|
||||
|
||||
/* Expect assembly such as:
|
||||
|
||||
ldq_u $2,3($16)
|
||||
ldq_u $1,0($16)
|
||||
msklh $2,$16,$2
|
||||
stq_u $2,3($16)
|
||||
mskll $1,$16,$1
|
||||
stq_u $1,0($16)
|
||||
|
||||
without any INSLH, INSLL, or BIS instructions. */
|
||||
|
||||
/* { dg-final { scan-assembler-times "\\sldq_u\\s" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "\\smsklh\\s" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "\\smskll\\s" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "\\sstq_u\\s" 2 } } */
|
||||
/* { dg-final { scan-assembler-not "\\s(?:bis|inslh|insll)\\s" } } */
|
28
gcc/testsuite/gcc.target/alpha/stqx0.c
Normal file
28
gcc/testsuite/gcc.target/alpha/stqx0.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" } } */
|
||||
|
||||
typedef struct { long v __attribute__ ((packed)); } longx;
|
||||
|
||||
void
|
||||
stqx0 (longx *p)
|
||||
{
|
||||
p->v = 0;
|
||||
}
|
||||
|
||||
/* Expect assembly such as:
|
||||
|
||||
ldq_u $2,7($16)
|
||||
ldq_u $1,0($16)
|
||||
mskqh $2,$16,$2
|
||||
stq_u $2,7($16)
|
||||
mskql $1,$16,$1
|
||||
stq_u $1,0($16)
|
||||
|
||||
without any INSQH, INSQL, or BIS instructions. */
|
||||
|
||||
/* { dg-final { scan-assembler-times "\\sldq_u\\s" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "\\smskqh\\s" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "\\smskql\\s" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "\\sstq_u\\s" 2 } } */
|
||||
/* { dg-final { scan-assembler-not "\\s(?:bis|insqh|insql)\\s" } } */
|
19
gcc/testsuite/gcc.target/alpha/stwx0-bwx.c
Normal file
19
gcc/testsuite/gcc.target/alpha/stwx0-bwx.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mbwx" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" } } */
|
||||
|
||||
typedef struct { short v __attribute__ ((packed)); } shortx;
|
||||
|
||||
void
|
||||
stwx0 (shortx *p)
|
||||
{
|
||||
p->v = 0;
|
||||
}
|
||||
|
||||
/* Expect assembly such as:
|
||||
|
||||
stb $31,0($16)
|
||||
stb $31,1($16)
|
||||
*/
|
||||
|
||||
/* { dg-final { scan-assembler-times "\\sstb\\s\\\$31," 2 } } */
|
28
gcc/testsuite/gcc.target/alpha/stwx0.c
Normal file
28
gcc/testsuite/gcc.target/alpha/stwx0.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mno-bwx" } */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" } } */
|
||||
|
||||
typedef struct { short v __attribute__ ((packed)); } shortx;
|
||||
|
||||
void
|
||||
stwx0 (shortx *p)
|
||||
{
|
||||
p->v = 0;
|
||||
}
|
||||
|
||||
/* Expect assembly such as:
|
||||
|
||||
ldq_u $2,1($16)
|
||||
ldq_u $1,0($16)
|
||||
mskwh $2,$16,$2
|
||||
stq_u $2,1($16)
|
||||
mskwl $1,$16,$1
|
||||
stq_u $1,0($16)
|
||||
|
||||
without any INSWH, INSWL, or BIS instructions. */
|
||||
|
||||
/* { dg-final { scan-assembler-times "\\sldq_u\\s" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "\\smskwh\\s" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "\\smskwl\\s" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "\\sstq_u\\s" 2 } } */
|
||||
/* { dg-final { scan-assembler-not "\\s(?:bis|inswh|inswl)\\s" } } */
|
Loading…
Add table
Reference in a new issue