[Bug tree-optimization/79666] [7 Regression] wrong code (SIGFPE) at -O2 on x86_64-linux-gnu (in both 32-bit and 64-bit modes)
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Feb 22 09:25:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79666
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Priority|P3 |P1
Status|NEW |ASSIGNED
Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Difference:
<bb 3> [12.75%]:
...
_41 = _40 & -124;
g_lsm.15_57 = g;
e_lsm.17_59 = e;
b_a_lsm.19_61 = b.a;
d_lsm.21_63 = d;
_42 = f.0_1 <= 0;
<bb 4>:
...
if (f.0_1 != 0)
goto <bb 5>; [50.00%]
else
goto <bb 6>; [50.00%]
<bb 5>:
_4 = g_lsm.15_35 ^ e_lsm.17_53;
_5 = -1 / _4;
...
- _100 = (signed char) _47;
- _102 = ~_100;
- _106 = _102 | _109;
+ _99 = (signed char) _47;
+ _101 = ~_99;
+ _105 = _101 | _110;
+ _107 = _41 & _105;
<bb 6> [85.00%]:
# iftmp.4_21 = PHI <_47(5), 0(4)>
# g_lsm.15_32 = PHI <_6(5), g_lsm.15_35(4)>
# g_lsm.16_51 = PHI <1(5), g_lsm.16_36(4)>
- # prephitmp_107 = PHI <_106(5), -1(4)>
- _17 = _41 & prephitmp_107;
- _18 = ~_17;
+ # prephitmp_108 = PHI <_107(5), _41(4)>
+ _18 = ~prephitmp_108;
_37 = _18 != 127;
_27 = _37 | _42;
if (_27 != 0)
that looks ok to me. _41 & -1 is _41 (_41 is signed char).
So the issue was latent and is elsewhere. In .optimized we can see we
were able to optimize a conditional away. And if we disable VRP2
with -fdisable-tree-vrp2 the issue goes away. VRP2 diff shows new symbolic
ranges:
@@ -60,17 +60,16 @@
c.11_8: [-INF, 8] EQUIVALENCES: { } (0 elements)
c.11_9: VARYING
.MEM_10: VARYING
-_17: [-INF(OVF), +INF(OVF)]
-_18: [-INF(OVF), +INF(OVF)]
+_18: [-_107 + -1, -_107 + -1]
_19: [-2147483647, 9]
-_20: [_41, _41] EQUIVALENCES: { _41 } (1 elements)
+_20: [-_41 + -1, -_41 + -1]
...
-Folding predicate _99 != 127 to 1
+Folding predicate _20 != 127 to 1
+Folding predicate _18 != 127 to 1
...
_37 = 1;
_27 = _37 | _42;
if (_27 != 0)
goto <bb 7>; [19.94%]
else
goto <bb 6>; [80.06%]
bah, it fails to optimize the conditional directly it seems.
Folding statement: _37 = _18 != 127;
Folding predicate _18 != 127 to 1
Folded into: _37 = 1;
Folding statement: _27 = _37 | _42;
Not folded
Folding statement: if (_27 != 0)
Not folded
that's because the lattice isn't updated and/or VRP doesn't properly
try match-and-simplify during propagation.
_18: [-_107 + -1, -_107 + -1]
so yes, for signed char _18 if it's -_107 + -1 it can't be 127 w/o invoking
undefined behavior. But whoever created that symbolic range was probably
not careful enough to avoid creating an expression that might involve
undefined behavior.
We have
<bb 6> [42.50%]:
# g_lsm.15_32 = PHI <_6(5)>
# g_lsm.16_51 = PHI <1(5)>
# prephitmp_108 = PHI <_107(5)>
_18 = ~prephitmp_108;
_37 = _18 != 127;
_27 = _37 | _42;
if (_27 != 0)
goto <bb 8>; [19.94%]
else
goto <bb 7>; [80.06%]
<bb 7> [34.03%]:
_29 = ASSERT_EXPR <_18, _18 == 127>;
<bb 8> [85.00%]:
# g_lsm.15_33 = PHI <g_lsm.15_32(6), 0(7), g_lsm.15_50(13)>
# g_lsm.16_52 = PHI <g_lsm.16_51(6), 1(7), g_lsm.16_22(13)>
# _96 = PHI <_18(6), _29(7), _20(13)>
and we can see from where that symbolic range comes from. _18 is ~_107
and we "trick" to use -_107 - 1 for that:
void
extract_range_from_unary_expr (value_range *vr,
enum tree_code code, tree type,
value_range *vr0_, tree op0_type)
{
...
else if (code == BIT_NOT_EXPR)
{
/* ~X is simply -1 - X, so re-use existing code that also handles
anti-ranges fine. */
value_range minusone = VR_INITIALIZER;
set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL);
extract_range_from_binary_expr_1 (vr, MINUS_EXPR,
type, &minusone, &vr0);
return;
That's also my code (but older), thus, mine.
More information about the Gcc-bugs
mailing list