Hi All,

GCC 4.1.1

This small bit of code from one of the test suites (
gcc.c-torture/execute/20020611-1.c)worked fine with all optimization
except size optimization -Os.
unsigned int p;
unsigned int n = 30;
void x ()
{
unsigned int h;
h = n <= 30;           // Line 1
if (h)
 p = 1;
else
 p = 0;
}

When we tried to debug the emitted RTL instruction for Os, it was
found that RTL instruction for Line #1 were not at all emitted. i.e.
there is no  reference with respect to "h or n" (Instructions 11, 12,
13 are not emitted in life1 pass). For the same optimization Os, if we
use "h" anywhere else in the program or declare the identifier "h" as
global, it generates the instructions properly.

While debugging, it was also found that the above mentioned
instructions were removed because of Global Common Sub-expression
Elimination (–fgcse) pass. More specifically, it was removed while
doing Code Hoisting optimization. If we disable code hoisting in gcc
source files or if we compile the code with –Os –fno-gcse flag, the
above mentioned code works fine.

The relevant part of RTL dump of fgcse pass  is given below:

(insn 13 12 50 0 (set (reg:CC 21 cc)
       (compare:CC (reg:SI 29 [ n ])
           (const_int 30 [0x1e]))) 68 {*cmpsi_internal} (nil)
   (nil))

(insn 50 13 53 0 (parallel [
           (set (reg/f:SI 38)
               (symbol_ref:SI ("p") <var_decl 0x402270b0 p>))
           (clobber (reg:CC 21 cc))
       ]) 22 {movsi_long_const} (nil)
   (nil))

(insn 53 50 14 0 (parallel [
           (set (reg/f:SI 39)
               (symbol_ref:SI ("k") <var_decl 0x40227108 k>))
           (clobber (reg:CC 21 cc))
       ]) 22 {movsi_long_const} (nil)
   (nil))

(jump_insn 14 53 16 0 (set (pc)
       (if_then_else (gtu:CC (reg:CC 21 cc)
               (const_int 0 [0x0]))
           (label_ref 27)
           (pc))) 41 {*branch_true} (nil)
   (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
       (nil)))

1. In Insn 13, the compiler uses the CC Reg instead of "h".  Then the
compiler inserted to movsi_long_const inbetween the compare and the
if_then_else.  BUT the movsi_long_const destroys the condition code
register CC .As the optimizer considers CC dead  due to the
clobber(reg:CC 21 cc)) it removes the first pattern actually setting
CC. It gets deleted later.

But in 3.2  the compiler never  inserted the movsi_long_const
instructions between compare and the actual branch.

2. We removed the clobbering from the movsi_long_const pattern. Then
this test case gets through. But there are many other test cases which
fail due to this changes for different optimization levels. Then we
tried to emit the instruction without clobbering  for -Os only. This
test case gets through but there are some other test case failures for
-Os only.

I have given the instruction below : I have masked clobber for the
last pattern(r, i) that too only for size optimization.

(define_insn "movsi_long_const"
 [(set (match_operand:SI 0 "scalar_reg"    "=d,d,r,r")
       (match_operand:SI 1 "immediate_operand" "L,n,n,i"))
  (clobber (reg:CC CC_REGNUM))]
 ""
 "*
  {

Is there any other thing that i can do to overcome this error?

Regards,
Rohit

Reply via email to