PR87870 shows a problem loading simple constant values into TImode variables.
This is a regression ever since VSX was added and we started using the
vsx_mov<mode>_64bit pattern. We still get the correct code on trunk if we
compile with -mno-vsx, since we fall back to using the older mov<mode>_ppc64
move pattern, which has an alternative "r" <- "n".
Our current vsx_mov<mode>_64bit pattern currently has two alternatives for
loading constants into GPRs, one using "*r" <- "jwM" and "??r" <- "W".
These look redundant to me, since "W" contains support for both all-zero
constants (ie, "j") and all-one constants (ie, wM) as well as a few more.
My patch below consolidates them both and uses a new mode iterator that
uses "W" for the vector modes and "n" for TImode like mov<mode>_ppc64
used.
I'll note I didn't change the vsx_mov<mode>_32bit pattern, since TImode
isn't supported with -m32. However, if you want, I could remove the
redundant "*r" <- "jwM" alternative there too?
This passes bootstrap and regtesting with no regressions. Ok for trunk?
Peter
gcc/
PR target/87870
* config/rs6000/vsx.md (nW): New mode iterator.
(vsx_mov<mode>_64bit): Use it. Remove redundant GPR 0/-1 alternative.
gcc/testsuite/
PR target/87870
* gcc.target/powerpc/pr87870.c: New test.
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md (revision 265971)
+++ gcc/config/rs6000/vsx.md (working copy)
@@ -183,6 +183,18 @@ (define_mode_attr ??r [(V16QI "??r")
(TF "??r")
(TI "r")])
+;; A mode attribute used for 128-bit constant values.
+(define_mode_attr nW [(V16QI "W")
+ (V8HI "W")
+ (V4SI "W")
+ (V4SF "W")
+ (V2DI "W")
+ (V2DF "W")
+ (V1TI "W")
+ (KF "W")
+ (TF "W")
+ (TI "n")])
+
;; Same size integer type for floating point data
(define_mode_attr VSi [(V4SF "v4si")
(V2DF "v2di")
@@ -1193,17 +1205,17 @@ (define_insn_and_split "*xxspltib_<mode>
;; VSX store VSX load VSX move VSX->GPR GPR->VSX LQ (GPR)
;; STQ (GPR) GPR load GPR store GPR move XXSPLTIB VSPLTISW
-;; VSX 0/-1 GPR 0/-1 VMX const GPR const LVX (VMX) STVX
(VMX)
+;; VSX 0/-1 VMX const GPR const LVX (VMX) STVX (VMX)
(define_insn "vsx_mov<mode>_64bit"
[(set (match_operand:VSX_M 0 "nonimmediate_operand"
"=ZwO, <VSa>, <VSa>, r, we, ?wQ,
?&r, ??r, ??Y, <??r>, wo, v,
- ?<VSa>, *r, v, ??r, wZ, v")
+ ?<VSa>, v, <??r>, wZ, v")
(match_operand:VSX_M 1 "input_operand"
"<VSa>, ZwO, <VSa>, we, r, r,
wQ, Y, r, r, wE, jwM,
- ?jwM, jwM, W, W, v, wZ"))]
+ ?jwM, W, <nW>, v, wZ"))]
"TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
&& (register_operand (operands[0], <MODE>mode)
@@ -1214,12 +1226,12 @@ (define_insn "vsx_mov<mode>_64bit"
[(set_attr "type"
"vecstore, vecload, vecsimple, mffgpr, mftgpr, load,
store, load, store, *, vecsimple,
vecsimple,
- vecsimple, *, *, *, vecstore,
vecload")
+ vecsimple, *, *, vecstore, vecload")
(set_attr "length"
"4, 4, 4, 8, 4, 8,
8, 8, 8, 8, 4, 4,
- 4, 8, 20, 20, 4, 4")])
+ 4, 20, 20, 4, 4")])
;; VSX store VSX load VSX move GPR load GPR store GPR move
;; XXSPLTIB VSPLTISW VSX 0/-1 GPR 0/-1 VMX const GPR
const
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md (revision 265971)
+++ gcc/config/rs6000/vsx.md (working copy)
@@ -183,6 +183,18 @@ (define_mode_attr ??r [(V16QI "??r")
(TF "??r")
(TI "r")])
+;; A mode attribute used for 128-bit constant values.
+(define_mode_attr nW [(V16QI "W")
+ (V8HI "W")
+ (V4SI "W")
+ (V4SF "W")
+ (V2DI "W")
+ (V2DF "W")
+ (V1TI "W")
+ (KF "W")
+ (TF "W")
+ (TI "n")])
+
;; Same size integer type for floating point data
(define_mode_attr VSi [(V4SF "v4si")
(V2DF "v2di")
@@ -1193,17 +1205,17 @@ (define_insn_and_split "*xxspltib_<mode>
;; VSX store VSX load VSX move VSX->GPR GPR->VSX LQ (GPR)
;; STQ (GPR) GPR load GPR store GPR move XXSPLTIB VSPLTISW
-;; VSX 0/-1 GPR 0/-1 VMX const GPR const LVX (VMX) STVX
(VMX)
+;; VSX 0/-1 VMX const GPR const LVX (VMX) STVX (VMX)
(define_insn "vsx_mov<mode>_64bit"
[(set (match_operand:VSX_M 0 "nonimmediate_operand"
"=ZwO, <VSa>, <VSa>, r, we, ?wQ,
?&r, ??r, ??Y, <??r>, wo, v,
- ?<VSa>, *r, v, ??r, wZ, v")
+ ?<VSa>, v, <??r>, wZ, v")
(match_operand:VSX_M 1 "input_operand"
"<VSa>, ZwO, <VSa>, we, r, r,
wQ, Y, r, r, wE, jwM,
- ?jwM, jwM, W, W, v, wZ"))]
+ ?jwM, W, <nW>, v, wZ"))]
"TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
&& (register_operand (operands[0], <MODE>mode)
@@ -1214,12 +1226,12 @@ (define_insn "vsx_mov<mode>_64bit"
[(set_attr "type"
"vecstore, vecload, vecsimple, mffgpr, mftgpr, load,
store, load, store, *, vecsimple,
vecsimple,
- vecsimple, *, *, *, vecstore,
vecload")
+ vecsimple, *, *, vecstore, vecload")
(set_attr "length"
"4, 4, 4, 8, 4, 8,
8, 8, 8, 8, 4, 4,
- 4, 8, 20, 20, 4, 4")])
+ 4, 20, 20, 4, 4")])
;; VSX store VSX load VSX move GPR load GPR store GPR move
;; XXSPLTIB VSPLTISW VSX 0/-1 GPR 0/-1 VMX const GPR
const
Index: gcc/testsuite/gcc.target/powerpc/pr87870.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr87870.c (nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr87870.c (working copy)
@@ -0,0 +1,28 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-options "-O2" } */
+
+__int128
+test0 (void)
+{
+ return 0;
+}
+
+__int128
+test1 (void)
+{
+ return 1;
+}
+
+__int128
+test2 (void)
+{
+ return -1;
+}
+
+__int128
+test3 (void)
+{
+ return ((__int128)0xdeadbeefcafebabe << 64) | 0xfacefeedbaaaaaad;
+}
+
+/* { dg-final { scan-assembler-not {\mld\M} } } */