Hi all: I have found something strange when scheduling instructions. considering following piece of code: -------------------------------------------------c start int func(float x) { int r = 0; r = (*(unsigned int*)&x) >> 23; return r; } -------------------------------------------------c end
the return value is different when compiling with or without optimization. Have tested on 4.2.4 and 4.3.3 on mips, 4.3.2(ubuntu) on x86 and results are the same. Is this a bug, or something wrong with the example code? following is output for mips target, hope it can help. commands: mipsel-elf-gcc -march=mips1 -EL -G0 -mabi=32 -S test/dummy.c -o test/dummy.S -fdump-rtl-all -fsched-verbose=9 -v -O2 the as output is : -------------------------------------------------as start .section .mdebug.abi32 .previous .text .align 2 .globl func .ent func func: .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0 .mask 0x00000000,0 .fmask 0x00000000,0 .set noreorder .set nomacro lw $2,0($sp) sw $4,0($sp) j $31 srl $2,$2,23 .set macro .set reorder .end func .size func, .-func .ident "GCC: (GNU) 4.2.4" --------------------------------------------------as end it seems the load insn is scheduled before store, which resulting in using of uninitialized data. following is the dumped rtls before and after sched1: before sched1: --------------------------------------------------- (note 8 2 6 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (insn 6 8 7 2 (set (mem/c/i:SF (reg/f:SI 77 $arg) [3 x+0 S4 A32]) (reg:SF 4 $4 [ x ])) 233 {*movsf_softfloat} (nil) (expr_list:REG_DEAD (reg:SF 4 $4 [ x ]) (nil))) (note 7 6 12 2 NOTE_INSN_FUNCTION_BEG) (insn 12 7 13 2 (set (reg:SI 196) (mem:SI (reg/f:SI 77 $arg) [4 S4 A32])) 213 {*movsi_internal} (nil) (nil)) ----------------------------------------------------- after sched1: --------------------------------------------------- (insn 12 17 6 2 (set (reg:SI 196) (mem:SI (reg/f:SI 77 $arg) [4 S4 A32])) 213 {*movsi_internal} (nil) (nil)) (insn 6 12 20 2 (set (mem/c/i:SF (reg/f:SI 77 $arg) [3 x+0 S4 A32]) (reg:SF 4 $4 [ x ])) 233 {*movsf_softfloat} (nil) (expr_list:REG_DEAD (reg:SF 4 $4 [ x ]) (nil))) ----------------------------------------------------- have checked gcc's source, It seems the two mem operands in insn12 and insn6 is computed into two different alias sets, so maybe this problem have something to do with the force type cast? The result is very strange, so please help and any comments will be highly appreciated. -- Best Regards.