[Bug target/104914] New: [MIPS] wrong comparison with scrabbled int value
mmyangfl at gmail dot com
gcc-bugzilla@gcc.gnu.org
Mon Mar 14 11:49:37 GMT 2022
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104914
Bug ID: 104914
Summary: [MIPS] wrong comparison with scrabbled int value
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: mmyangfl at gmail dot com
Target Milestone: ---
GCC 12.0 (current git master, 80fcc4b) and 11 generates wrong instructions for
this code. (older version not tested)
$ mips64el-img-elf-gcc -mabi=64 -S -O1 -o - ~/a.c
#include <stdio.h>
void test(const unsigned char *buf) {
int val;
((unsigned char*)&val)[0] = *buf++;
((unsigned char*)&val)[1] = *buf++;
((unsigned char*)&val)[2] = *buf++;
((unsigned char*)&val)[3] = *buf++;
if(val > 0)
puts("a");
else
fputs("b", stderr);
}
int main() { test("\xff\xff\xff\xff"); } // => "a"
Generated asm code in question:
test:
.frame $sp,16,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
.mask 0x80000000,-8
.fmask 0x00000000,0
.set noreorder
.set nomacro
daddiu $sp,$sp,-16
sd $31,8($sp)
lbu $3,0($4)
move $2,$0
dins $2,$3,0,8
lbu $3,1($4)
dins $2,$3,8,8
lbu $3,2($4)
dins $2,$3,16,8
lbu $3,3($4)
dins $2,$3,24,8
blezc $2,.L2 // signed extending $2 missing!
lui $4,%highest(.LC0)
lui $2,%hi(.LC0)
daddiu $4,$4,%higher(.LC0)
daddiu $2,$2,%lo(.LC0)
dsll $4,$4,32
daddu $4,$4,$2
balc puts
ld $31,8($sp)
.L5:
daddiu $sp,$sp,16
jrc $31
.L2:
ld $2,%gp_rel(_impure_ptr)($28)
ld $5,24($2)
li $4,98 # 0x62
balc fputc
b .L5
ld $31,8($sp)
Below are my attempts to fix this bug:
-fdump-final-insns gives the following statement:
(jump_insn # 0 0 (set (pc)
(if_then_else (le (reg:SI 2 $2 [orig:201 val ] [201])
(const_int 0 [0]))
(label_ref #)
(pc))) "/home/ding/a.c":8:5# {*branch_ordersi}
(expr_list:REG_DEAD (reg:SI 2 $2 [orig:201 val ] [201])
(int_list:REG_BR_PROB 440234148 (nil)))
-> 2)
After manually `icode != CODE_FOR_cbranchsi4` in gcc/gcc/optabs.cc:4501,
combine pass still combines them back, but the machine description simply
define "cbranch<mode>4" for all cbranch family.
I wonder since MIPS64 can't really do comparsion over partial register, is this
RTL valid?
More information about the Gcc-bugs
mailing list