https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127903

            Bug ID: 127903
           Summary: simplify-rtx: bit-cast of an unordered vector
                    comparison is folded to a constant zero
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: guojie at loongson dot cn
  Target Milestone: ---

Testcase(t.c):
    typedef float v4f32 __attribute__((vector_size (16)));
    typedef int   v4i32 __attribute__((vector_size (16)));

    __attribute__((noinline)) v4f32
    unord_cast3 (v4f32 a, v4f32 b)
    {
      v4i32 m;
      for (int i = 0; i < 4; i++)
        m[i] = __builtin_isunordered (a[i], b[i]) ? -1 : 0;
      return (v4f32) m;
    }

$ loongarch64-linux-gnu-gcc t.c -O3 -mlasx -S -o t.s #-O2 -mlsx behaves the
same

  unord_cast3:
    vrepli.b        $vr0,0          <- constant zero, operands unused
    vpickve2gr.du   $r4,$vr0,0
    vpickve2gr.du   $r5,$vr0,1
    jr      $r1

Runtime check with NaNs in lanes 0/3:
  got  00000000 00000000 00000000 00000000
  want ffffffff 00000000 00000000 ffffffff


------ Analysis ------
The two insns that are affected, before and after fwprop1:

before fwprop1 (cse1) - both insns are still sane:
  insn 7: (set (reg:V4SI 86 [ mask__12.12_25 ])
               (unordered:V4SI (reg/v:V4SF 83 [ a ])
                               (reg/v:V4SF 84 [ b ])))   {lsx_vfcmp_cun_s}
  insn 8: (set (reg:V4SF 82 [ <retval> ])
               (subreg:V4SF (reg:V4SI 86 [ mask__12.12_25 ]) 0)) {movv4sf_simd}

after fwprop1 - insn 7 is unchanged, insn 8 gained a bogus constant:
  insn 7: (set (reg:V4SI 86 [ mask__12.12_25 ])
               (unordered:V4SI (reg/v:V4SF 83 [ a ])
                               (reg/v:V4SF 84 [ b ])))   {lsx_vfcmp_cun_s}
  insn 8: (set (reg:V4SF 82 [ <retval> ])
               (subreg:V4SF (reg:V4SI 86 [ mask__12.12_25 ]) 0)) {movv4sf_simd}
              (REG_EQUAL (const_vector:V4SF [0.0 x4])   <-- the only real
change
              (REG_DEAD (reg:V4SI 86 [ mask__12.12_25 ])))

How insn 8 gets that note - fwprop1 propagates insn 7's source into the subreg
of insn 8 and asks simplify_subreg() to fold it:
    recog.cc:
        insn_propagation::apply_to_rvalue_1(), SUBREG branch:
        newx = simplify_subreg (V4SF, (unordered:V4SI ...), V4SI, 0);

    simplify-rtx.cc:
        simplify_subreg() -> simplify_gen_relational (UNORDERED, outermode =
V4SF, cmp_mode = innermode = V4SI, op0, op1);

    simplify-rtx.cc:
        simplify_const_relational_operation():
            if (! HONOR_NANS (mode) && code == UNORDERED)
              return const0_rtx;              /* HONOR_NANS (V4SI) is false */
        -> relational_result() -> (const_vector:V4SF [0.0 x4])

Reply via email to