Hi Eikansh,

This looks good - a few comments:

Please add a comment before this pattern so it's clear what it is for and
shows up if you search for similar saturating patterns.

+(define_expand "usmulsi3"
+  [(set (match_operand:SI 0 "register_operand")
+       (us_mult:SI (match_operand:SI 1 "register_operand")
+                   (match_operand:SI 2 "register_operand")))]
+  ""
+{
+  rtx product = gen_reg_rtx (DImode);
+  emit_insn (gen_umulsidi3 (product, operands[1], operands[2]));
+
+  rtx high = gen_reg_rtx (DImode);
+  emit_insn (gen_lshrdi3 (high, product, GEN_INT (32)));
+
+  rtx cc_reg = aarch64_gen_compare_reg (EQ, high, const0_rtx);
+  rtx cond = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
+  rtx low = gen_lowpart (SImode, product);
+  emit_insn (gen_rtx_SET (operands[0],
+                         gen_rtx_IF_THEN_ELSE (SImode, cond, low,
+                                               constm1_rtx)));
+  DONE;
+})

This generates:

        umull   x0, w0, w1
        cmp     xzr, x0, lsr 32
        csinv   w0, w0, wzr, eq

This is an odd form of CMP, and it uses a shift which means it takes 2 cycles 
on most CPUs.
Using TST x0, 0xffffffff00000000 is both easier to understand and faster.

Cheers,
Wilco

Reply via email to