diff mbox series

Fix incorrect subreg mode check [PR117476]

Message ID ZzLlP7nB6MsLdgoO@amerzlyakov-PC
State New
Headers show
Series Fix incorrect subreg mode check [PR117476] | expand

Commit Message

Alexey Merzlyakov Nov. 12, 2024, 5:18 a.m. UTC
gcc/ChangeLog:

	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
	Fix subreg mode check during zero_extend(not) -> xor optimization.

gcc/testsuite/ChangeLog:

	* gcc.dg/pr117476.c: New test.

Signed-off-by: Alexey Merzlyakov <alexey.merzlyakov@samsung.com>
---
 gcc/simplify-rtx.cc             |  2 +-
 gcc/testsuite/gcc.dg/pr117476.c | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr117476.c

Comments

Alexey Merzlyakov Nov. 12, 2024, 11:38 a.m. UTC | #1
Updated testsuite/ChangeLog with respect to the original testcase author

-- >8 --

gcc/ChangeLog:

	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
	Fix subreg mode check during zero_extend(not) -> xor optimization.

gcc/testsuite/ChangeLog:

	* gcc.dg/pr117476.c: New test. From Zhendong Su.

Signed-off-by: Alexey Merzlyakov <alexey.merzlyakov@samsung.com>
---
 gcc/simplify-rtx.cc             |  2 +-
 gcc/testsuite/gcc.dg/pr117476.c | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr117476.c

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index d05efac20dc..2a9cabaad09 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -1856,7 +1856,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	  && subreg_lowpart_p (op)
 	  && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
 	  && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
