[llvm] 0bec0e7 - [VE] udiv/sdiv/urem/srem/mul isel patterns

Simon Moll via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 29 07:00:27 PST 2020


Author: Kazushi (Jam) Marukawa
Date: 2020-01-29T15:59:50+01:00
New Revision: 0bec0e71514a038f828b147725f44c5ed03a608b

URL: https://github.com/llvm/llvm-project/commit/0bec0e71514a038f828b147725f44c5ed03a608b
DIFF: https://github.com/llvm/llvm-project/commit/0bec0e71514a038f828b147725f44c5ed03a608b.diff

LOG: [VE] udiv/sdiv/urem/srem/mul isel patterns

Summary:
udiv/sdiv/urem/srem/mul integer isel patterns and tests.
Pretend for now that integer division were always cheap in HW.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D73623

Added: 
    llvm/test/CodeGen/VE/div.ll
    llvm/test/CodeGen/VE/multiply.ll
    llvm/test/CodeGen/VE/rem.ll

Modified: 
    llvm/lib/Target/VE/VEISelLowering.cpp
    llvm/lib/Target/VE/VEISelLowering.h
    llvm/lib/Target/VE/VEInstrInfo.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp
index 3f1b373f9c45..eae71465b55c 100644
--- a/llvm/lib/Target/VE/VEISelLowering.cpp
+++ b/llvm/lib/Target/VE/VEISelLowering.cpp
@@ -501,6 +501,14 @@ VETargetLowering::VETargetLowering(const TargetMachine &TM,
   MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
   setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
 
+  // VE has no REM or DIVREM operations.
+  for (MVT IntVT : MVT::integer_valuetypes()) {
+    setOperationAction(ISD::UREM, IntVT, Expand);
+    setOperationAction(ISD::SREM, IntVT, Expand);
+    setOperationAction(ISD::SDIVREM, IntVT, Expand);
+    setOperationAction(ISD::UDIVREM, IntVT, Expand);
+  }
+
   // VE doesn't have instructions for fp<->uint, so expand them by llvm
   setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64
   setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64

diff  --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h
index eb7835e6a8ae..8be851378d7a 100644
--- a/llvm/lib/Target/VE/VEISelLowering.h
+++ b/llvm/lib/Target/VE/VEISelLowering.h
@@ -86,6 +86,9 @@ class VETargetLowering : public TargetLowering {
   bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, unsigned Align,
                                       MachineMemOperand::Flags Flags,
                                       bool *Fast) const override;
+
+  // Block s/udiv lowering for now
+  bool isIntDivCheap(EVT VT, AttributeList Attr) const override { return true; }
 };
 } // namespace llvm
 

diff  --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td
index 4d5676947ef9..ab995c8cb846 100644
--- a/llvm/lib/Target/VE/VEInstrInfo.td
+++ b/llvm/lib/Target/VE/VEInstrInfo.td
@@ -630,6 +630,38 @@ defm SBSU : RRm<"subs.w.zx", 0x5A, I32, i32, simm7Op32, uimm6Op32>;
 let cx = 0 in
 defm SBX : RRNCm<"subs.l", 0x5B, I64, i64, simm7Op64, uimm6Op64, sub>;
 
+// MPY instruction
+let cx = 0 in
+defm MPY : RRm<"mulu.l", 0x49, I64, i64, simm7Op64, uimm6Op64>;
+let cx = 1 in
+defm MPYUW : RRm<"mulu.w", 0x49, I32, i32, simm7Op32, uimm6Op32>;
+
+// MPS instruction
+let cx = 0 in
+defm MPS : RRm<"muls.w.sx", 0x4B, I32, i32, simm7Op32, uimm6Op32, mul>;
+let cx = 1 in
+defm MPSU : RRm<"muls.w.zx", 0x4B, I32, i32, simm7Op32, uimm6Op32>;
+
+// MPX instruction
+let cx = 0 in
+defm MPX : RRm<"muls.l", 0x6E, I64, i64, simm7Op64, uimm6Op64, mul>;
+
+// DIV instruction
+let cx = 0 in
+defm DIV : RRNCm<"divu.l", 0x6F, I64, i64, simm7Op64, uimm6Op64, udiv>;
+let cx = 1 in
+defm DIVUW : RRNCm<"divu.w", 0x6F, I32, i32, simm7Op32, uimm6Op32, udiv>;
+
+// DVS instruction
+let cx = 0 in
+defm DVS : RRNCm<"divs.w.sx", 0x7B, I32, i32, simm7Op32, uimm6Op32, sdiv>;
+let cx = 1 in
+defm DVSU : RRm<"divs.w.zx", 0x7B, I32, i32, simm7Op32, uimm6Op32>;
+
+// DVX instruction
+let cx = 0 in
+defm DVX : RRNCm<"divs.l", 0x7F, I64, i64, simm7Op64, uimm6Op64, sdiv>;
+
 // CMP instruction
 let cx = 0 in
 defm CMP : RRm<"cmpu.l", 0x55, I64, i64, simm7Op64, uimm6Op64>;

