Commit d89f355e by Michael Meissner Committed by Michael Meissner

re PR target/78543 (ICE in push_reload, at reload.c:1349 on powerpc64le-linux-gnu)

[gcc]
2017-03-27  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/78543
	* config/rs6000/rs6000.md (bswaphi2_extenddi): Combine bswap
	HImode and SImode with zero extend to DImode to one insn.
	(bswap<mode>2_extenddi): Likewise.
	(bswapsi2_extenddi): Likewise.
	(bswaphi2_extendsi): Likewise.
	(bswaphi2): Combine bswap HImode and SImode into one insn.
	Separate memory insns from swapping register.
	(bswapsi2): Likewise.
	(bswap<mode>2): Likewise.
	(bswaphi2_internal): Delete, no longer used.
	(bswapsi2_internal): Likewise.
	(bswap<mode>2_load): Split bswap HImode/SImode into separate load,
	store, and gpr<-gpr swap insns.
	(bswap<mode>2_store): Likewise.
	(bswaphi2_reg): Register only splitter, combine with the splitter.
	(bswaphi2 splitter): Likewise.
	(bswapsi2_reg): Likewise.
	(bswapsi2 splitter): Likewise.
	(bswapdi2): If we have the LDBRX and STDBRX instructions, split
	the insns into load, store, and register/register insns.
	(bswapdi2_ldbrx): Likewise.
	(bswapdi2_load): Likewise.
	(bswapdi2_store): Likewise.
	(bswapdi2_reg): Likewise.

[gcc/testsuite]
2017-03-27  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/78543
	* gcc.target/powerpc/pr78543.c: New test.

