Hi all,

Can gatekeeper help review for a fix for bug860.
https://bugs.open64.net/show_bug.cgi?id=860

Problem: case buffer.c at line 60:
    58   for (i = 0; i < 8; i++)
    59     {
    60       struct buffer_head *bh = lru->bhs[i];

when compile at O2:
   112  #  60        struct buffer_head *bh = lru->bhs[i];
   113         movq 0(%rax),%r8                # [0] id:56       #kernel
boot fail at here

%rax come from:
72  #  45    lru = &(*(
    73  #  46               {
    74  #  47    unsigned long __ptr;
    75  #  48    __asm__ ("": "=r" (__ptr):"0" ((&per_cpu__bh_lrus)));
    76         movq $(.data.percpu),%rax       # [0] .data.percpu
    77
    78 .LBB3_lookup_bh_lru:
              #here should have a move from %rax to %r11
    79         movq %gs:per_cpu__this_cpu_off(%rip),%r8
    80 .LBB4_lookup_bh_lru:
    81         .loc    1       58      0
    82  #  54       ret__;}
    83  #  55     ))));}
    84  #  56    ));
    85  #  57
    86  #  58    for (i = 0; i < 8; i++)
    87         movq 32(%rsp),%r9               # [0] bdev
    88         movq 40(%rsp),%r10              # [0] block
    89         .loc    1       54      0
    90         leaq 0(%r8,%r11,1), %rdx        # [0]            %r11 is
never defined before
    91         xorq %rsi,%rsi                  # [1]
    92         xorl %ecx,%ecx                  # [1]
    93         movq %r8,.bss+8(%rip)           # [1] id:54 anon2+0x0
    94         .loc    1       58      0
    95         movq %rdx,%rax                  # [2]

The root reason is "[  48, 0] GTN152 :- mov64 GTN151 ; copy"    is deleted
at EBO_Remove_Unused_Ops, but it has use at BB4 and should not be deleted.

// Block: 3 Pred: 2 Succ: 4

[  48, 0] GTN152 :- mov64 GTN151 ; copy           //deleted at
EBO_Remove_Unused_Ops

|||||[53]     asm ("mov" "q " "%%" "gs" ":%P" "1" ",%0": "=r" (ret__):"m"
(per_cpu__this_cpu_off));

[  53, 0] GTN153 :- asm (sym:per_cpu__this_cpu_off+0) ; side_effects


// Block: 4 Pred: 3 Succ: 5

-----------------------------------------------------------------------

|||||[54]     ret__;}

[  54, 0] :- store64 GTN153 GTN34(%rip) (sym:.bss+8) ; WN id:54 anon2+0x0

[  54, 0] GTN156 :- leax64 GTN153 GTN152 (0x1) (0x0) ;

[  54, 0] :- store64 GTN156 GTN34(%rip) (sym:.bss+0) ; WN id:55 anon1+0x0

[   0, 0] GTN157 :- zero32 ;

[   0, 0] GTN159 :- zero64 ;



Then found at fun EBO_Remove_Unused_Ops, for TN152, its
tninfo->redefined_before_block_end is true.

3370      /* Check for indirect and global references.   */
3371       if (!tninfo->redefined_before_block_end &&
3372           TN_live_out_of(tn, tninfo->in_bb)) goto op_is_needed;
3373


redefined_before_block_end set to true is because at
CGTARG_Gen_Dedicated_Subclass_TN,
TN153 will always return ISA_REGISTER_SUBCLASS_r11 (because the opcode is
"TOP_asm"),  which is the same register for TN152.  but infact its fixed
number of operands or results are 0, and should not have register set info.

   4041 TN* CGTARG_Gen_Dedicated_Subclass_TN( OP* op, int idx, BOOL
is_result )
   4042 {
   4043   const ISA_REGISTER_SUBCLASS subclass = is_result ?
   4044     OP_result_reg_subclass( op, idx ) : OP_opnd_reg_subclass( op,
idx );
   4045   const REGISTER_SET subclass_regs =
REGISTER_SUBCLASS_members(subclass);
   4046
   4047   if( REGISTER_SET_Size(subclass_regs) != 1 ){
   4048     TN* tn = is_result ? OP_result( op, idx ) : OP_opnd( op, idx );
   4049     return TN_is_dedicated(tn) ? tn : NULL;
   4050   }
   4051
   4052   const REGISTER reg = REGISTER_SET_Choose(subclass_regs);
   4053   const ISA_REGISTER_CLASS rc =
REGISTER_SUBCLASS_register_class(subclass);
   4054
   4055   return Build_Dedicated_TN( rc, reg, 0 );
   4056 }


The fix is to add check on the idx, make sure it did not overlap fixed opnd
or results.


Thanks

zhuqing
extern __attribute__ ((section (".data.percpu" ""))) __typeof__ (unsigned long) per_cpu__this_cpu_off;

static inline void native_irq_disable (void)
{
  asm volatile ("cli":::"memory");
}


static inline void raw_local_irq_disable (void)
{
  native_irq_disable ();
}

struct buffer_head
{
  unsigned long b_blocknr;
  unsigned long b_size;
  struct block_device *b_bdev;
};

static inline void get_bh (struct buffer_head *bh)
{
}

struct bh_lru
{
  struct buffer_head *bhs[8];
};

static
  __attribute__ ((section (".data.percpu" ""))) __typeof__ (struct bh_lru)
  per_cpu__bh_lrus =
{
};

static struct buffer_head *
lookup_bh_lru (struct block_device *bdev, unsigned long block, unsigned size)
{
  struct buffer_head *ret = ((void *) 0);
  struct bh_lru *lru;
  unsigned int i;
  raw_local_irq_disable ();


  lru = &(*(
             {
  unsigned long __ptr;
  __asm__ ("": "=r" (__ptr):"0" ((&per_cpu__bh_lrus)));
  (typeof ((&per_cpu__bh_lrus))) (__ptr +
  (((
   {
     typeof(per_cpu__this_cpu_off) ret__;
     asm ("mov" "q " "%%" "gs" ":%P" "1" ",%0": "=r" (ret__):"m" (per_cpu__this_cpu_off));
     ret__;}
   ))));}
  ));

  for (i = 0; i < 8; i++)
    {
      struct buffer_head *bh = lru->bhs[i];
      if (bh && bh->b_bdev == bdev && bh->b_blocknr == block
          && bh->b_size == size)
        {
          if (i)
            {
              while (i)
                {
                  lru->bhs[i] = lru->bhs[i - 1];
                  i--;
                }
            }
          ret = bh;
          break;
        }
    }
}

struct buffer_head *
__find_get_block (struct block_device *bdev, unsigned long block, unsigned size)
{
  struct buffer_head *bh = lookup_bh_lru (bdev, block, size);
}

Attachment: bug860.patch
Description: Binary data

------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure 
contains a definitive record of customers, application performance, 
security threats, fraudulent activity, and more. Splunk takes this 
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to