diff  --git a/llvm/test/CodeGen/VE/div.ll b/llvm/test/CodeGen/VE/div.ll
new file mode 100644
index 000000000000..1cb51f42c81d
--- /dev/null
+++ b/llvm/test/CodeGen/VE/div.ll
@@ -0,0 +1,175 @@
+; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @divi64(i64 %a, i64 %b) {
+; CHECK-LABEL: divi64:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.l %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = sdiv i64 %a, %b
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @divi32(i32 %a, i32 %b) {
+; CHECK-LABEL: divi32:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = sdiv i32 %a, %b
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @divu64(i64 %a, i64 %b) {
+; CHECK-LABEL: divu64:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.l %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = udiv i64 %a, %b
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @divu32(i32 %a, i32 %b) {
+; CHECK-LABEL: divu32:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.w %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = udiv i32 %a, %b
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i16 @divi16(i16 signext %a, i16 signext %b) {
+; CHECK-LABEL: divi16:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 16
+; CHECK-NEXT:    sra.w.sx %s0, %s0, 16
+; CHECK-NEXT:    or %s11, 0, %s9
+  %a32 = sext i16 %a to i32
+  %b32 = sext i16 %b to i32
+  %r32 = sdiv i32 %a32, %b32
+  %r = trunc i32 %r32 to i16
+  ret i16 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i16 @divu16(i16 zeroext %a, i16 zeroext %b) {
+; CHECK-LABEL: divu16:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.w %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = udiv i16 %a, %b
+  ret i16 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i8 @divi8(i8 signext %a, i8 signext %b) {
+; CHECK-LABEL: divi8:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 24
+; CHECK-NEXT:    sra.w.sx %s0, %s0, 24
+; CHECK-NEXT:    or %s11, 0, %s9
+  %a32 = sext i8 %a to i32
+  %b32 = sext i8 %b to i32
+  %r32 = sdiv i32 %a32, %b32
+  %r = trunc i32 %r32 to i8
+  ret i8 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i8 @divu8(i8 zeroext %a, i8 zeroext %b) {
+; CHECK-LABEL: divu8:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.w %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = udiv i8 %a, %b
+  ret i8 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @divi64ri(i64 %a, i64 %b) {
+; CHECK-LABEL: divi64ri:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s1, 3, (0)1
+; CHECK-NEXT:    divs.l %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = sdiv i64 %a, 3
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @divi32ri(i32 %a, i32 %b) {
+; CHECK-LABEL: divi32ri:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s1, 3, (0)1
+; CHECK-NEXT:    divs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = sdiv i32 %a, 3
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @divu64ri(i64 %a, i64 %b) {
+; CHECK-LABEL: divu64ri:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s1, 3, (0)1
+; CHECK-NEXT:    divu.l %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = udiv i64 %a, 3
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @divu32ri(i32 %a, i32 %b) {
+; CHECK-LABEL: divu32ri:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s1, 3, (0)1
+; CHECK-NEXT:    divu.w %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = udiv i32 %a, 3
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @divi64li(i64 %a, i64 %b) {
+; CHECK-LABEL: divi64li:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.l %s0, 3, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = sdiv i64 3, %b
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @divi32li(i32 %a, i32 %b) {
+; CHECK-LABEL: divi32li:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.w.sx %s0, 3, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = sdiv i32 3, %b
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @divu64li(i64 %a, i64 %b) {
+; CHECK-LABEL: divu64li:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.l %s0, 3, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = udiv i64 3, %b
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @divu32li(i32 %a, i32 %b) {
+; CHECK-LABEL: divu32li:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.w %s0, 3, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = udiv i32 3, %b
+  ret i32 %r
+}

diff  --git a/llvm/test/CodeGen/VE/multiply.ll b/llvm/test/CodeGen/VE/multiply.ll
new file mode 100644
index 000000000000..dabb6cf85d12
--- /dev/null
+++ b/llvm/test/CodeGen/VE/multiply.ll
@@ -0,0 +1,175 @@
+; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
+
+define signext i8 @func1(i8 signext %a, i8 signext %b) {
+; CHECK-LABEL: func1:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, %s1, %s0
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 24
+; CHECK-NEXT:    sra.w.sx %s0, %s0, 24
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i8 %b, %a
+  ret i8 %r
+}
+
+define signext i16 @func2(i16 signext %a, i16 signext %b) {
+; CHECK-LABEL: func2:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, %s1, %s0
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 16
+; CHECK-NEXT:    sra.w.sx %s0, %s0, 16
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i16 %b, %a
+  ret i16 %r
+}
+
+define i32 @func3(i32 %a, i32 %b) {
+; CHECK-LABEL: func3:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, %s1, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul nsw i32 %b, %a
+  ret i32 %r
+}
+
+define i64 @func4(i64 %a, i64 %b) {
+; CHECK-LABEL: func4:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.l %s0, %s1, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul nsw i64 %b, %a
+  ret i64 %r
+}
+
+define zeroext i8 @func5(i8 zeroext %a, i8 zeroext %b) {
+; CHECK-LABEL: func5:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, %s1, %s0
+; CHECK-NEXT:    and %s0, %s0, (56)0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i8 %b, %a
+  ret i8 %r
+}
+
+define zeroext i16 @func6(i16 zeroext %a, i16 zeroext %b) {
+; CHECK-LABEL: func6:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, %s1, %s0
+; CHECK-NEXT:    and %s0, %s0, (48)0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i16 %b, %a
+  ret i16 %r
+}
+
+define i32 @func7(i32 %a, i32 %b) {
+; CHECK-LABEL: func7:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, %s1, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i32 %b, %a
+  ret i32 %r
+}
+
+define i64 @func8(i64 %a, i64 %b) {
+; CHECK-LABEL: func8:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.l %s0, %s1, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i64 %b, %a
+  ret i64 %r
+}
+
+define signext i8 @func9(i8 signext %a) {
+; CHECK-LABEL: func9:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, 5, %s0
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 24
+; CHECK-NEXT:    sra.w.sx %s0, %s0, 24
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i8 %a, 5
+  ret i8 %r
+}
+
+define signext i16 @func10(i16 signext %a) {
+; CHECK-LABEL: func10:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, 5, %s0
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 16
+; CHECK-NEXT:    sra.w.sx %s0, %s0, 16
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i16 %a, 5
+  ret i16 %r
+}
+
+define i32 @func11(i32 %a) {
+; CHECK-LABEL: func11:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, 5, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul nsw i32 %a, 5
+  ret i32 %r
+}
+
+define i64 @func12(i64 %a) {
+; CHECK-LABEL: func12:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.l %s0, 5, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul nsw i64 %a, 5
+  ret i64 %r
+}
+
+define zeroext i8 @func13(i8 zeroext %a) {
+; CHECK-LABEL: func13:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, 5, %s0
+; CHECK-NEXT:    and %s0, %s0, (56)0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i8 %a, 5
+  ret i8 %r
+}
+
+define zeroext i16 @func14(i16 zeroext %a) {
+; CHECK-LABEL: func14:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, 5, %s0
+; CHECK-NEXT:    and %s0, %s0, (48)0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i16 %a, 5
+  ret i16 %r
+}
+
+define i32 @func15(i32 %a) {
+; CHECK-LABEL: func15:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.w.sx %s0, 5, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i32 %a, 5
+  ret i32 %r
+}
+
+define i64 @func16(i64 %a) {
+; CHECK-LABEL: func16:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    muls.l %s0, 5, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = mul i64 %a, 5
+  ret i64 %r
+}
+
+define i32 @func17(i32 %a) {
+; CHECK-LABEL: func17:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 31
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = shl i32 %a, 31
+  ret i32 %r
+}
+
+define i64 @func18(i64 %a) {
+; CHECK-LABEL: func18:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    sll %s0, %s0, 31
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = shl nsw i64 %a, 31
+  ret i64 %r
+}

diff  --git a/llvm/test/CodeGen/VE/rem.ll b/llvm/test/CodeGen/VE/rem.ll
new file mode 100644
index 000000000000..4c0d90d3ad49
--- /dev/null
+++ b/llvm/test/CodeGen/VE/rem.ll
@@ -0,0 +1,207 @@
+; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @remi64(i64 %a, i64 %b) {
+; CHECK-LABEL: remi64:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.l %s2, %s0, %s1
+; CHECK-NEXT:    muls.l %s1, %s2, %s1
+; CHECK-NEXT:    subs.l %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = srem i64 %a, %b
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @remi32(i32 %a, i32 %b) {
+; CHECK-LABEL: remi32:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.w.sx %s2, %s0, %s1
+; CHECK-NEXT:    muls.w.sx %s1, %s2, %s1
+; CHECK-NEXT:    subs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = srem i32 %a, %b
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @remu64(i64 %a, i64 %b) {
+; CHECK-LABEL: remu64:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.l %s2, %s0, %s1
+; CHECK-NEXT:    muls.l %s1, %s2, %s1
+; CHECK-NEXT:    subs.l %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = urem i64 %a, %b
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @remu32(i32 %a, i32 %b) {
+; CHECK-LABEL: remu32:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.w %s2, %s0, %s1
+; CHECK-NEXT:    muls.w.sx %s1, %s2, %s1
+; CHECK-NEXT:    subs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = urem i32 %a, %b
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i16 @remi16(i16 signext %a, i16 signext %b) {
+; CHECK-LABEL: remi16:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.w.sx %s2, %s0, %s1
+; CHECK-NEXT:    muls.w.sx %s1, %s2, %s1
+; CHECK-NEXT:    subs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 16
+; CHECK-NEXT:    sra.w.sx %s0, %s0, 16
+; CHECK-NEXT:    or %s11, 0, %s9
+  %a32 = sext i16 %a to i32
+  %b32 = sext i16 %b to i32
+  %r32 = srem i32 %a32, %b32
+  %r = trunc i32 %r32 to i16
+  ret i16 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i16 @remu16(i16 zeroext %a, i16 zeroext %b) {
+; CHECK-LABEL: remu16:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.w %s2, %s0, %s1
+; CHECK-NEXT:    muls.w.sx %s1, %s2, %s1
+; CHECK-NEXT:    subs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = urem i16 %a, %b
+  ret i16 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define signext i8 @remi8(i8 signext %a, i8 signext %b) {
+; CHECK-LABEL: remi8:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.w.sx %s2, %s0, %s1
+; CHECK-NEXT:    muls.w.sx %s1, %s2, %s1
+; CHECK-NEXT:    subs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    sla.w.sx %s0, %s0, 24
+; CHECK-NEXT:    sra.w.sx %s0, %s0, 24
+; CHECK-NEXT:    or %s11, 0, %s9
+  %a32 = sext i8 %a to i32
+  %b32 = sext i8 %b to i32
+  %r32 = srem i32 %a32, %b32
+  %r = trunc i32 %r32 to i8
+  ret i8 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i8 @remu8(i8 zeroext %a, i8 zeroext %b) {
+; CHECK-LABEL: remu8:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.w %s2, %s0, %s1
+; CHECK-NEXT:    muls.w.sx %s1, %s2, %s1
+; CHECK-NEXT:    subs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = urem i8 %a, %b
+  ret i8 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @remi64ri(i64 %a, i64 %b) {
+; CHECK-LABEL: remi64ri:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s1, 3, (0)1
+; CHECK-NEXT:    divs.l %s1, %s0, %s1
+; CHECK-NEXT:    muls.l %s1, 3, %s1
+; CHECK-NEXT:    subs.l %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = srem i64 %a, 3
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @remi32ri(i32 %a, i32 %b) {
+; CHECK-LABEL: remi32ri:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s1, 3, (0)1
+; CHECK-NEXT:    divs.w.sx %s1, %s0, %s1
+; CHECK-NEXT:    muls.w.sx %s1, 3, %s1
+; CHECK-NEXT:    subs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = srem i32 %a, 3
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @remu64ri(i64 %a, i64 %b) {
+; CHECK-LABEL: remu64ri:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s1, 3, (0)1
+; CHECK-NEXT:    divu.l %s1, %s0, %s1
+; CHECK-NEXT:    muls.l %s1, 3, %s1
+; CHECK-NEXT:    subs.l %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = urem i64 %a, 3
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @remu32ri(i32 %a, i32 %b) {
+; CHECK-LABEL: remu32ri:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    or %s1, 3, (0)1
+; CHECK-NEXT:    divu.w %s1, %s0, %s1
+; CHECK-NEXT:    muls.w.sx %s1, 3, %s1
+; CHECK-NEXT:    subs.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = urem i32 %a, 3
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @remi64li(i64 %a, i64 %b) {
+; CHECK-LABEL: remi64li:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.l %s0, 3, %s1
+; CHECK-NEXT:    muls.l %s0, %s0, %s1
+; CHECK-NEXT:    subs.l %s0, 3, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = srem i64 3, %b
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @remi32li(i32 %a, i32 %b) {
+; CHECK-LABEL: remi32li:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divs.w.sx %s0, 3, %s1
+; CHECK-NEXT:    muls.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    subs.w.sx %s0, 3, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = srem i32 3, %b
+  ret i32 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i64 @remu64li(i64 %a, i64 %b) {
+; CHECK-LABEL: remu64li:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.l %s0, 3, %s1
+; CHECK-NEXT:    muls.l %s0, %s0, %s1
+; CHECK-NEXT:    subs.l %s0, 3, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = urem i64 3, %b
+  ret i64 %r
+}
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @remu32li(i32 %a, i32 %b) {
+; CHECK-LABEL: remu32li:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    divu.w %s0, 3, %s1
+; CHECK-NEXT:    muls.w.sx %s0, %s0, %s1
+; CHECK-NEXT:    subs.w.sx %s0, 3, %s0
+; CHECK-NEXT:    or %s11, 0, %s9
+  %r = urem i32 3, %b
+  ret i32 %r
+}


        


More information about the llvm-commits mailing list