diff --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h --- a/llvm/lib/Target/VE/VEISelLowering.h +++ b/llvm/lib/Target/VE/VEISelLowering.h @@ -86,6 +86,9 @@ 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/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -501,6 +501,14 @@ 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/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td --- a/llvm/lib/Target/VE/VEInstrInfo.td +++ b/llvm/lib/Target/VE/VEInstrInfo.td @@ -630,6 +630,38 @@ 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 --- /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 --- /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 --- /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 +}