diff options
author | Roger Sayle <roger@nextmovesoftware.com> | 2024-07-06 05:24:39 +0100 |
---|---|---|
committer | Roger Sayle <roger@nextmovesoftware.com> | 2024-07-06 05:27:12 +0100 |
commit | 9a7e3f57e1ab8e6e4cf5ea3c0998aa50c6220579 (patch) | |
tree | 9dac33be832bc4a0ec0c513f6946f0d041cbcb3d | |
parent | 92e4d73dd9ddd80d24c7843895ee1cc85e30cee4 (diff) | |
download | gcc-9a7e3f57e1ab8e6e4cf5ea3c0998aa50c6220579.zip gcc-9a7e3f57e1ab8e6e4cf5ea3c0998aa50c6220579.tar.gz gcc-9a7e3f57e1ab8e6e4cf5ea3c0998aa50c6220579.tar.bz2 |
PR target/115751: Avoid force_reg in ix86_expand_ternlog.
This patch fixes a problem with splitting of complex AVX512 ternlog
instructions on x86_64. A recent change allows the ternlog pattern
to have multiple mem-like operands prior to reload, by emitting any
"reloads" as necessary during split1, before register allocation.
The issue is that this code calls force_reg to place the mem-like
operand into a register, but unfortunately the vec_duplicate (broadcast)
form of operands supported by ternlog isn't considered a "general_operand",
i.e. supported by all instructions. This mismatch triggers an ICE in
the middle-end's force_reg, even though the x86 supports loading these
vec_duplicate operands into a vector register in a single (move)
instruction.
This patch resolves this problem by replacing force_reg with calls
to gen_reg_rtx and emit_move (as the i386 backend, unlike the middle-end,
knows these will be recognized by recog).
2024-07-06 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR target/115751
* config/i386/i386-expand.cc (ix86_expand_ternlog): Avoid use of
force_reg to "reload" non-register operands, as these may contain
vec_duplicate (broadcast) operands that aren't supported by
force_reg. Use (safer) gen_reg_rtx and emit_move instead.
-rw-r--r-- | gcc/config/i386/i386-expand.cc | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index a773b45..bf79e59 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -26050,14 +26050,25 @@ ix86_expand_ternlog (machine_mode mode, rtx op0, rtx op1, rtx op2, int idx, break; } - tmp0 = register_operand (op0, mode) ? op0 : force_reg (mode, op0); + if (!register_operand (op0, mode)) + { + /* We can't use force_reg (mode, op0). */ + tmp0 = gen_reg_rtx (GET_MODE (op0)); + emit_move_insn (tmp0,op0); + } + else + tmp0 = op0; if (GET_MODE (tmp0) != mode) tmp0 = gen_lowpart (mode, tmp0); if (!op1 || rtx_equal_p (op0, op1)) tmp1 = copy_rtx (tmp0); else if (!register_operand (op1, mode)) - tmp1 = force_reg (mode, op1); + { + /* We can't use force_reg (mode, op1). */ + tmp1 = gen_reg_rtx (GET_MODE (op1)); + emit_move_insn (tmp1, op1); + } else tmp1 = op1; if (GET_MODE (tmp1) != mode) |