simplify (X != 0 ? X + ~0 : 0) to (X - X != 0). */
(simplify
(cond (ne@1 @0 integer_zerop)
- (nop_convert? (plus (nop_convert? @0) integer_all_onesp))
+ (nop_convert1? (plus (nop_convert2?@2 @0) integer_all_onesp))
integer_zerop)
(if (INTEGRAL_TYPE_P (type))
- (minus @0 (convert @1))))
+ (with { tree itype = TREE_TYPE (@2); }
+ (convert (minus @2 (convert:itype @1))))))
/* Signed saturation sub, case 1:
T minus = (T)((UT)X - (UT)Y);
--- /dev/null
+/* { dg-do run } */
+/* { dg-additional-options "-fgimple" } */
+
+/* PR tree-optimization/117363 */
+
+/* a != 0 ? (signed)(((unsigned)a) - 1) : 0
+ Should not be transformed into doing the
+ plus in a signed type which could cause an overflow.` */
+
+__attribute__((noinline))
+signed __GIMPLE ()
+test2 (int n)
+{
+ unsigned t;
+ _Bool _4;
+ if (n_1(D) > 0) goto unreachable;
+ else goto normal;
+normal:
+ t_2 = (unsigned)n_1(D);
+ t_3 = t_2 - 1u;
+ n_5 = (signed) t_3;
+ _4 = n_1(D) != 0;
+ n_6 = _4 ? n_5 : 0;
+ if (n_6 > 0) goto return1;
+ else goto trap;
+
+return1:
+ return n_6;
+
+unreachable:
+ __builtin_unreachable();
+
+trap:
+ __builtin_trap ();
+}
+
+int main()
+{
+ unsigned t = -__INT_MAX__ - 1;
+ test2(t);
+}
--- /dev/null
+/* { dg-do compile } */
+
+/* PR tree-optimization/117363 */
+/* ldist produces `s != 0 ? s - 1 : 0` (with casts) and that
+ the match pattern which messed up the converts. */
+
+void f(int *array, long t) {
+ if (!t) return;
+ unsigned long s = ~t;
+ for (long i = 0; i < s; i++)
+ array[i] = 0;
+}