From 794acc6340cb2869a74fc69104c38ac5c2840a91 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Wed, 11 Mar 2026 13:01:08 -0700 Subject: [PATCH] simplify-rtx: Fix the case where subreg of a vec_concat could fail [PR123822] So combine (rightfully) produces: (subreg:DD (vec_concat:V2DI (const_int -1 [0xffffffffffffffff]) (reg:DI 145 [ _22 ])) 0) And then calls simplify_subreg on it. simplify_subreg then sees it can remove the vec_concat as this is the lower part and try to do `(subreg:DD (const_int -1 [0xffffffffffffffff]))` but that is an invalid constant for DF64 so simplify_subreg rejects that and returns NULL but there is code in simplify_subreg to create a SUBREG then if the subreg validates. The problem is we are using DImode for the inner mode and that validates but when gen_rtx_SUBREG is called the inner mode of DImode is not there; only VOIDmode. So the fix is to check for VOIDmode before the call to validate_subreg. Bootstrapped and tested on x86_64-linux-gnu. And lightly tested for aarch64-linux-gnu. PR rtl-optimization/123822 gcc/ChangeLog: * simplify-rtx.cc (simplify_context::simplify_subreg): Check the mode of the part to be non-VOIDmode before calling gen_rtx_SUBREG. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr123822-1.c: New test. Signed-off-by: Andrew Pinski --- gcc/simplify-rtx.cc | 3 ++- gcc/testsuite/gcc.dg/torture/pr123822-1.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr123822-1.c diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 88aa95c8123..50fc51152ca 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -8491,7 +8491,8 @@ simplify_context::simplify_subreg (machine_mode outermode, rtx op, res = simplify_subreg (outermode, part, part_mode, final_offset); if (res) return res; - if (validate_subreg (outermode, part_mode, part, final_offset)) + if (GET_MODE (part) != VOIDmode + && validate_subreg (outermode, part_mode, part, final_offset)) return gen_rtx_SUBREG (outermode, part, final_offset); return NULL_RTX; } diff --git a/gcc/testsuite/gcc.dg/torture/pr123822-1.c b/gcc/testsuite/gcc.dg/torture/pr123822-1.c new file mode 100644 index 00000000000..38dd05507d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr123822-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffast-math" } */ +/* { dg-require-effective-target dfp } */ + +/* PR rtl-optimization/123822 */ + +typedef __attribute__((__vector_size__(16))) _Decimal64 D; + +int i; +D d; + +void +foo() +{ + d /= (D)(d >= *(D *)__builtin_memset(&d, i, 3)); +}