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

--- Comment #5 from Vineet Gupta <vineetg at gcc dot gnu.org> ---
ifcvt: noce_try_cond_zero_arith () currently only handles COND EQ and NE 0.
while the condition we get due to testing sign-bit is GE 0.
It seems we can transform this to EQ 0 with an intermediate SLTI

The patch below fixes the orig test...

+  /* ifcvt/czero has better outcomes with EQ operator, so convert
+       "if (a >= 0)"
+     to
+       "slti a, a, 0"
+       "if (a == 0)".  */
+  if (*code == GE
+      && REG_P (*op0)
+      && *op1 == CONST0_RTX (GET_MODE (*op0)))
+    {
+      if (GET_MODE (*op0) == DImode)
+        emit_insn (gen_slt_didi3 (*op0, *op0, *op1));
+      else
+        emit_insn (gen_slt_sisi3 (*op0, *op0, *op1));
+      *code = EQ;
+      return;
+    }

... but trips up when building glibc

error: unrecognizable insn:

(insn 11 10 12 2 (set (reg:SI 165)
        (lt:SI (reg:SI 165)
            (const_int 0 [0])))

The existing mode iterators in slt pattern are a bit confusing though

(define_insn "@slt<u>_<X:mode><GPR:mode>3"
  [(set (match_operand:GPR           0 "register_operand" "= r")
        (any_lt:GPR (match_operand:X 1 "register_operand" "  r")
                    (match_operand:X 2 "arith_operand"    " rI")))]
  ""
  "slt%i2<u>\t%0,%1,%2"
  [(set_attr "type" "slt")
   (set_attr "mode" "<X:MODE>")])

specifically "any_lt:GPR"

Reply via email to