/* a ? 1 : 0 -> a if 0 and 1 are integral types. */
(if (integer_onep (@1))
(convert (convert:boolean_type_node @0)))
- /* a ? -1 : 0 -> -a. */
- (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
- (negate (convert (convert:boolean_type_node @0))))
/* a ? powerof2cst : 0 -> a << (log2(powerof2cst)) */
(if (INTEGRAL_TYPE_P (type) && integer_pow2p (@1))
(with {
tree shift = build_int_cst (integer_type_node, tree_log2 (@1));
}
- (lshift (convert (convert:boolean_type_node @0)) { shift; })))))
+ (lshift (convert (convert:boolean_type_node @0)) { shift; })))
+ /* a ? -1 : 0 -> -a. No need to check the TYPE_PRECISION not being 1
+ here as the powerof2cst case above will handle that case correctly. */
+ (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
+ (negate (convert (convert:boolean_type_node @0))))))
(if (integer_zerop (@1))
(with {
tree booltrue = constant_boolean_node (true, boolean_type_node);
/* a ? 0 : 1 -> !a. */
(if (integer_onep (@2))
(convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))
- /* a ? -1 : 0 -> -(!a). */
- (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
- (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
/* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
- (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@2))
+ (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@2)
+ && TYPE_PRECISION (type) != 1)
(with {
tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
}
(lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))
- { shift; }))))))))
+ { shift; })))
+ /* a ? -1 : 0 -> -(!a). No need to check the TYPE_PRECISION not being 1
+ here as the powerof2cst case above will handle that case correctly. */
+ (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
+ (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
+ )
+ )
+ )
+ )
+)
#endif
/* Simplification moved from fold_cond_expr_with_comparison. It may also
--- /dev/null
+/* PR tree-optimization/102622 */
+/* Wrong code introduced due to phi-opt
+ introducing undefined signed interger overflow
+ with one bit signed integer negation. */
+
+struct f{signed t:1;};
+int g(struct f *a, int t) __attribute__((noipa));
+int g(struct f *a, int t)
+{
+ if (t)
+ a->t = -1;
+ else
+ a->t = 0;
+ int t1 = a->t;
+ if (t1) return 1;
+ return t1;
+}
+
+int main(void)
+{
+ struct f a;
+ if (!g(&a, 1)) __builtin_abort();
+ return 0;
+}