aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-09-15 10:34:33 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2025-09-15 10:34:33 +0200
commitbd83c6227c6c2ccb5df88937a338b501fd550de6 (patch)
treeeb8cc0e235da85f101ed3b4debc8eff05c4b47ed
parent6485b105655c2179eb9f74ac35d535912f43cac5 (diff)
downloadgcc-bd83c6227c6c2ccb5df88937a338b501fd550de6.zip
gcc-bd83c6227c6c2ccb5df88937a338b501fd550de6.tar.gz
gcc-bd83c6227c6c2ccb5df88937a338b501fd550de6.tar.bz2
expr, tree: Ensure get_range_pos_neg is called only on scalar integral types [PR121904]
The gcc.c-torture/compile/20111209-1.c testcase which uses typedef char* char_ptr32 __attribute__ ((mode(SI))); ICEs on s390x since my change to optimize extensions by cheaper of signed or unsigned extension if sign bit is known from VRP not to be set. The problem is that get_range_pos_neg uses ranger into int_range_max and so ICEs on pointers. All the other current callers call it from places where only scalar integral types can appear (scalar division/modulo, overflow ifns, etc.) I think, this spot was just testing SCALAR_INT_MODE_P. The following patch adds check for INTEGRAL_TYPE_P, I think ranger will not do anything useful for pointers here anyway and what is a negative pointer is also fuzzy. I've changed both get_range_pos_neg to punt on that and the caller, either of those changes are sufficient to fix the ICE, but I think it doesn't hurt to do it in both places. 2025-09-15 Jakub Jelinek <jakub@redhat.com> PR middle-end/121904 * tree.cc (get_range_pos_neg): Return 3 if arg doesn't have scalar integral type. * expr.cc (expand_expr_real_2) <CASE_CONVERT>: Only choose between sign and zero extension based on costs for scalar integral inner types.
-rw-r--r--gcc/expr.cc1
-rw-r--r--gcc/tree.cc2
2 files changed, 2 insertions, 1 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 4f7b457..4a69910 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -9960,6 +9960,7 @@ expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode,
else if (SCALAR_INT_MODE_P (GET_MODE (op0))
&& optimize >= 2
&& SCALAR_INT_MODE_P (mode)
+ && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
&& (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
> GET_MODE_SIZE (as_a <scalar_int_mode> (GET_MODE (op0))))
&& get_range_pos_neg (treeop0,
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 2a3ab23f..5d52a38 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -14708,7 +14708,7 @@ verify_type (const_tree t)
int
get_range_pos_neg (tree arg, gimple *stmt)
{
- if (arg == error_mark_node)
+ if (arg == error_mark_node || !INTEGRAL_TYPE_P (TREE_TYPE (arg)))
return 3;
int prec = TYPE_PRECISION (TREE_TYPE (arg));