From-SVN: r246508
parent b6749273
2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78543
* config/rs6000/rs6000.md (bswaphi2_extenddi): Combine bswap
HImode and SImode with zero extend to DImode to one insn.
(bswap<mode>2_extenddi): Likewise.
(bswapsi2_extenddi): Likewise.
(bswaphi2_extendsi): Likewise.
(bswaphi2): Combine bswap HImode and SImode into one insn.
Separate memory insns from swapping register.
(bswapsi2): Likewise.
(bswap<mode>2): Likewise.
(bswaphi2_internal): Delete, no longer used.
(bswapsi2_internal): Likewise.
(bswap<mode>2_load): Split bswap HImode/SImode into separate load,
store, and gpr<-gpr swap insns.
(bswap<mode>2_store): Likewise.
(bswaphi2_reg): Register only splitter, combine with the splitter.
(bswaphi2 splitter): Likewise.
(bswapsi2_reg): Likewise.
(bswapsi2 splitter): Likewise.
(bswapdi2): If we have the LDBRX and STDBRX instructions, split
the insns into load, store, and register/register insns.
(bswapdi2_ldbrx): Likewise.
(bswapdi2_load): Likewise.
(bswapdi2_store): Likewise.
(bswapdi2_reg): Likewise.
2017-03-27 Gunther Nikl <gnikl@users.sourceforge.net> 2017-03-27 Gunther Nikl <gnikl@users.sourceforge.net>
* system.h (HAVE_DESIGNATED_INITIALIZERS): Fix non C++ case. * system.h (HAVE_DESIGNATED_INITIALIZERS): Fix non C++ case.
......
...@@ -2350,12 +2350,12 @@ ...@@ -2350,12 +2350,12 @@
;; Since the hardware zeros the upper part of the register, save generating the ;; Since the hardware zeros the upper part of the register, save generating the
;; AND immediate if we are converting to unsigned ;; AND immediate if we are converting to unsigned
(define_insn "*bswaphi2_extenddi" (define_insn "*bswap<mode>2_extenddi"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extend:DI (zero_extend:DI
(bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
"TARGET_POWERPC64" "TARGET_POWERPC64"
"lhbrx %0,%y1" "l<wd>brx %0,%y1"
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "type" "load")]) (set_attr "type" "load")])
...@@ -2368,34 +2368,52 @@ ...@@ -2368,34 +2368,52 @@
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "type" "load")]) (set_attr "type" "load")])
(define_expand "bswaphi2" ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
[(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "") ;; the register allocator from converting a gpr<-gpr swap into a store and then
(bswap:HI ;; load with byte swap, which can be slower than doing it in the registers. It
(match_operand:HI 1 "reg_or_mem_operand" ""))) ;; also prevents certain failures with the RELOAD register allocator.
(clobber (match_scratch:SI 2 ""))])]
(define_expand "bswap<mode>2"
[(use (match_operand:HSI 0 "reg_or_mem_operand"))
(use (match_operand:HSI 1 "reg_or_mem_operand"))]
"" ""
{ {
if (!REG_P (operands[0]) && !REG_P (operands[1])) rtx dest = operands[0];
operands[1] = force_reg (HImode, operands[1]); rtx src = operands[1];
if (!REG_P (dest) && !REG_P (src))
src = force_reg (<MODE>mode, src);
if (MEM_P (src))
emit_insn (gen_bswap<mode>2_load (dest, src));
else if (MEM_P (dest))
emit_insn (gen_bswap<mode>2_store (dest, src));
else
emit_insn (gen_bswap<mode>2_reg (dest, src));
DONE;
}) })
(define_insn "bswaphi2_internal" (define_insn "bswap<mode>2_load"
[(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r") [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
(bswap:HI (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
(match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:SI 2 "=X,X,&r"))]
"" ""
"@ "l<wd>brx %0,%y1"
lhbrx %0,%y1 [(set_attr "type" "load")])
sthbrx %1,%y0
#"
[(set_attr "length" "4,4,12")
(set_attr "type" "load,store,*")])
(define_split (define_insn "bswap<mode>2_store"
[(set (match_operand:HI 0 "gpc_reg_operand" "") [(set (match_operand:HSI 0 "memory_operand" "=Z")
(bswap:HI (match_operand:HI 1 "gpc_reg_operand" ""))) (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
(clobber (match_operand:SI 2 "gpc_reg_operand" ""))] ""
"st<wd>brx %1,%y0"
[(set_attr "type" "store")])
(define_insn_and_split "bswaphi2_reg"
[(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
(bswap:HI
(match_operand:HI 1 "gpc_reg_operand" "r")))
(clobber (match_scratch:SI 2 "=&r"))]
""
"#"
"reload_completed" "reload_completed"
[(set (match_dup 3) [(set (match_dup 3)
(and:SI (lshiftrt:SI (match_dup 4) (and:SI (lshiftrt:SI (match_dup 4)
...@@ -2408,48 +2426,21 @@ ...@@ -2408,48 +2426,21 @@
(set (match_dup 3) (set (match_dup 3)
(ior:SI (match_dup 3) (ior:SI (match_dup 3)
(match_dup 2)))] (match_dup 2)))]
"
{ {
operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
}") }
[(set_attr "length" "12")
(define_insn "*bswapsi2_extenddi" (set_attr "type" "*")])
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extend:DI
(bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
"TARGET_POWERPC64"
"lwbrx %0,%y1"
[(set_attr "length" "4")
(set_attr "type" "load")])
(define_expand "bswapsi2"
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(bswap:SI
(match_operand:SI 1 "reg_or_mem_operand" "")))]
""
{
if (!REG_P (operands[0]) && !REG_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
})
(define_insn "*bswapsi2_internal"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
(bswap:SI
(match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
""
"@
lwbrx %0,%y1
stwbrx %1,%y0
#"
[(set_attr "length" "4,4,12")
(set_attr "type" "load,store,*")])
;; We are always BITS_BIG_ENDIAN, so the bit positions below in ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
;; zero_extract insns do not change for -mlittle. ;; zero_extract insns do not change for -mlittle.
(define_split (define_insn_and_split "bswapsi2_reg"
[(set (match_operand:SI 0 "gpc_reg_operand" "") [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
(bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))] (bswap:SI
(match_operand:SI 1 "gpc_reg_operand" "r")))]
""
"#"
"reload_completed" "reload_completed"
[(set (match_dup 0) ; DABC [(set (match_dup 0) ; DABC
(rotate:SI (match_dup 1) (rotate:SI (match_dup 1)
...@@ -2465,11 +2456,13 @@ ...@@ -2465,11 +2456,13 @@
(const_int 24)) (const_int 24))
(const_int 255)) (const_int 255))
(and:SI (match_dup 0) (and:SI (match_dup 0)
(const_int -256)))) (const_int -256))))]
]
"") "")
;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
;; complex code.
(define_expand "bswapdi2" (define_expand "bswapdi2"
[(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "") [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
(bswap:DI (bswap:DI
...@@ -2478,33 +2471,56 @@ ...@@ -2478,33 +2471,56 @@
(clobber (match_scratch:DI 3 ""))])] (clobber (match_scratch:DI 3 ""))])]
"" ""
{ {
if (!REG_P (operands[0]) && !REG_P (operands[1])) rtx dest = operands[0];
operands[1] = force_reg (DImode, operands[1]); rtx src = operands[1];
if (!REG_P (dest) && !REG_P (src))
operands[1] = src = force_reg (DImode, src);
if (TARGET_POWERPC64 && TARGET_LDBRX)
{
if (MEM_P (src))
emit_insn (gen_bswapdi2_load (dest, src));
else if (MEM_P (dest))
emit_insn (gen_bswapdi2_store (dest, src));
else
emit_insn (gen_bswapdi2_reg (dest, src));
DONE;
}
if (!TARGET_POWERPC64) if (!TARGET_POWERPC64)
{ {
/* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
that uses 64-bit registers needs the same scratch registers as 64-bit that uses 64-bit registers needs the same scratch registers as 64-bit
mode. */ mode. */
emit_insn (gen_bswapdi2_32bit (operands[0], operands[1])); emit_insn (gen_bswapdi2_32bit (dest, src));
DONE; DONE;
} }
}) })
;; Power7/cell has ldbrx/stdbrx, so use it directly ;; Power7/cell has ldbrx/stdbrx, so use it directly
(define_insn "*bswapdi2_ldbrx" (define_insn "bswapdi2_load"
[(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r") [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
(clobber (match_scratch:DI 2 "=X,X,&r")) "TARGET_POWERPC64 && TARGET_LDBRX"
(clobber (match_scratch:DI 3 "=X,X,&r"))] "ldbrx %0,%y1"
"TARGET_POWERPC64 && TARGET_LDBRX [(set_attr "type" "load")])
&& (REG_P (operands[0]) || REG_P (operands[1]))"
"@ (define_insn "bswapdi2_store"
ldbrx %0,%y1 [(set (match_operand:DI 0 "memory_operand" "=Z")
stdbrx %1,%y0 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
#" "TARGET_POWERPC64 && TARGET_LDBRX"
[(set_attr "length" "4,4,36") "stdbrx %1,%y0"
(set_attr "type" "load,store,*")]) [(set_attr "type" "store")])
(define_insn "bswapdi2_reg"
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
(clobber (match_scratch:DI 2 "=&r"))
(clobber (match_scratch:DI 3 "=&r"))]
"TARGET_POWERPC64 && TARGET_LDBRX"
"#"
[(set_attr "length" "36")])
;; Non-power7/cell, fall back to use lwbrx/stwbrx ;; Non-power7/cell, fall back to use lwbrx/stwbrx
(define_insn "*bswapdi2_64bit" (define_insn "*bswapdi2_64bit"
......
2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78543
* gcc.target/powerpc/pr78543.c: New test.
2017-03-27 Kelvin Nilsen <kelvin@gcc.gnu.org> 2017-03-27 Kelvin Nilsen <kelvin@gcc.gnu.org>
PR target/80103 PR target/80103
......
/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
/* { dg-options "-mcpu=power8 -O1 -mno-lra" } */
typedef long a;
enum c { e, f, g, h, i, ab } j();
int l, n, o, p;
a q, r;
void *memcpy();
void b();
static int k(int *s) {
int m;
if (j(&m))
*s = m;
return !0;
}
void d(char s) {
int af[4];
int ag;
enum c ah;
char ai[24 << 11];
unsigned aj;
if (!k(&aj))
goto ak;
for (;;) {
if (!k(&ag))
goto ak;
switch (ah) {
case e:
b("");
b("bad length %d for GUID in fileinfo v%u for \"%s\"");
case i:
b("bad length %d for TTH in fileinfo v%u for \"%s\"", aj);
case ab:
if (ag % 24)
b("for \"%s\"", s);
case f:
if (20 == ag)
case h:
if (20 == ag)
o = 0;
break;
case g:
memcpy(af, ai, sizeof af);
b();
if (p) {
a al, am;
r = al << 2 | am;
n = af[2];
al = n;
l = __builtin_bswap32(af[3]);
am = q = n | l;
}
default:
b("%s0 unhandled field ID %u 0", __func__);
}
}
ak:;
}
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