-	      & ~GET_MODE_MASK (mode)) == 0)
+	      & ~GET_MODE_MASK (GET_MODE (op))) == 0)
       {
 	const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
 	return simplify_gen_binary (XOR, mode,
diff --git a/gcc/testsuite/gcc.dg/pr117476.c b/gcc/testsuite/gcc.dg/pr117476.c
new file mode 100644
index 00000000000..b8f51e697bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr117476.c
@@ -0,0 +1,12 @@
+/* PR rtl-optimization/117476 */
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+
+int c = 0x1FF;
+
+int main()
+{
+  if (((c ^ 0xFF) & 0xFF) != 0)
+    __builtin_abort();
+  return 0;
+}
Alex Coplan Nov. 12, 2024, 11:46 a.m. UTC | #2
Hi Alexey,

On 12/11/2024 08:18, Alexey Merzlyakov wrote:
> gcc/ChangeLog:
> 
> 	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
> 	Fix subreg mode check during zero_extend(not) -> xor optimization.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.dg/pr117476.c: New test.
> 
> Signed-off-by: Alexey Merzlyakov <alexey.merzlyakov@samsung.com>
> ---
>  gcc/simplify-rtx.cc             |  2 +-
>  gcc/testsuite/gcc.dg/pr117476.c | 12 ++++++++++++
>  2 files changed, 13 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr117476.c
> 
> diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
> index d05efac20dc..2a9cabaad09 100644
> --- a/gcc/simplify-rtx.cc
> +++ b/gcc/simplify-rtx.cc
> @@ -1856,7 +1856,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
>  	  && subreg_lowpart_p (op)
>  	  && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
>  	  && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
> -	      & ~GET_MODE_MASK (mode)) == 0)
> +	      & ~GET_MODE_MASK (GET_MODE (op))) == 0)
>        {
>  	const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
>  	return simplify_gen_binary (XOR, mode,
> diff --git a/gcc/testsuite/gcc.dg/pr117476.c b/gcc/testsuite/gcc.dg/pr117476.c
> new file mode 100644
> index 00000000000..b8f51e697bf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr117476.c

I think it might be better to put the test in gcc.c-torture/execute,
then it will automatically get run with the various torture options
and you should be able to drop both the dejagnu directives.

Thanks,
Alex

> @@ -0,0 +1,12 @@
> +/* PR rtl-optimization/117476 */
> +/* { dg-do run } */
> +/* { dg-options "-O1" } */
> +
> +int c = 0x1FF;
> +
> +int main()
> +{
> +  if (((c ^ 0xFF) & 0xFF) != 0)
> +    __builtin_abort();
> +  return 0;
> +}
> -- 
> 2.34.1
Jeff Law Nov. 12, 2024, 5:56 p.m. UTC | #3
On 11/12/24 4:46 AM, Alex Coplan wrote:
> Hi Alexey,
> 
> On 12/11/2024 08:18, Alexey Merzlyakov wrote:
>> gcc/ChangeLog:
>>
>> 	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
>> 	Fix subreg mode check during zero_extend(not) -> xor optimization.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* gcc.dg/pr117476.c: New test.
>>
>> Signed-off-by: Alexey Merzlyakov <alexey.merzlyakov@samsung.com>
>> ---
>>   gcc/simplify-rtx.cc             |  2 +-
>>   gcc/testsuite/gcc.dg/pr117476.c | 12 ++++++++++++
>>   2 files changed, 13 insertions(+), 1 deletion(-)
>>   create mode 100644 gcc/testsuite/gcc.dg/pr117476.c
>>
>> diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
>> index d05efac20dc..2a9cabaad09 100644
>> --- a/gcc/simplify-rtx.cc
>> +++ b/gcc/simplify-rtx.cc
>> @@ -1856,7 +1856,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
>>   	  && subreg_lowpart_p (op)
>>   	  && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
>>   	  && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
>> -	      & ~GET_MODE_MASK (mode)) == 0)
>> +	      & ~GET_MODE_MASK (GET_MODE (op))) == 0)
>>         {
>>   	const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
>>   	return simplify_gen_binary (XOR, mode,
>> diff --git a/gcc/testsuite/gcc.dg/pr117476.c b/gcc/testsuite/gcc.dg/pr117476.c
>> new file mode 100644
>> index 00000000000..b8f51e697bf
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pr117476.c
> 
> I think it might be better to put the test in gcc.c-torture/execute,
> then it will automatically get run with the various torture options
> and you should be able to drop both the dejagnu directives.
Actually, gcc.dg/torture is better.

jeff
Alexey Merzlyakov Nov. 12, 2024, 5:59 p.m. UTC | #4
Hi, Alex,

On Tue, Nov 12, 2024 at 11:46:54AM +0000, Alex Coplan wrote:
> I think it might be better to put the test in gcc.c-torture/execute,
> then it will automatically get run with the various torture options
> and you should be able to drop both the dejagnu directives.
> 
> Thanks,
> Alex
Yep. Now it is going through more options at runtime. Thank you for the
suggestion.

Updated patch is below:

-- >8 --

gcc/ChangeLog:

	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
	Fix subreg mode check during zero_extend(not) -> xor optimization.

gcc/testsuite/ChangeLog:

	* gcc.c-torture/execute/pr117476.c: New test. From Zhendong Su.

Signed-off-by: Alexey Merzlyakov <alexey.merzlyakov@samsung.com>
---
 gcc/simplify-rtx.cc                            |  2 +-
 gcc/testsuite/gcc.c-torture/execute/pr117476.c | 10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr117476.c

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index d05efac20dc..2a9cabaad09 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -1856,7 +1856,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	  && subreg_lowpart_p (op)
 	  && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
 	  && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
-	      & ~GET_MODE_MASK (mode)) == 0)
+	      & ~GET_MODE_MASK (GET_MODE (op))) == 0)
       {
 	const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
 	return simplify_gen_binary (XOR, mode,
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr117476.c b/gcc/testsuite/gcc.c-torture/execute/pr117476.c
new file mode 100644
index 00000000000..97deb1e2b63
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr117476.c
@@ -0,0 +1,10 @@
+/* PR rtl-optimization/117476 */
+
+int c = 0x1FF;
+
+int main()
+{
+  if (((c ^ 0xFF) & 0xFF) != 0)
+    __builtin_abort();
+  return 0;
+}
Alexey Merzlyakov Nov. 12, 2024, 6:31 p.m. UTC | #5
Hi, Jeff,

Oops... It looks like I've made a reply to Alex at the same time when
you sent an e-mail update.

So, moving the testcase to the gcc.dg/torture directory.

On Tue, Nov 12, 2024 at 10:56:13AM -0700, Jeff Law wrote:
> > I think it might be better to put the test in gcc.c-torture/execute,
> > then it will automatically get run with the various torture options
> > and you should be able to drop both the dejagnu directives.
> Actually, gcc.dg/torture is better.
> 
> jeff

Next version of patch is below:

-- >8 --

gcc/ChangeLog:

	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
	Fix subreg mode check during zero_extend(not) -> xor optimization.

gcc/testsuite/ChangeLog:

	* gcc.dg/torture/pr117476.c: New test. From Zhendong Su.

Signed-off-by: Alexey Merzlyakov <alexey.merzlyakov@samsung.com>
---
 gcc/simplify-rtx.cc                     |  2 +-
 gcc/testsuite/gcc.dg/torture/pr117476.c | 11 +++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr117476.c

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index d05efac20dc..2a9cabaad09 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -1856,7 +1856,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	  && subreg_lowpart_p (op)
 	  && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
 	  && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
-	      & ~GET_MODE_MASK (mode)) == 0)
+	      & ~GET_MODE_MASK (GET_MODE (op))) == 0)
       {
 	const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
 	return simplify_gen_binary (XOR, mode,
diff --git a/gcc/testsuite/gcc.dg/torture/pr117476.c b/gcc/testsuite/gcc.dg/torture/pr117476.c
new file mode 100644
index 00000000000..7a0225a4f19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr117476.c
@@ -0,0 +1,11 @@
+/* PR rtl-optimization/117476 */
+/* { dg-do run } */
+
+int c = 0x1FF;
+
+int main()
+{
+  if (((c ^ 0xFF) & 0xFF) != 0)
+    __builtin_abort();
+  return 0;
+}
Jeff Law Nov. 13, 2024, 12:42 a.m. UTC | #6
On 11/12/24 11:31 AM, Alexey Merzlyakov wrote:
> Hi, Jeff,
> 
> Oops... It looks like I've made a reply to Alex at the same time when
> you sent an e-mail update.
> 
> So, moving the testcase to the gcc.dg/torture directory.
> 
> On Tue, Nov 12, 2024 at 10:56:13AM -0700, Jeff Law wrote:
>>> I think it might be better to put the test in gcc.c-torture/execute,
>>> then it will automatically get run with the various torture options
>>> and you should be able to drop both the dejagnu directives.
>> Actually, gcc.dg/torture is better.
>>
>> jeff
> 
> Next version of patch is below:
> 
> -- >8 --
> 
> gcc/ChangeLog:
> 
> 	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
> 	Fix subreg mode check during zero_extend(not) -> xor optimization.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.dg/torture/pr117476.c: New test. From Zhendong Su.
I think we've still got a problem in this code.  If we take this test 
from Zdenek, we completely optimize away foo() during combine.

unsigned __int128 g;

void
foo ()
{
   g += __builtin_add_overflow_p (~g, 0, 0ul);
}

int
main ()
{
   foo();
   if (!g)
     __builtin_abort();
}
$ x86_64-pc-linux-gnu-gcc -O1 testcase.c -Wall -W && ./a.out
Aborted

I think the problem is the mask we generate when the optimization 
applies -- and you're about to be exposed to a bit of GCC quirkyness.

We've got a TImode ZERO_EXTEND of this object:

(gdb) p debug_rtx (op)
(subreg:DI (not:TI (reg:TI 100 [ g.0_2 ])) 0)


So precisely the kind of case you're trying to handle.  This is 
equivalent to a (xor:TI (reg:TI 100) (const_int 0xffffffffffffffff))

So we end up calling simplify_gen_binary, and our constant is:

(gdb) p debug_rtx (op1)
(const_int -1 [0xffffffffffffffff])


Note constants in GCC do not have a mode.  So that (const_int -1) when 
interpreted in TImode is 0xffffffffffffffffffffffffffffffff, clearly not 
what we want.  We ultimately return:

(gdb) finish
Run till exit from #0  simplify_context::simplify_unary_operation_1 
(this=0x7fffffffd928, code=ZERO_EXTEND, mode=E_TImode, 
op=0x7ffff77e5b40) at /home/jlaw/test/gcc/gcc/simplify-rtx.cc:1861
simplify_context::simplify_unary_operation (this=0x7fffffffd928, 
code=ZERO_EXTEND, mode=E_TImode, op=0x7ffff77e5b40, op_mode=E_DImode) at 
/home/jlaw/test/gcc/gcc/simplify-rtx.cc:893
893       return simplify_unary_operation_1 (code, mode, op);
Value returned is $20 = (rtx_def *) 0x7ffff77c1e20
(gdb) p debug_rtx ($20)
(not:TI (reg:TI 100 [ g.0_2 ]))


Which is not the same as:

(zero_extend:TI (subreg:DI (not:TI (reg:TI 100 [ g.0_2 ])) 0))

Anyway, that the beginning of that function into:

(insn 8 6 15 2 (set (reg:TI 107)
         (not:TI (reg:TI 100 [ g.0_2 ]))) "j.c":6:8 1029 
{*one_cmplti2_doubleword}
      (nil))

(insn 15 8 35 2 (set (reg:TI 108)
         (not:TI (reg:TI 100 [ g.0_2 ]))) "j.c":6:8 174 {zero_extendditi2}
      (nil))

(insn 35 15 36 2 (set (reg:CCZ 17 flags)
         (compare:CCZ (reg:TI 107)
             (reg:TI 108))) "j.c":6:8 34 {*cmpti_doubleword}
      (expr_list:REG_DEAD (reg:TI 108)
         (expr_list:REG_DEAD (reg:TI 107)
             (nil))))

Naturally things go downhill after that since the condition has a known 
result, eventually leading to the whole function optimizing away and 
returning random garbage.


So the natural question is how to fix.  First I would recommend changing 
the type of "mask" to a HOST_WIDE_INT.  In an of itself that won't fix 
this problem, but it's the right thing to do.

I think what you want is to test HWI_COMPUTABLE_MODE_P.  That will 
verify whether or not the given scalar integer mode can fit into a 
HOST_WIDE_INT, which should return false for TI or larger modes.

Jeff
Andrew Pinski Nov. 13, 2024, 1:02 a.m. UTC | #7
On Tue, Nov 12, 2024 at 4:43 PM Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
> On 11/12/24 11:31 AM, Alexey Merzlyakov wrote:
> > Hi, Jeff,
> >
> > Oops... It looks like I've made a reply to Alex at the same time when
> > you sent an e-mail update.
> >
> > So, moving the testcase to the gcc.dg/torture directory.
> >
> > On Tue, Nov 12, 2024 at 10:56:13AM -0700, Jeff Law wrote:
> >>> I think it might be better to put the test in gcc.c-torture/execute,
> >>> then it will automatically get run with the various torture options
> >>> and you should be able to drop both the dejagnu directives.
> >> Actually, gcc.dg/torture is better.
> >>
> >> jeff
> >
> > Next version of patch is below:
> >
> > -- >8 --
> >
> > gcc/ChangeLog:
> >
> >       * simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
> >       Fix subreg mode check during zero_extend(not) -> xor optimization.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * gcc.dg/torture/pr117476.c: New test. From Zhendong Su.
> I think we've still got a problem in this code.  If we take this test
> from Zdenek, we completely optimize away foo() during combine.
>
> unsigned __int128 g;
>
> void
> foo ()
> {
>    g += __builtin_add_overflow_p (~g, 0, 0ul);
> }
>
> int
> main ()
> {
>    foo();
>    if (!g)
>      __builtin_abort();
> }
> $ x86_64-pc-linux-gnu-gcc -O1 testcase.c -Wall -W && ./a.out
> Aborted
>
> I think the problem is the mask we generate when the optimization
> applies -- and you're about to be exposed to a bit of GCC quirkyness.
>
> We've got a TImode ZERO_EXTEND of this object:
>
> (gdb) p debug_rtx (op)
> (subreg:DI (not:TI (reg:TI 100 [ g.0_2 ])) 0)
>
>
> So precisely the kind of case you're trying to handle.  This is
> equivalent to a (xor:TI (reg:TI 100) (const_int 0xffffffffffffffff))
>
> So we end up calling simplify_gen_binary, and our constant is:
>
> (gdb) p debug_rtx (op1)
> (const_int -1 [0xffffffffffffffff])
>
>
> Note constants in GCC do not have a mode.  So that (const_int -1) when
> interpreted in TImode is 0xffffffffffffffffffffffffffffffff, clearly not
> what we want.  We ultimately return:
>
> (gdb) finish
> Run till exit from #0  simplify_context::simplify_unary_operation_1
> (this=0x7fffffffd928, code=ZERO_EXTEND, mode=E_TImode,
> op=0x7ffff77e5b40) at /home/jlaw/test/gcc/gcc/simplify-rtx.cc:1861
> simplify_context::simplify_unary_operation (this=0x7fffffffd928,
> code=ZERO_EXTEND, mode=E_TImode, op=0x7ffff77e5b40, op_mode=E_DImode) at
> /home/jlaw/test/gcc/gcc/simplify-rtx.cc:893
> 893       return simplify_unary_operation_1 (code, mode, op);
> Value returned is $20 = (rtx_def *) 0x7ffff77c1e20
> (gdb) p debug_rtx ($20)
> (not:TI (reg:TI 100 [ g.0_2 ]))
>
>
> Which is not the same as:
>
> (zero_extend:TI (subreg:DI (not:TI (reg:TI 100 [ g.0_2 ])) 0))
>
> Anyway, that the beginning of that function into:
>
> (insn 8 6 15 2 (set (reg:TI 107)
>          (not:TI (reg:TI 100 [ g.0_2 ]))) "j.c":6:8 1029
> {*one_cmplti2_doubleword}
>       (nil))
>
> (insn 15 8 35 2 (set (reg:TI 108)
>          (not:TI (reg:TI 100 [ g.0_2 ]))) "j.c":6:8 174 {zero_extendditi2}
>       (nil))
>
> (insn 35 15 36 2 (set (reg:CCZ 17 flags)
>          (compare:CCZ (reg:TI 107)
>              (reg:TI 108))) "j.c":6:8 34 {*cmpti_doubleword}
>       (expr_list:REG_DEAD (reg:TI 108)
>          (expr_list:REG_DEAD (reg:TI 107)
>              (nil))))
>
> Naturally things go downhill after that since the condition has a known
> result, eventually leading to the whole function optimizing away and
> returning random garbage.
>
>
> So the natural question is how to fix.  First I would recommend changing
> the type of "mask" to a HOST_WIDE_INT.  In an of itself that won't fix
> this problem, but it's the right thing to do.

I see nonzero_bits returns an unsigned HOST_WIDE_INT; though I wonder
if it should use wi::wide_int; maybe it less important for RTX than
the gimple level to support wider integers.

The places which uses nonzero_bits either use HWI_COMPUTABLE_MODE_P
(or ` GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT`)
or checks against 1 or a had a CONST_INT (which is HWI only). Though I
wonder if the ones which check nonzero_bits against 1 are ok.

Thanks,
Andrew


>
> I think what you want is to test HWI_COMPUTABLE_MODE_P.  That will
> verify whether or not the given scalar integer mode can fit into a
> HOST_WIDE_INT, which should return false for TI or larger modes.
>
> Jeff
>
>
>
>
>
>
>
Jeff Law Nov. 13, 2024, 1:06 a.m. UTC | #8
On 11/12/24 11:31 AM, Alexey Merzlyakov wrote:
> Hi, Jeff,
> 
> Oops... It looks like I've made a reply to Alex at the same time when
> you sent an e-mail update.
It happens.  But as Zdenek's test showed, we've got one more issue to 
resolve :-)  Hopefully my email gave you a solid pointer on what needs 
adjustment.  It didn't even occur to me to worry about TImode constants.

jeff
Alex Coplan Nov. 14, 2024, 11:34 a.m. UTC | #9
On 12/11/2024 10:56, Jeff Law wrote:
> 
> 
> On 11/12/24 4:46 AM, Alex Coplan wrote:
> > Hi Alexey,
> > 
> > On 12/11/2024 08:18, Alexey Merzlyakov wrote:
> > > gcc/ChangeLog:
> > > 
> > > 	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
> > > 	Fix subreg mode check during zero_extend(not) -> xor optimization.
> > > 
> > > gcc/testsuite/ChangeLog:
> > > 
> > > 	* gcc.dg/pr117476.c: New test.
> > > 
> > > Signed-off-by: Alexey Merzlyakov <alexey.merzlyakov@samsung.com>
> > > ---
> > >   gcc/simplify-rtx.cc             |  2 +-
> > >   gcc/testsuite/gcc.dg/pr117476.c | 12 ++++++++++++
> > >   2 files changed, 13 insertions(+), 1 deletion(-)
> > >   create mode 100644 gcc/testsuite/gcc.dg/pr117476.c
> > > 
> > > diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
> > > index d05efac20dc..2a9cabaad09 100644
> > > --- a/gcc/simplify-rtx.cc
> > > +++ b/gcc/simplify-rtx.cc
> > > @@ -1856,7 +1856,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
> > >   	  && subreg_lowpart_p (op)
> > >   	  && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
> > >   	  && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
> > > -	      & ~GET_MODE_MASK (mode)) == 0)
> > > +	      & ~GET_MODE_MASK (GET_MODE (op))) == 0)
> > >         {
> > >   	const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
> > >   	return simplify_gen_binary (XOR, mode,
> > > diff --git a/gcc/testsuite/gcc.dg/pr117476.c b/gcc/testsuite/gcc.dg/pr117476.c
> > > new file mode 100644
> > > index 00000000000..b8f51e697bf
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/pr117476.c
> > 
> > I think it might be better to put the test in gcc.c-torture/execute,
> > then it will automatically get run with the various torture options
> > and you should be able to drop both the dejagnu directives.
> Actually, gcc.dg/torture is better.

Oh, why's that (just so I know for next time)..?

Thanks,
Alex

> 
> jeff
>
Jeff Law Nov. 14, 2024, 2:14 p.m. UTC | #10
On 11/14/24 4:34 AM, Alex Coplan wrote:
> On 12/11/2024 10:56, Jeff Law wrote:
>>
>>
>> On 11/12/24 4:46 AM, Alex Coplan wrote:
>>> Hi Alexey,
>>>
>>> On 12/11/2024 08:18, Alexey Merzlyakov wrote:
>>>> gcc/ChangeLog:
>>>>
>>>> 	* simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
>>>> 	Fix subreg mode check during zero_extend(not) -> xor optimization.
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>>
>>>> 	* gcc.dg/pr117476.c: New test.
>>>>
>>>> Signed-off-by: Alexey Merzlyakov <alexey.merzlyakov@samsung.com>
>>>> ---
>>>>    gcc/simplify-rtx.cc             |  2 +-
>>>>    gcc/testsuite/gcc.dg/pr117476.c | 12 ++++++++++++
>>>>    2 files changed, 13 insertions(+), 1 deletion(-)
>>>>    create mode 100644 gcc/testsuite/gcc.dg/pr117476.c
>>>>
>>>> diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
>>>> index d05efac20dc..2a9cabaad09 100644
>>>> --- a/gcc/simplify-rtx.cc
>>>> +++ b/gcc/simplify-rtx.cc
>>>> @@ -1856,7 +1856,7 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
>>>>    	  && subreg_lowpart_p (op)
>>>>    	  && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
>>>>    	  && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
>>>> -	      & ~GET_MODE_MASK (mode)) == 0)
>>>> +	      & ~GET_MODE_MASK (GET_MODE (op))) == 0)
>>>>          {
>>>>    	const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
>>>>    	return simplify_gen_binary (XOR, mode,
>>>> diff --git a/gcc/testsuite/gcc.dg/pr117476.c b/gcc/testsuite/gcc.dg/pr117476.c
>>>> new file mode 100644
>>>> index 00000000000..b8f51e697bf
>>>> --- /dev/null
>>>> +++ b/gcc/testsuite/gcc.dg/pr117476.c
>>>
>>> I think it might be better to put the test in gcc.c-torture/execute,
>>> then it will automatically get run with the various torture options
>>> and you should be able to drop both the dejagnu directives.
>> Actually, gcc.dg/torture is better.
> 
> Oh, why's that (just so I know for next time)..?
The dg-torture is considered a more modern framework, c-torture is legacy.
jeff
diff mbox series

Patch

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index d05efac20dc..2a9cabaad09 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -1856,7 +1856,7 @@  simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 	  && subreg_lowpart_p (op)
 	  && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
 	  && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
-	      & ~GET_MODE_MASK (mode)) == 0)
+	      & ~GET_MODE_MASK (GET_MODE (op))) == 0)
       {
 	const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
 	return simplify_gen_binary (XOR, mode,
diff --git a/gcc/testsuite/gcc.dg/pr117476.c b/gcc/testsuite/gcc.dg/pr117476.c
new file mode 100644
index 00000000000..b8f51e697bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr117476.c
@@ -0,0 +1,12 @@ 
+/* PR rtl-optimization/117476 */
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+
+int c = 0x1FF;
+
+int main()
+{
+  if (((c ^ 0xFF) & 0xFF) != 0)
+    __builtin_abort();
+  return 0;
+}