On 1/15/07, Richard Guenther <[EMAIL PROTECTED]> wrote:
On 1/15/07, pranav bhandarkar <[EMAIL PROTECTED]> wrote:
> Hello Everyone,
> I have the following source code
>
> static int i;
> static char a;
>
> char foo_gen(int);
> void foo_assert(char);
> void foo ()
> {
> int *x = &i;
> a = foo_gen(0);
> a |= 1; /* ----1-----*/
> if (*x) goto end:
> a | =1; /* -----2------*/
> foo_assert(a);
> end:
> return;
> }
>
> Now I expect the CSE pass to realise that 1 and 2 are equal and eliminate 2.
> However the RTL code before the first CSE pass the RTL snippet is as
follows
>
> (insn 11 9 12 0 (set (reg:SI 1 $c1)
> (const_int 0 [0x0])) 43 {*movsi} (nil)
> (nil))
>
> (call_insn 12 11 13 0 (parallel [
> (set (reg:SI 1 $c1)
> (call (mem:SI (symbol_ref:SI ("gen_T") [flags 0x41]
> <function_decl 0xb7d54e00 gen_T>) [0 S4 A32])
> (const_int 0 [0x0])))
> (use (const_int 0 [0x0]))
> (clobber (reg:SI 31 $link))
> ]) 39 {*call_value_direct} (nil)
> (nil)
> (expr_list:REG_DEP_TRUE (use (reg:SI 1 $c1))
> (nil)))
>
> (insn 13 12 14 0 (set (reg:SI 137)
> (reg:SI 1 $c1)) 43 {*movsi} (nil)
> (nil))
>
> (insn 14 13 16 0 (set (reg:SI 135 [ D.1217 ])
> (reg:SI 137)) 43 {*movsi} (nil)
> (nil))
>
> (insn 16 14 17 0 (set (reg:SI 138)
> (ior:SI (reg:SI 135 [ D.1217 ])
> (const_int 1 [0x1]))) 63 {iorsi3} (nil)
> (nil))
>
> (insn 17 16 18 0 (set (reg:SI 134 [ D.1219 ])
> (zero_extend:SI (subreg:QI (reg:SI 138) 0))) 84 {zero_extendqisi2}
(nil)
> (nil))
>
> (insn 18 17 19 0 (set (reg/f:SI 139)
> (symbol_ref:SI ("a") [flags 0x2] <var_decl 0xb7d5d05c a>)) 43
> {*movsi} (nil)
> (nil))
>
> (insn 19 18 21 0 (set (mem/c/i:QI (reg/f:SI 139) [0 a+0 S1 A8])
> (subreg/s/u:QI (reg:SI 134 [ D.1219 ]) 0)) 56 {*movqi} (nil)
> (nil))
>
> <<<<< expansion of the if condition >>>>>>>>
>
> ;; End of basic block 0, registers live:
> (nil)
>
> ;; Start of basic block 1, registers live: (nil)
> (note 25 23 27 1 [bb 1] NOTE_INSN_BASIC_BLOCK)
>
> (insn 27 25 28 1 (set (reg:SI 142)
> (ior:SI (reg:SI 134 [ D.1219 ])
> (const_int 1 [0x1]))) 63 {iorsi3} (nil)
> (nil))
>
> (insn 28 27 29 1 (set (reg:SI 133 [ temp.28 ])
> (zero_extend:SI (subreg:QI (reg:SI 142) 0))) 84 {zero_extendqisi2}
(nil)
> (nil))
>
> (insn 29 28 30 1 (set (reg/f:SI 143)
> (symbol_ref:SI ("a") [flags 0x2] <var_decl 0xb7d5d05c a>)) 43
> {*movsi} (nil)
> (nil))
>
> (insn 30 29 32 1 (set (mem/c/i:QI (reg/f:SI 143) [0 a+0 S1 A8])
> (subreg/s/u:QI (reg:SI 133 [ temp.28 ]) 0)) 56 {*movqi} (nil)
> (nil))
>
>
>
> Now the problem is that the CSE pass doesnt identify that the source
> of the set in insn 27 is equivalent to the source of the set in insn
> 16. This It seems happens because of the zero_extend in insn 17. I am
> using a 4.1 toolchain. However with a 3.4.6 toolchain no zero_extend
> gets generated and the result of the ior operation is immediately
> copied into memory. I am compiling this case with -O3. Can anybody
> please tell me how this problem can be overcome.
CSE/FRE or VRP do not track bit operations and CSE of bits. To overcome this
you need to implement such.
Thanks. Another question I have is that, in this case, will the following
http://gcc.gnu.org/wiki/Sign_Extension_Removal
help in removal of the sign / zero extension ?
Thanks in Advance,
Pranav