https://gcc.gnu.org/g:436aa53e7bf8384c7321a5a47b523ad08dc5748e
commit r16-9295-g436aa53e7bf8384c7321a5a47b523ad08dc5748e Author: Jakub Jelinek <[email protected]> Date: Wed Jul 15 10:27:56 2026 +0200 match.pd: Guard x+x -> x*2 simplification [PR126257] The x+x -> x*2 simplication obviously requires that 2 is representable in type, so that rules out unsigned _BitInt(1) and signed _BitInt(2) (and 1 too in C2Y, ditto unsigned:1 and signed:2 and :1), otherwise we don't multiply by 2 but by 0 or -2. While perhaps we could transform in those cases x+x to x<<1, I'm not convinced it is worth it. 2026-07-15 Jakub Jelinek <[email protected]> PR tree-optimization/126257 * match.pd (x+x -> x*2): Only optimize if 2 is representable in the type. * gcc.dg/torture/bitint-101.c: New test. Reviewed-by: Richard Biener <[email protected]> (cherry picked from commit d5059b35e03e63c7686288c3554c2922a2c37468) Diff: --- gcc/match.pd | 3 ++- gcc/testsuite/gcc.dg/torture/bitint-101.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/gcc/match.pd b/gcc/match.pd index 87a6c2377962..1cdf53702c76 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6037,7 +6037,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (plus @0 @0) (if (SCALAR_FLOAT_TYPE_P (type)) (mult @0 { build_real (type, dconst2); }) - (if (INTEGRAL_TYPE_P (type)) + (if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) > (2 - TYPE_UNSIGNED (type))) (mult @0 { build_int_cst (type, 2); })))) /* 0 - X -> -X. */ diff --git a/gcc/testsuite/gcc.dg/torture/bitint-101.c b/gcc/testsuite/gcc.dg/torture/bitint-101.c new file mode 100644 index 000000000000..95e9a982aa2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-101.c @@ -0,0 +1,26 @@ +/* PR tree-optimization/126257 */ +/* { dg-do run } */ + +_BitInt(2) a; +long long b, c, d; + +int +main () +{ + int e; + _BitInt(2) f; + bool g; + long long h = b; +lab: + e = h; + if (e != 4) + f = -1; + f = f + f; + a = f; + g = d - 4; + if (!g) + goto lab; + c = a; + if (c != -2) + __builtin_abort (); +}
