* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
@ 2023-11-29 18:18 ` pinskia at gcc dot gnu.org
2023-12-08 2:57 ` guminb at ajou dot ac.kr
` (18 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-11-29 18:18 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|target |rtl-optimization
Last reconfirmed| |2023-11-29
Summary|Inconsistent Bitwise AND |[13/14 Regression]
|Operation Result between |Inconsistent Bitwise AND
|int and long long int on |Operation Result between
|Different Optimization |int and long long int
|Levels in GCC Trunk |
Keywords| |needs-bisection
Ever confirmed|0 |1
Target Milestone|--- |13.3
Status|UNCONFIRMED |NEW
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Trying 21, 18 -> 22:
21: r149:DI=0xffff00ffffffffff
18: r147:DI=sign_extend([r143:DI+low(`globalVar')])
REG_DEAD r143:DI
22: r148:DI=r147:DI&r149:DI
REG_DEAD r149:DI
REG_DEAD r147:DI
REG_EQUAL r147:DI&0xffff00ffffffffff
Successfully matched this instruction:
(set (reg:DI 148)
(zero_extend:DI (mem/c:SI (lo_sum:DI (reg/f:DI 143)
(symbol_ref:DI ("globalVar") [flags 0x86] <var_decl
0x7f79b69e8090 globalVar>)) [1 globalVarD.2927+0 S4 A32])))
allowing combination of insns 18, 21 and 22
original costs 32 + 4 + 4 = 40
replacement cost 32
That is almost definitely wrong.
Was working in GCC 12 but started to go wrong in GCC 13.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
2023-11-29 18:18 ` [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int pinskia at gcc dot gnu.org
@ 2023-12-08 2:57 ` guminb at ajou dot ac.kr
2023-12-08 17:01 ` jakub at gcc dot gnu.org
` (17 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: guminb at ajou dot ac.kr @ 2023-12-08 2:57 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #2 from gyumin <guminb at ajou dot ac.kr> ---
Dear GCC Development Team,
I recently reported an inconsistency in the GCC compiler (RISC-V 64 version
14.0.0) involving bitwise AND operations between int and long long int
variables. This issue, which occurs under different optimization levels, has
been acknowledged, and I appreciate your response.
Given the nature of this bug, I am curious about its potential impact on
open-source projects. Specifically, I am concerned that the unexpected behavior
in bitwise operations under different optimization levels might introduce
vulnerabilities or other issues in open-source software that relies on precise
bitwise manipulations.
Could you please provide some insights on whether this bug might have security
implications for open-source projects? Also, are there any recommended
guidelines or best practices for developers to mitigate potential risks arising
from this issue in their projects?
Thank you for your attention to this matter.
Best regards,
[Gyumin Baek]
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
2023-11-29 18:18 ` [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int pinskia at gcc dot gnu.org
2023-12-08 2:57 ` guminb at ajou dot ac.kr
@ 2023-12-08 17:01 ` jakub at gcc dot gnu.org
2023-12-08 17:37 ` segher at gcc dot gnu.org
` (16 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-12-08 17:01 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |ebotcazou at gcc dot gnu.org,
| |jakub at gcc dot gnu.org,
| |law at gcc dot gnu.org,
| |segher at gcc dot gnu.org
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Seems expand_compound_operation is called on
(sign_extend:DI (mem/c:SI (lo_sum:DI (reg/f:DI 144)
(symbol_ref:DI ("globalVar") [flags 0x86] <var_decl 0x7fffea1f9b40
globalVar>)) [1 globalVar+0 S4 A32]))
and takes the
7336 tem = gen_lowpart (mode, XEXP (x, 0));
7337 if (!tem || GET_CODE (tem) == CLOBBER)
7338 return x;
7339 tem = simplify_shift_const (NULL_RTX, ASHIFT, mode,
7340 tem, modewidth - pos - len);
7341 tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT :
ASHIFTRT,
7342 mode, tem, modewidth - len);
path on it, mode being DImode, modewidth 64, pos 0, len 32.
The second simplify_shift_const is then called with
(ashift:DI (subreg:DI (mem/c:SI (lo_sum:DI (reg/f:DI 144)
(symbol_ref:DI ("globalVar") [flags 0x86] <var_decl
0x7fffea1f9b40 globalVar>)) [1 globalVar+0 S4 A32]) 0)
(const_int 32 [0x20]))
and triggers the
10810 /* If this was (ashiftrt (ashift foo C1) C2) and FOO has
more
10811 than C1 high-order bits equal to the sign bit, we can
convert
10812 this to either an ASHIFT or an ASHIFTRT depending on
the
10813 two counts.
10814
10815 We cannot do this if VAROP's mode is not
SHIFT_UNIT_MODE. */
10816
10817 if (code == ASHIFTRT && first_code == ASHIFT
10818 && int_varop_mode == shift_unit_mode
10819 && (num_sign_bit_copies (XEXP (varop, 0),
shift_unit_mode)
10820 > first_count))
10821 {
10822 varop = XEXP (varop, 0);
10823 count -= first_count;
10824 if (count < 0)
10825 {
10826 count = -count;
10827 code = ASHIFT;
10828 }
10829
10830 continue;
10831 }
optimization in there.
As RISC V is WORD_REGISTER_OPERATIONS target with load_extend_op (E_SImode) ==
SIGN_EXTEND, it triggers the:
5444 /* For paradoxical SUBREGs on machines where all register
operations
5445 affect the entire register, just look inside. Note that
we are
5446 passing MODE to the recursive call, so the number of sign
bit
5447 copies will remain relative to that mode, not the inner
mode.
5448
5449 This works only if loads sign extend. Otherwise, if we
get a
5450 reload for the inner part, it may be loaded from the
stack, and
5451 then we lose all sign bit copies that existed before the
store
5452 to the stack. */
5453 if (WORD_REGISTER_OPERATIONS
5454 && load_extend_op (inner_mode) == SIGN_EXTEND
5455 && paradoxical_subreg_p (x)
5456 && MEM_P (SUBREG_REG (x)))
5457 return cached_num_sign_bit_copies (SUBREG_REG (x), mode,
5458 known_x, known_mode,
known_ret);
path and so the sign-extension in the end folds into just a paradoxical subreg
of the MEM. But probably something in the combiner then just sees a
paradoxical SUBREG and thinks that all the bits above the SUBREG_REG are
undefined and picks ZERO_EXTEND.
I'm afraid I don't know enough about WORD_REGISTER_OPERATIONS to know what is
right and what is not.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (2 preceding siblings ...)
2023-12-08 17:01 ` jakub at gcc dot gnu.org
@ 2023-12-08 17:37 ` segher at gcc dot gnu.org
2023-12-08 19:33 ` jakub at gcc dot gnu.org
` (15 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: segher at gcc dot gnu.org @ 2023-12-08 17:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #4 from Segher Boessenkool <segher at gcc dot gnu.org> ---
WORD_REGISTER_OPERATIONS is extremely ill-defined. Or, it is used for other
things than what it stands for, whichever way you want to look at it.
A backend that defines the macro to non-zero promises that for *any* operation
on any values in a smaller than full-register mode, the compiler can instead
do the operation in that full-register mode, and all the resulting bits will
be well-defined. This is not true for most real non-trivial backends.
There is word_register_operation_p to filter out the most obvious and egregious
cases where WORD_REGISTER_OPERATIONS is just a foolish thing, but this function
isn't used nearly enough, and it doesn't filter out enough either.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (3 preceding siblings ...)
2023-12-08 17:37 ` segher at gcc dot gnu.org
@ 2023-12-08 19:33 ` jakub at gcc dot gnu.org
2023-12-08 19:36 ` jakub at gcc dot gnu.org
` (14 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-12-08 19:33 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Oh, and the reason why given the above
(and:DI (subreg:DI (mem/c:SI (lo_sum:DI (reg/f:DI 144)
(symbol_ref:DI ("globalVar") [flags 0x86] <var_decl
0x7fffea1f9b40 globalVar>)) [1 globalVar+0 S4 A32]) 0)
(const_int -280375465082881 [0xffff00ffffffffff]))
is optimized into the zero extension is the following in combine.cc:
/* If the one operand is a paradoxical subreg of a register or memory and
the constant (limited to the smaller mode) has only zero bits where
the sub expression has known zero bits, this can be expressed as
a zero_extend. */
else if (GET_CODE (XEXP (x, 0)) == SUBREG)
{
rtx sub;
sub = XEXP (XEXP (x, 0), 0);
machine_mode sub_mode = GET_MODE (sub);
int sub_width;
if ((REG_P (sub) || MEM_P (sub))
&& GET_MODE_PRECISION (sub_mode).is_constant (&sub_width)
&& sub_width < mode_width)
{
unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (sub_mode);
unsigned HOST_WIDE_INT mask;
/* original AND constant with all the known zero bits set */
mask = UINTVAL (XEXP (x, 1)) | (~nonzero_bits (sub, sub_mode));
if ((mask & mode_mask) == mode_mask)
{
new_rtx = make_compound_operation (sub, next_code);
new_rtx = make_extraction (mode, new_rtx, 0, 0, sub_width,
true, false, in_code == COMPARE);
}
}
}
clearly, if the sign_bit_copies stuff is right for wordmode paradoxical SUBREGs
of smaller MEMs with load_extend_op (MEM_mode) == SIGN_EXTEND, then this
optimization
needs to punt if those conditions are met and sub is a MEM.
Will defer this to people actually using WORD_REGISTER_OPERATIONS arches,
fortunately
none of the ones I'm involved with on a daily basis is.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (4 preceding siblings ...)
2023-12-08 19:33 ` jakub at gcc dot gnu.org
@ 2023-12-08 19:36 ` jakub at gcc dot gnu.org
2023-12-09 8:51 ` ebotcazou at gcc dot gnu.org
` (13 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-12-08 19:36 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I must say I have no idea what WORD_REGISTER_OPERATION says about the upper
bits of a paradoxical SUBREG if it is a MEM and load_extend_op (inner_mode) is
ZERO_EXTEND (zeros then? Then this optimization is ok), or something else?
And what it says on REGs.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (5 preceding siblings ...)
2023-12-08 19:36 ` jakub at gcc dot gnu.org
@ 2023-12-09 8:51 ` ebotcazou at gcc dot gnu.org
2023-12-09 9:11 ` jakub at gcc dot gnu.org
` (12 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: ebotcazou at gcc dot gnu.org @ 2023-12-09 8:51 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #7 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> I must say I have no idea what WORD_REGISTER_OPERATION says about the upper
> bits of a paradoxical SUBREG if it is a MEM and load_extend_op (inner_mode)
> is ZERO_EXTEND (zeros then?
Yes.
> Then this optimization is ok), or something else? And what it says on REGs.
That it contains the result of the operation that was applied to the SUBREG as
if it was applied to the entire REG, provided that word_register_operation_p is
true. Otherwise, it's undefined.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (6 preceding siblings ...)
2023-12-09 8:51 ` ebotcazou at gcc dot gnu.org
@ 2023-12-09 9:11 ` jakub at gcc dot gnu.org
2023-12-09 11:00 ` ebotcazou at gcc dot gnu.org
` (11 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-12-09 9:11 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Eric Botcazou from comment #7)
> > I must say I have no idea what WORD_REGISTER_OPERATION says about the upper
> > bits of a paradoxical SUBREG if it is a MEM and load_extend_op (inner_mode)
> > is ZERO_EXTEND (zeros then?
>
> Yes.
>
> > Then this optimization is ok), or something else? And what it says on REGs.
>
> That it contains the result of the operation that was applied to the SUBREG
> as if it was applied to the entire REG, provided that
> word_register_operation_p is true. Otherwise, it's undefined.
But if we see a REG in there, we don't really know what operation it was.
Sure, if the operation is visible, we know it, but say PLUS can be extended
either way.
Which means punt on this optimization for WORD_REGISTER_OPERATIONS if the outer
mode is word_mode, except when sub is a MEM and load_extend_op (inner_mode) ==
ZERO_EXTEND?
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (7 preceding siblings ...)
2023-12-09 9:11 ` jakub at gcc dot gnu.org
@ 2023-12-09 11:00 ` ebotcazou at gcc dot gnu.org
2023-12-09 19:25 ` segher at gcc dot gnu.org
` (10 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: ebotcazou at gcc dot gnu.org @ 2023-12-09 11:00 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #9 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> Which means punt on this optimization for WORD_REGISTER_OPERATIONS if the
> outer mode is word_mode, except when sub is a MEM and load_extend_op
> (inner_mode) == ZERO_EXTEND?
Yes, this sounds like a sensible approach.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (8 preceding siblings ...)
2023-12-09 11:00 ` ebotcazou at gcc dot gnu.org
@ 2023-12-09 19:25 ` segher at gcc dot gnu.org
2023-12-09 22:06 ` ebotcazou at gcc dot gnu.org
` (9 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: segher at gcc dot gnu.org @ 2023-12-09 19:25 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #10 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #6)
> I must say I have no idea what WORD_REGISTER_OPERATION says about the upper
> bits of a paradoxical SUBREG if it is a MEM and load_extend_op (inner_mode)
> is ZERO_EXTEND (zeros then? Then this optimization is ok), or something
> else? And what it says on REGs.
It says those upper bits are well-defined, i.e. whatever MD pattern is used for
it eventually will emit machine code that has the exact same result for those
upper bits. This is almost impossible to prove for any non-trivial target, and
certainly extremely fragile.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (9 preceding siblings ...)
2023-12-09 19:25 ` segher at gcc dot gnu.org
@ 2023-12-09 22:06 ` ebotcazou at gcc dot gnu.org
2023-12-10 12:16 ` segher at gcc dot gnu.org
` (8 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: ebotcazou at gcc dot gnu.org @ 2023-12-09 22:06 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #11 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> It says those upper bits are well-defined, i.e. whatever MD pattern is used
> for it eventually will emit machine code that has the exact same result for
> those upper bits.
No, that's not true, the set of "register operations" is restricted.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (10 preceding siblings ...)
2023-12-09 22:06 ` ebotcazou at gcc dot gnu.org
@ 2023-12-10 12:16 ` segher at gcc dot gnu.org
2023-12-13 22:06 ` pinskia at gcc dot gnu.org
` (7 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: segher at gcc dot gnu.org @ 2023-12-10 12:16 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #12 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to Eric Botcazou from comment #11)
> > It says those upper bits are well-defined, i.e. whatever MD pattern is used
> > for it eventually will emit machine code that has the exact same result for
> > those upper bits.
>
> No, that's not true, the set of "register operations" is restricted.
Who what where? That is not how it is documented. There is
word_register_operation_p as a bandaid to make it *somewhat* work, added
decades
later, but it still won't fly :-(
Different parts of the compiler think it has much more stringent semantics btw.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (11 preceding siblings ...)
2023-12-10 12:16 ` segher at gcc dot gnu.org
@ 2023-12-13 22:06 ` pinskia at gcc dot gnu.org
2023-12-16 18:43 ` gkm at rivosinc dot com
` (6 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-12-13 22:06 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |gkm at rivosinc dot com
--- Comment #13 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 113010 has been marked as a duplicate of this bug. ***
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (12 preceding siblings ...)
2023-12-13 22:06 ` pinskia at gcc dot gnu.org
@ 2023-12-16 18:43 ` gkm at rivosinc dot com
2023-12-21 20:04 ` gkm at rivosinc dot com
` (5 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: gkm at rivosinc dot com @ 2023-12-16 18:43 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #14 from Greg McGary <gkm at rivosinc dot com> ---
I bisected to here for the commit that broke the non-Zbs case:
https://github.com/gcc-mirror/gcc/commit/2e886eef7f2b5aadb00171af868f0895b647c3a4
... and here for Zbs case:
https://github.com/gcc-mirror/gcc/commit/4e1e0d79ecbe8727cb69d4cd97b20c71caaefafc
Note that the Zbs break happens with the commit that introduces Zbs handling,
i.e., it never worked with Zbs from the beginning.
In the non-Zbs case, it was the introduction of the insn_and_split pattern for
single-insn materialization of negative constants that allows the combiner to
create the problematic insn.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (13 preceding siblings ...)
2023-12-16 18:43 ` gkm at rivosinc dot com
@ 2023-12-21 20:04 ` gkm at rivosinc dot com
2023-12-21 20:06 ` jakub at gcc dot gnu.org
` (4 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: gkm at rivosinc dot com @ 2023-12-21 20:04 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #15 from Greg McGary <gkm at rivosinc dot com> ---
I have a simple patch for this which I will submit soon. The idea is to do
nothing in expand_compound_operation() when the pattern is (sign_extend (mem
...) ).
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (14 preceding siblings ...)
2023-12-21 20:04 ` gkm at rivosinc dot com
@ 2023-12-21 20:06 ` jakub at gcc dot gnu.org
2023-12-22 11:30 ` cvs-commit at gcc dot gnu.org
` (3 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-12-21 20:06 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #16 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Here is what I'd propose, but I can't really test it on any
WORD_REGISTER_OPERATIONS
target.
2023-12-21 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/112758
* combine.cc (make_compopund_operation_int): Optimize AND of a SUBREG
based on nonzero_bits of SUBREG_REG and constant mask on
WORD_REGISTER_OPERATIONS targets only if it is a zero extending
MEM load.
* gcc.c-torture/execute/pr112758.c: New test.
--- gcc/combine.cc.jj 2023-12-11 23:52:03.528513943 +0100
+++ gcc/combine.cc 2023-12-21 20:25:45.461737423 +0100
@@ -8227,12 +8227,20 @@ make_compound_operation_int (scalar_int_
int sub_width;
if ((REG_P (sub) || MEM_P (sub))
&& GET_MODE_PRECISION (sub_mode).is_constant (&sub_width)
- && sub_width < mode_width)
+ && sub_width < mode_width
+ && (!WORD_REGISTER_OPERATIONS
+ || sub_width >= BITS_PER_WORD
+ /* On WORD_REGISTER_OPERATIONS targets the bits
+ beyond sub_mode aren't considered undefined,
+ so optimize only if it is a MEM load when MEM loads
+ zero extend, because then the upper bits are all zero. */
+ || (MEM_P (sub)
+ && load_extend_op (sub_mode) == ZERO_EXTEND)))
{
unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (sub_mode);
unsigned HOST_WIDE_INT mask;
- /* original AND constant with all the known zero bits set */
+ /* Original AND constant with all the known zero bits set. */
mask = UINTVAL (XEXP (x, 1)) | (~nonzero_bits (sub, sub_mode));
if ((mask & mode_mask) == mode_mask)
{
--- gcc/testsuite/gcc.c-torture/execute/pr112758.c.jj 2023-12-21
21:01:43.780755959 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr112758.c 2023-12-21
21:01:30.521940358 +0100
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/112758 */
+
+int a = -__INT_MAX__ - 1;
+
+int
+main ()
+{
+ if (-__INT_MAX__ - 1U == 0x80000000ULL)
+ {
+ unsigned long long b = 0xffff00ffffffffffULL;
+ if ((b & a) != 0xffff00ff80000000ULL)
+ __builtin_abort ();
+ }
+ return 0;
+}
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (15 preceding siblings ...)
2023-12-21 20:06 ` jakub at gcc dot gnu.org
@ 2023-12-22 11:30 ` cvs-commit at gcc dot gnu.org
2024-03-02 0:37 ` cvs-commit at gcc dot gnu.org
` (2 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-12-22 11:30 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #17 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:cefae511ed7fa34ef6d24b67a7bc305459bf10e8
commit r14-6806-gcefae511ed7fa34ef6d24b67a7bc305459bf10e8
Author: Jakub Jelinek <jakub@redhat.com>
Date: Fri Dec 22 12:29:34 2023 +0100
combine: Don't optimize paradoxical SUBREG AND CONST_INT on
WORD_REGISTER_OPERATIONS targets [PR112758]
As discussed in the PR, the following testcase is miscompiled on RISC-V
64-bit, because num_sign_bit_copies in one spot pretends the bits in
a paradoxical SUBREG beyond SUBREG_REG SImode are all sign bit copies:
5444 /* For paradoxical SUBREGs on machines where all register
operations
5445 affect the entire register, just look inside. Note
that we are
5446 passing MODE to the recursive call, so the number of
sign bit
5447 copies will remain relative to that mode, not the
inner mode.
5448
5449 This works only if loads sign extend. Otherwise, if
we get a
5450 reload for the inner part, it may be loaded from the
stack, and
5451 then we lose all sign bit copies that existed before
the store
5452 to the stack. */
5453 if (WORD_REGISTER_OPERATIONS
5454 && load_extend_op (inner_mode) == SIGN_EXTEND
5455 && paradoxical_subreg_p (x)
5456 && MEM_P (SUBREG_REG (x)))
and then optimizes based on that in one place, but then the
r7-1077 optimization triggers in and treats all the upper bits in
paradoxical SUBREG as undefined and performs based on that another
optimization. The r7-1077 optimization is done only if SUBREG_REG
is either a REG or MEM, from the discussions in the PR seems that if
it is a REG, the upper bits in paradoxical SUBREG on
WORD_REGISTER_OPERATIONS targets aren't really undefined, but we can't
tell what values they have because we don't see the operation which
computed that REG, and for MEM it depends on load_extend_op - if
it is SIGN_EXTEND, the upper bits are sign bit copies and so something
not really usable for the optimization, if ZERO_EXTEND, they are zeros
and it is usable for the optimization, for UNKNOWN I think it is better
to punt as well.
So, the following patch basically disables the r7-1077 optimization
on WORD_REGISTER_OPERATIONS unless we know it is still ok for sure,
which is either if sub_width is >= BITS_PER_WORD because then the
WORD_REGISTER_OPERATIONS rules don't apply, or load_extend_op on a MEM
is ZERO_EXTEND.
2023-12-22 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/112758
* combine.cc (make_compopund_operation_int): Optimize AND of a
SUBREG
based on nonzero_bits of SUBREG_REG and constant mask on
WORD_REGISTER_OPERATIONS targets only if it is a zero extending
MEM load.
* gcc.c-torture/execute/pr112758.c: New test.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (16 preceding siblings ...)
2023-12-22 11:30 ` cvs-commit at gcc dot gnu.org
@ 2024-03-02 0:37 ` cvs-commit at gcc dot gnu.org
2024-03-04 1:09 ` law at gcc dot gnu.org
2024-03-04 12:07 ` [Bug rtl-optimization/112758] [13 " jakub at gcc dot gnu.org
19 siblings, 0 replies; 21+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-03-02 0:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #18 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-13 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:e7c9aafd7c2c3f3b68e65ddc999808cce75a19b3
commit r13-8379-ge7c9aafd7c2c3f3b68e65ddc999808cce75a19b3
Author: Jakub Jelinek <jakub@redhat.com>
Date: Fri Dec 22 12:29:34 2023 +0100
combine: Don't optimize paradoxical SUBREG AND CONST_INT on
WORD_REGISTER_OPERATIONS targets [PR112758]
As discussed in the PR, the following testcase is miscompiled on RISC-V
64-bit, because num_sign_bit_copies in one spot pretends the bits in
a paradoxical SUBREG beyond SUBREG_REG SImode are all sign bit copies:
5444 /* For paradoxical SUBREGs on machines where all register
operations
5445 affect the entire register, just look inside. Note
that we are
5446 passing MODE to the recursive call, so the number of
sign bit
5447 copies will remain relative to that mode, not the
inner mode.
5448
5449 This works only if loads sign extend. Otherwise, if
we get a
5450 reload for the inner part, it may be loaded from the
stack, and
5451 then we lose all sign bit copies that existed before
the store
5452 to the stack. */
5453 if (WORD_REGISTER_OPERATIONS
5454 && load_extend_op (inner_mode) == SIGN_EXTEND
5455 && paradoxical_subreg_p (x)
5456 && MEM_P (SUBREG_REG (x)))
and then optimizes based on that in one place, but then the
r7-1077 optimization triggers in and treats all the upper bits in
paradoxical SUBREG as undefined and performs based on that another
optimization. The r7-1077 optimization is done only if SUBREG_REG
is either a REG or MEM, from the discussions in the PR seems that if
it is a REG, the upper bits in paradoxical SUBREG on
WORD_REGISTER_OPERATIONS targets aren't really undefined, but we can't
tell what values they have because we don't see the operation which
computed that REG, and for MEM it depends on load_extend_op - if
it is SIGN_EXTEND, the upper bits are sign bit copies and so something
not really usable for the optimization, if ZERO_EXTEND, they are zeros
and it is usable for the optimization, for UNKNOWN I think it is better
to punt as well.
So, the following patch basically disables the r7-1077 optimization
on WORD_REGISTER_OPERATIONS unless we know it is still ok for sure,
which is either if sub_width is >= BITS_PER_WORD because then the
WORD_REGISTER_OPERATIONS rules don't apply, or load_extend_op on a MEM
is ZERO_EXTEND.
2023-12-22 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/112758
* combine.cc (make_compopund_operation_int): Optimize AND of a
SUBREG
based on nonzero_bits of SUBREG_REG and constant mask on
WORD_REGISTER_OPERATIONS targets only if it is a zero extending
MEM load.
* gcc.c-torture/execute/pr112758.c: New test.
(cherry picked from commit cefae511ed7fa34ef6d24b67a7bc305459bf10e8)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13/14 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (17 preceding siblings ...)
2024-03-02 0:37 ` cvs-commit at gcc dot gnu.org
@ 2024-03-04 1:09 ` law at gcc dot gnu.org
2024-03-04 12:07 ` [Bug rtl-optimization/112758] [13 " jakub at gcc dot gnu.org
19 siblings, 0 replies; 21+ messages in thread
From: law at gcc dot gnu.org @ 2024-03-04 1:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
--- Comment #19 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Fixed by Jakub's patch on the trunk.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Bug rtl-optimization/112758] [13 Regression] Inconsistent Bitwise AND Operation Result between int and long long int
2023-11-29 6:05 [Bug c/112758] New: Inconsistent Bitwise AND Operation Result between int and long long int on Different Optimization Levels in GCC Trunk guminb at ajou dot ac.kr
` (18 preceding siblings ...)
2024-03-04 1:09 ` law at gcc dot gnu.org
@ 2024-03-04 12:07 ` jakub at gcc dot gnu.org
19 siblings, 0 replies; 21+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-03-04 12:07 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112758
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|--- |FIXED
Status|NEW |RESOLVED
--- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Should be now fixed for GCC 13 too.
^ permalink raw reply [flat|nested] 21+ messages in thread