diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 2486e1489609..3d8fa3abdfea 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -4398,12 +4398,14 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size, /* If we are optimizing, force expensive constants into a register. */ if (CONSTANT_P (x) && optimize && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ()) - > COSTS_N_INSNS (1))) + > COSTS_N_INSNS (1)) + && can_create_pseudo_p ()) x = force_reg (mode, x); if (CONSTANT_P (y) && optimize && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ()) - > COSTS_N_INSNS (1))) + > COSTS_N_INSNS (1)) + && can_create_pseudo_p ()) y = force_reg (mode, y); /* Don't let both operands fail to indicate the mode. */ @@ -4472,6 +4474,8 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size, compare and branch in different basic blocks. */ if (cfun->can_throw_non_call_exceptions) { + if (!can_create_pseudo_p () && (may_trap_p (x) || may_trap_p (y))) + goto fail; if (may_trap_p (x)) x = copy_to_reg (x); if (may_trap_p (y)) diff --git a/gcc/testsuite/gcc.dg/pr102478.c b/gcc/testsuite/gcc.dg/pr102478.c new file mode 100644 index 000000000000..43bc49b584df --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102478.c @@ -0,0 +1,29 @@ +/* PR rtl-optimization/102478 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-if-conversion -Wno-div-by-zero" } */ + +unsigned a, b, c; + +void +foo (void) +{ + c |= __builtin_expect (65535 / a, 0) && 0 / 0; + b = 0; +} + +void +bar (void) +{ + if (a <= 65535) + __builtin_trap (); + b = 0; +} + +void +baz (void) +{ + if (a > 65535) + b = 0; + else + __builtin_trap (); +}