(No cans of worms opened here, I believe...)
For MMIX with the default, Knuth's ABI (returning values in register
$0, through the register stack), function return values are prepared
in a register-swapped fashion due to the way the register stack works,
which has to be expressed as:
(parallel [
(expr_list:REG_DEP_TRUE (reg:DI 0 $0)
(const_int 8 [0x8]))
(expr_list:REG_DEP_TRUE (reg:DI 1 $1)
(const_int 0 [0]))
])
i.e. a group load. Compare to the more intuitive "GNU ABI", passing
parameters straightforwardly, with the order in the called and the
calling function being the same, starting with global register $231.
Of course this matters only to >64bit (i.e. >registersize) values like
TImode, alias __int128. The problem here is that group-loading a
constant for a function return-value doesn't work; it's passed to
simplify_gen_subreg which horks on the VOIDmode constant. Thankfully,
the code below the context handles this case, twice the register-mode,
just fine, so let's just gate the simplify_gen_subreg call with a test
for a VOIDmode source. Bootstrapped and checked for
x86_64-*-linux-gnu and checked for mmix-knuth-mmixware, both -mabi=gnu
multilib (no regressions) and the base multilib with the Knuth ABI,
where the patch below fixes:
Running
/home/hp/gcctop/tmp/mbasf/gcc/gcc/testsuite/gcc.c-torture/execute/execute.exp
...
...
FAIL: gcc.c-torture/execute/pr54471.c compilation, -O1 (internal compiler
error)
FAIL: gcc.c-torture/execute/pr54471.c compilation, -O2 (internal compiler
error)
FAIL: gcc.c-torture/execute/pr54471.c compilation, -O3 -fomit-frame-pointer
(internal compiler error)
FAIL: gcc.c-torture/execute/pr54471.c compilation, -O3 -fomit-frame-pointer
-funroll-loops (internal compiler error)
FAIL: gcc.c-torture/execute/pr54471.c compilation, -O3 -fomit-frame-pointer
-funroll-all-loops -finline-functions (internal compiler error)
FAIL: gcc.c-torture/execute/pr54471.c compilation, -O3 -g (internal compiler
error)
FAIL: gcc.c-torture/execute/pr54471.c compilation, -Os (internal compiler
error)
FAIL: gcc.c-torture/execute/pr54471.c compilation, -O2 -flto
-fno-use-linker-plugin -flto-partition=none (internal compiler error)
FAIL: gcc.c-torture/execute/pr54471.c compilation, -O2 -flto
-fuse-linker-plugin -fno-fat-lto-objects (internal compiler error)
...
Running /home/hp/gcctop/tmp/mbasf/gcc/gcc/testsuite/gcc.dg/dg.exp ...
...
FAIL: gcc.dg/pr32912-2.c (internal compiler error)
FAIL: gcc.dg/pr32912-2.c (test for excess errors)
FAIL: gcc.dg/pr32912-3.c (internal compiler error)
FAIL: gcc.dg/pr32912-3.c (test for excess errors)
...
Running
/home/hp/gcctop/tmp/mbasf/gcc/gcc/testsuite/gcc.dg/torture/dg-torture.exp ...
...
FAIL: c-c++-common/torture/vector-compare-2.c -O1 (internal compiler error)
FAIL: c-c++-common/torture/vector-compare-2.c -O1 (test for excess errors)
FAIL: c-c++-common/torture/vector-compare-2.c -O2 (internal compiler error)
FAIL: c-c++-common/torture/vector-compare-2.c -O2 (test for excess errors)
FAIL: c-c++-common/torture/vector-compare-2.c -O3 -fomit-frame-pointer
(internal compiler error)
FAIL: c-c++-common/torture/vector-compare-2.c -O3 -fomit-frame-pointer (test
for excess errors)
FAIL: c-c++-common/torture/vector-compare-2.c -O3 -fomit-frame-pointer
-funroll-loops (internal compiler error)
FAIL: c-c++-common/torture/vector-compare-2.c -O3 -fomit-frame-pointer
-funroll-loops (test for excess errors)
FAIL: c-c++-common/torture/vector-compare-2.c -O3 -fomit-frame-pointer
-funroll-all-loops -finline-functions (internal compiler error)
FAIL: c-c++-common/torture/vector-compare-2.c -O3 -fomit-frame-pointer
-funroll-all-loops -finline-functions (test for excess errors)
FAIL: c-c++-common/torture/vector-compare-2.c -O3 -g (internal compiler error)
FAIL: c-c++-common/torture/vector-compare-2.c -O3 -g (test for excess errors)
FAIL: c-c++-common/torture/vector-compare-2.c -Os (internal compiler error)
FAIL: c-c++-common/torture/vector-compare-2.c -Os (test for excess errors)
FAIL: c-c++-common/torture/vector-compare-2.c -O2 -flto -fno-use-linker-plugin
-flto-partition=none (internal compiler error)
FAIL: c-c++-common/torture/vector-compare-2.c -O2 -flto -fno-use-linker-plugin
-flto-partition=none (test for excess errors)
(ditto the c++ testsuite for c-c++-common/torture/vector-compare-2.c)
(FWIW, the failing gcc.dg/pr32912-3.c is a regression.)
Ok?
gcc:
* expr.c (emit_group_load_1): Don't call simplify_gen_subreg for
a VOIDmode src.
Index: gcc/expr.c
===================================================================
--- gcc/expr.c (revision 192677)
+++ gcc/expr.c (working copy)
@@ -1739,7 +1739,9 @@ emit_group_load_1 (rtx *tmps, rtx dst, r
emit_move_insn (mem, src);
tmps[i] = adjust_address (mem, mode, (int) bytepos);
}
- else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
+ else if (CONSTANT_P (src)
+ && GET_MODE (src) != VOIDmode
+ && GET_MODE (dst) != BLKmode
&& XVECLEN (dst, 0) > 1)
tmps[i] = simplify_gen_subreg (mode, src, GET_MODE(dst), bytepos);
else if (CONSTANT_P (src))
brgds, H-P