aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-06-04 15:49:41 +0200
committerJakub Jelinek <jakub@redhat.com>2024-06-11 12:35:39 +0200
commitb065824e30e9168d33b56039e436c4b09078e260 (patch)
treed835247b9345604127511478b120ee267a7f8537
parent91a371254494934e191e3060ae2a86905eb4b2b2 (diff)
downloadgcc-b065824e30e9168d33b56039e436c4b09078e260.zip
gcc-b065824e30e9168d33b56039e436c4b09078e260.tar.gz
gcc-b065824e30e9168d33b56039e436c4b09078e260.tar.bz2
fold-const: Fix up CLZ handling in tree_call_nonnegative_warnv_p [PR115337]
The function currently incorrectly assumes all the __builtin_clz* and .CLZ calls have non-negative result. That is the case of the former which is UB on zero and has [0, prec-1] return value otherwise, and is the case of the single argument .CLZ as well (again, UB on zero), but for two argument .CLZ is the case only if the second argument is also nonnegative (or if we know the argument can't be zero, but let's do that just in the ranger IMHO). The following patch does that. 2024-06-04 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/115337 * fold-const.cc (tree_call_nonnegative_warnv_p) <CASE_CFN_CLZ>: If fn is CFN_CLZ, use CLZ_DEFINED_VALUE_AT. (cherry picked from commit b82a816000791e7a286c7836b3a473ec0e2a577b)
-rw-r--r--gcc/fold-const.cc18
1 files changed, 17 insertions, 1 deletions
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 7030294..d81a71c 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see
#include "vec-perm-indices.h"
#include "asan.h"
#include "gimple-range.h"
+#include "internal-fn.h"
/* Nonzero if we are folding constants inside an initializer or a C++
manifestly-constant-evaluated context; zero otherwise.
@@ -14861,7 +14862,6 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
CASE_CFN_FFS:
CASE_CFN_PARITY:
CASE_CFN_POPCOUNT:
- CASE_CFN_CLZ:
CASE_CFN_CLRSB:
case CFN_BUILT_IN_BSWAP16:
case CFN_BUILT_IN_BSWAP32:
@@ -14870,6 +14870,22 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
/* Always true. */
return true;
+ CASE_CFN_CLZ:
+ if (fn != CFN_CLZ)
+ return true;
+ else if (INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+ {
+ tree atype = TREE_TYPE (arg0);
+ int val = 0;
+ if (direct_internal_fn_supported_p (IFN_CLZ, atype,
+ OPTIMIZE_FOR_BOTH)
+ && CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (atype),
+ val) == 2
+ && val >= 0)
+ return true;
+ }
+ break;
+
CASE_CFN_SQRT:
CASE_CFN_SQRT_FN:
/* sqrt(-0.0) is -0.0. */