comp <comp_...@163.com> writes:
> Hi all,
> I recently have a problem with LRA.
> 1 The Bug use case
> int a=10;
> float c=2.0,d;
> main()
> {
>         float b;
>         *(int*)&b=a;
>         d=b+c;
> }
> 
> 2 The problem description
> In the pass LRA, curr_insn_transform () deal with the addition statement d = 
> b + c, the
> corresponding rtx expression in register allocation is as follows:
> (gdb) pr curr_insn
> (insn 9 8 10 2 (set (reg:SF 73 [ d ])
>         (plus:SF (reg:SF 79 [ c ])
>             (subreg:SF (reg:SI 77 [ a ]) 0))) test.c:7 121 {addsf3}
>      (expr_list:REG_DEAD (reg:SF 79 [ c ])
>         (expr_list:REG_DEAD (reg:SI 77 [ a ])
>             (nil))))
> The corresponding addsf3 template in the .md file is defined as follows:
> (define_insn "add<mode>3"
>   [(set (match_operand:FMODE 0 "register_operand" "=f")
>         (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
>                     (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
>   "TARGET_FP"
>   "fadd<modesuffix>%/ %R1,%R2,%0"
>   [(set_attr "type" "fadd"))
> 
> curr_insn_transform() calls process_alt_operands() for matching constraints, 
> the matching
> of operands 0, 1, and 2 are all successful, where the main matching processes 
> of the
> second operand, i.e.(subreg: SF (reg: SI 77 [a]) 0) are as follows:
> op = no_subreg_reg_operand[nop], where nop=2;
> Here get op: (reg:SI 77 [ a ])
> mode = curr_operand_mode[nop];
> Here get mode: SFmode
> cl = reg_class_for_constraint (cn)
> Here get cn: CONSTRAINT_f£¬and cl:FLOAT_REGS
> 
> FLOAT_REGS is defined as the ability to allocate all hard registers in the
> REG_CLASS_CONTENTS macro that describes the processor¡¯s registers in the 
> machine
> description. so that the matching key function in_hard_reg_set_p 
> (this_alternative_set,
> mode, hard_regno [nop]) returns true, where psudo reg 77 is assigned $1 hard 
> reg in the
> pass IRA.i.e. hard_regno[nop]=1. The hardware register $1 belongs to 
> FLOAT_REGS and also
> belongs to GENERAL_REGS, but it was derived from the integer a, so the before 
> matched
> instruction that generated $1 as the destination register is an integer kind 
> load
> instruction ldw. Thus the d = b + c statement generates the instruction:
> fadds $ 48, $ 1, $ 48, where c is assigned to $48, b is assigned to $1, and 
> the result d
> lies in $48. The result is the following instructions:
> ldw $1,a($1)
> flds $48,c($2)
> fadds $48,$1,$48
> The problem lies in the second source operand of the floating-point addition 
> fadds
> instruction , $48 is obtained by floating-point load instruction flds, but $1 
> is obtained
> by the integer load instruction ldw, so the result is wrong, we hope that the
> process_alt_operands() results a match failure, and a reload may generate 
> that turns ldw
> to flds instruction.

Isn't this a CANNOT_CHANGE_MODE_CLASS issue then? I.e. don't allow it to be 
reinterpreted
from integer mode to floating point mode.

> 3 The comparative test
> In contrast, if the $1 in the REG_CLASS_CONTENTS register category is defined 
> as not
> belonging to FLOAT_REGS, the above process_alt_operands () returns false when 
> the second
> operand is matched(in_hard_reg_set_p (this_alternative_set, mode, hard_regno 
> [nop])
> returns fail), and so a reload is triggered, an ifmovs instruction will 
> generate to move
> the contents of the integer register to the floating point register. the 
> following
> instructions is correct:
> ldw $1,a($1)
> flds $f11,c($2)
> ifmovs $1,$f10
> fadds $f11,$f10,$f11

This is not consistent with the previous example code as the floating point 
registers now
have 'f' prefixes but did not before.

You will need to explain more about what registers are available and how they 
can be used
(or not as the case may be).

If this issue ends up anywhere near subreg handling inside LRA then please keep 
me on CC. I
think this is likely to just be a backend issue from the description so far 
though.

Thanks,
Matthew

Reply via email to