if (!dep1)
return false;
- // Don't recalculate PHIs or statements with side_effects.
+ // Only recalculate range-op statements that are recomputable.
gimple *s = SSA_NAME_DEF_STMT (name);
- if (is_a<gphi *> (s) || gimple_has_side_effects (s))
+ gimple_range_op_handler handler (s);
+ if (!handler || !handler.recomputable_p ())
return false;
if (!dep2)
m_stmt = s;
m_op1 = NULL_TREE;
m_op2 = NULL_TREE;
+ // Recomputation defaults to TRUE.
+ m_recomputable = true;
if (oper)
switch (gimple_code (m_stmt))
m_operator = &op_cfn_constant_p;
else if (frange::supports_p (TREE_TYPE (m_op1)))
m_operator = &op_cfn_constant_float_p;
+ // builtin_constant_p should not be recomputed. See PR 123205.
+ m_recomputable = false;
break;
CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
relation_trio = TRIO_VARYING);
bool calc_op2 (vrange &r, const vrange &lhs_range, const vrange &op1_range,
relation_trio = TRIO_VARYING);
+ inline bool recomputable_p () { return m_recomputable; }
private:
void maybe_builtin_call ();
void maybe_non_standard ();
gimple *m_stmt;
tree m_op1, m_op2;
+ bool m_recomputable;
};
// Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+void isconst (int, int);
+void nonconst (int, int);
+
+int foo (int x)
+{
+ int y = __builtin_constant_p (x);
+ if (y)
+ isconst (y, x);
+ else
+ nonconst (y, x);
+
+ if (x == 24)
+ {
+ /* Y should have the same value as earlier. */
+ if (y)
+ isconst (y, x);
+ else
+ nonconst (y, x);
+ }
+}
+/* { dg-final { scan-tree-dump-not "isconst" "optimized" } } */