On Thu, 2024-07-18 at 20:41 +0800, Xi Ruoyao wrote:
> On Thu, 2024-07-18 at 19:54 +0800, Xi Ruoyao wrote:
> > On Tue, 2024-07-09 at 22:29 -0600, Jeff Law wrote:
> > > 
> > > 
> > > On 7/9/24 8:35 PM, Xi Ruoyao wrote:
> > > > On Mon, 2024-07-08 at 15:03 -0600, Jeff Law wrote:
> > > > > So I would use tmp (or another word_mode pseudo register) for the
> > > > > destination of that emit_insn.   Then something like:
> > > > > 
> > > > >         t = gen_lowpart (SImode, tmp);
> > > > >         SUBREG_PROMOTED_VAR_P (tmp) = 1;
> > > > >         SUBREG_PROMOTED_SET (tmp, SRP_SIGNED);
> > > > >         emit_move_insn (operands[0], tmp);
> > > > > 
> > > > > To the output into operands[0] with enough magic to allow us to
> > > > > potentially remove a subsequent sign extension.
> > > > 
> > > > I'd already tried this trick for LoongArch:
> > > > 
> > > > (define_int_attr fclass_optab
> > > >    [(68         "isinf")
> > > >     (136        "isnormal")
> > > >     (952        "isfinite")])
> > > > 
> > > > (define_expand "<FCLASS_MASK:fclass_optab><ANYF:mode>2"
> > > >    [(match_operand:SI   0 "register_operand" "=r")
> > > >     (match_operand:ANYF 1 "register_operand" " f")
> > > >     (const_int FCLASS_MASK)]
> > > >    "TARGET_HARD_FLOAT"
> > > >    {
> > > >      rtx ft0 = gen_reg_rtx (SImode);
> > > >      rtx t0 = gen_reg_rtx (word_mode);
> > > >      rtx mask = GEN_INT (<FCLASS_MASK>);
> > > > 
> > > >      emit_insn (gen_fclass_<ANYF:fmt> (ft0, operands[1]));
> > > > 
> > > >      if (TARGET_64BIT)
> > > >        emit_insn (gen_extend_insn (t0, ft0, DImode, SImode, 0));
> > > >      else
> > > >        emit_move_insn (t0, ft0);
> > > > 
> > > >      emit_move_insn (t0, gen_rtx_AND (word_mode, t0, mask));
> > > >      emit_move_insn (t0, gen_rtx_NE (word_mode, t0, const0_rtx));
> > > > 
> > > >      if (TARGET_64BIT)
> > > >        {
> > > >         t0 = lowpart_subreg (SImode, t0, DImode);
> > > >         SUBREG_PROMOTED_VAR_P (t0) = 1;
> > > >         SUBREG_PROMOTED_SET (t0, SRP_SIGNED);
> > > >        }
> > > > 
> > > >      emit_move_insn (operands[0], t0);
> > > > 
> > > >      DONE;
> > > >    })
> > > > 
> > > > But for a test case:
> > > > 
> > > > __attribute__ ((noipa)) int
> > > > test_fclass_f (float f)
> > > > {
> > > >    return __builtin_isinf (f)
> > > >           | __builtin_isnormal (f) << 1
> > > >           | __builtin_isfinite (f) << 2;
> > > > }
> > > > 
> > > > I still get:
> > > > 
> > > > test_fclass_f:
> > > >      fclass.s    $f0,$f0
> > > >      movfr2gr.s  $r4,$f0
> > > >      andi    $r12,$r4,136
> > > >      andi    $r13,$r4,952
> > > >      sltu    $r12,$r0,$r12
> > > >      sltu    $r13,$r0,$r13
> > > >      slli.w  $r13,$r13,2
> > > >      andi    $r4,$r4,68
> > > >      slli.w  $r12,$r12,1
> > > >      or  $r12,$r12,$r13
> > > >      sltu    $r4,$r0,$r4
> > > >      or  $r4,$r4,$r12
> > > >      andi    $r4,$r4,7     # <==== Why we need this?!
> > > You'll need to debug it.  It's not a zero or sign extension, so it's not 
> > > going to be impacted by the SUBREG_PROMOTED stuff.
> > 
> > Hmm it looks like the difference of LoongArch from RISC-V is lacking
> > WORD_REGISTER_OPERATIONS.  But this thing is really not suitable for
> > LoongArch...
> > 
> > I've no idea how to resolve this as at now.
> 
> Oops we actually have WORD_REGISTER_OPERATIONS.  It seems I have some
> trouble to understand what it really does and I'm too sleepy today...
> 
> And now I've even more puzzled.

Ok I get it.  The problem is we don't expand ashlsi3 to ashlsi3_extended
with a SUBREG_PROMOTED_VAR_P.  I was too focused on SImode vs. word_mode
in fclass but it seems not really relevant.

-- 
Xi Ruoyao <xry...@xry111.site>
School of Aerospace Science and Technology, Xidian University

Reply via email to