Summary: | folding (~ -x) >= (-2147483647-1) to x != -2147483648 | ||
---|---|---|---|
Product: | gcc | Reporter: | Bruno Haible <bruno> |
Component: | middle-end | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | minor | CC: | gabravier, gcc-bugs, rguenth |
Priority: | P3 | Keywords: | missed-optimization |
Version: | 4.1.1 | ||
Target Milestone: | 7.0 | ||
Host: | Target: | i686-pc-linux-gnu | |
Build: | Known to work: | 10.3.0, 11.1.0, 4.0.3, 6.5.0, 7.5.0, 8.4.0, 9.3.0 | |
Known to fail: | 4.1.2, 4.3.0, 4.8.5, 4.9.4, 5.5.0 | Last reconfirmed: | 2006-12-27 16:48:37 |
Description
Bruno Haible
2006-12-20 14:35:40 UTC
This is folded to ;; Function notneg (notneg) ;; enabled by -tree-original { return x != -2147483648; } ;; Function negnot (negnot) ;; enabled by -tree-original { return x != 2147483647; } via /* Convert - (~A) to A + 1. */ if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == BIT_NOT_EXPR) return fold_build2 (PLUS_EXPR, type, TREE_OPERAND (arg0, 0), build_int_cst (type, 1)); and /* Convert ~ (-A) to A - 1. */ else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR) return fold_build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0), build_int_cst (type, 1)); and /* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 +- C1. */ if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)) && !TYPE_UNSIGNED (TREE_TYPE (arg1)) && !(flag_wrapv || flag_trapv)) && (TREE_CODE (arg1) == INTEGER_CST && !TREE_OVERFLOW (arg1))) { tree const1 = TREE_OPERAND (arg0, 1); tree const2 = arg1; tree variable = TREE_OPERAND (arg0, 0); tree lhs; int lhs_add; lhs_add = TREE_CODE (arg0) != PLUS_EXPR; lhs = fold_build2 (lhs_add ? PLUS_EXPR : MINUS_EXPR, TREE_TYPE (arg1), const2, const1); if (TREE_CODE (lhs) == TREE_CODE (arg1) && (TREE_CODE (lhs) != INTEGER_CST || !TREE_OVERFLOW (lhs))) return fold_build2 (code, type, variable, lhs); } (citing from the 4.1 branch) Note this is actually wrong-code. (In reply to comment #1) > Note this is actually wrong-code. No, it is not. In notneg, if x is -2147483647-1, it is obviously, we have an overflow as -(-2147483647-1) is overflowed. In negnot, if x is 2147483647, then ~ 2147483647 == -2147483647-1, and then we have an overflow. Fixed with at least GCC 7. It was still broken in GCC 4.8.5 though. (In reply to Andrew Pinski from comment #3) > Fixed with at least GCC 7. > It was still broken in GCC 4.8.5 though. Indeed. Here's the status with GCC versions since 4.0.x: 4.0.4 optimized 4.1.2 missed 4.2.4 missed 4.3.6 missed 4.4.7 missed 4.5.4 missed 4.6.4 missed 4.7.3 missed 4.8.5 missed 4.9.4 missed 5.5.0 missed 6.5.0 optimized 7.5.0 optimized 8.4.0 optimized 9.3.0 optimized 10.3.0 optimized 11.1.0 optimized |