aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2023-12-12 21:55:50 -0800
committerAndrew Pinski <quic_apinski@quicinc.com>2023-12-14 13:38:57 -0800
commit5fa27d9f8c4bec65887654e374146926d76690b0 (patch)
tree0caca1aec529c6bf41390f008ea980f1f4ffc9ea
parent8cccdc2176740f3e034ee6caa49552cf2f142744 (diff)
downloadgcc-5fa27d9f8c4bec65887654e374146926d76690b0.zip
gcc-5fa27d9f8c4bec65887654e374146926d76690b0.tar.gz
gcc-5fa27d9f8c4bec65887654e374146926d76690b0.tar.bz2
middle-end: Fix up constant handling in emit_conditional_move [PR111260]
After r14-2667-gceae1400cf24f329393e96dd9720, we force a constant to a register if it is shared with one of the other operands. The problem is used the comparison mode for the register but that could be different from the operand mode. This causes some issues on some targets. To fix it, we need to make sure the mode of the comparison matches the mode of the other operands, before we can compare the constants (CONST_INT has no modes so compare_rtx returns true if they have the same value even if the usage is in a different mode). Bootstrapped and tested on both aarch64-linux-gnu and x86_64-linux. PR middle-end/111260 gcc/ChangeLog: * optabs.cc (emit_conditional_move): Change the modes to be equal before forcing the constant to a register. gcc/testsuite/ChangeLog: * gcc.c-torture/compile/condmove-1.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
-rw-r--r--gcc/optabs.cc2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/condmove-1.c9
2 files changed, 11 insertions, 0 deletions
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index f0a048a..6a34276 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -5131,6 +5131,7 @@ emit_conditional_move (rtx target, struct rtx_comparison comp,
/* If we are optimizing, force expensive constants into a register
but preserve an eventual equality with op2/op3. */
if (CONSTANT_P (orig_op0) && optimize
+ && cmpmode == mode
&& (rtx_cost (orig_op0, mode, COMPARE, 0,
optimize_insn_for_speed_p ())
> COSTS_N_INSNS (1))
@@ -5142,6 +5143,7 @@ emit_conditional_move (rtx target, struct rtx_comparison comp,
op3p = XEXP (comparison, 0) = force_reg (cmpmode, orig_op0);
}
if (CONSTANT_P (orig_op1) && optimize
+ && cmpmode == mode
&& (rtx_cost (orig_op1, mode, COMPARE, 0,
optimize_insn_for_speed_p ())
> COSTS_N_INSNS (1))
diff --git a/gcc/testsuite/gcc.c-torture/compile/condmove-1.c b/gcc/testsuite/gcc.c-torture/compile/condmove-1.c
new file mode 100644
index 0000000..3fcc591
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/condmove-1.c
@@ -0,0 +1,9 @@
+/* PR middle-end/111260 */
+
+/* Used to ICE while expansion of the `(a == b) ? b : 0;` */
+int f1(long long a)
+{
+ int b = 822920;
+ int t = a == b;
+ return t * (int)b;
+}