Hi Jeff, Do you have any suggestion about this case? Sorry for late response due to not receive the mail-thread (Copy the latest one from hongtao for reference). https://gcc.gnu.org/pipermail/gcc-patches/2023-March/614644.html Pan -------- On Sun, Mar 26, 2023 at 3:01 AM Jeff Law via Gcc-patches wrote: > > > > On 3/24/23 08:11, pan2.li--- via Gcc-patches wrote: > > From: Pan Li > > > > Fix the bug of the incorrect code generation for the > > below code sample. > > > > typedef unsigned short __attribute__((__vector_size__ (32))) V; > > typedef unsigned short u16; > > > > void > > foo (V m, u16 *ret) > > { > > V v = 6 > ((V) { 2049, 8 } & m); > > *ret = v[0]; // + a + b + c + d; > > } > > > > Before this patch. > > addi sp,sp,-64 > > ld a5,0(a0) > > li a4,528384 > > addi a4,a4,-2047 > > and a5,a5,a4 > > // slli a5,a5,48 <- eliminated by mistake > > // srli a5,a5,48 <- eliminated by mistake > > sltiu a5,a5,6 > > negw a5,a5 > > sh a5,0(a1) > > > > After this patch. > > addi sp,sp,-64 > > ld a5,0(a0) > > li a4,528384 > > addi a4,a4,-2047 > > and a5,a5,a4 > > slli a5,a5,48 > > srli a5,a5,48 > > sltiu a5,a5,6 > > negw a5,a5 > > sh a5,0(a1) > > > > The simplify_comparation for the AND operation will > > try to simplify below RTL code from: > > (and:DI (subreg:DI (reg:HI 154) 0) (const_int 0x801)) > > to: > > (subreg:DI (and (reg:HI 154) (const_int 0x801)) 0) > These look equivalent to me -- assuming they're used as rvalues. They're equivalent only when WORD_REGISTER_OPERATIONS, orelse the upper bits of latter is UD, but the former is 0. (and (reg:HI 154) (const_int 0x801)) is simplified to (reg:HI 154) since nonzero_bits (reg:154, HImode) is exactly same as 0x801. These two optimizations are fine on their own, but if they are put together, there are problems. The first optimization relies on the WORD_REGISTER_OPERATIONS, but the second optimize the operation off which make upper bits of (subreg:DI (reg:HI 154) 0) UD, but originally it should be 0 after AND (const_int 0x801). > > > > > > If reg:HI 154 is 0x801 and reg:DI 154 is 0x80801, the RTL will > > be simplified continuely to: > That statement has no meaning. Each pseudo has one and only one native > mode and you can only refer to it in that mode. ie reg:HI 154. reg:DI > 154 has no meaning. You might say that (subreg:DI (reg:HI 154) 0) has > the value 0x80801, but that's OK. The subreg says those bits outside > HImode simply don't matter -- you can not depend on them having any > particular value. > > > (subreg:DI (reg:HI 154) 0) > I think that's equivalent to (subreg:DI (and:HI (reg:HI 154) (const_int > 0x801)) 0) when used as an rvalue. > > I suspect your problem is elsewhere. > > jeff >