[llvm] [Xtensa] Implement Xtensa Mul and Div Options. (PR #132157)

Andrei Safronov via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 20 00:43:52 PDT 2025


https://github.com/andreisfr created https://github.com/llvm/llvm-project/pull/132157

Implement Xtensa Mul16, Mul32, Mul32High and Div32 Options.

>From 583eed5d6beb588774bbe121d2438ca26f69140a Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Sat, 15 Mar 2025 13:38:19 +0300
Subject: [PATCH] [Xtensa] Implement Xtensa Mul and Div Options.

Implement Xtensa Mul16, Mul32, Mul32High and Div32 Options.
---
 llvm/lib/Target/Xtensa/XtensaFeatures.td      |  20 +
 llvm/lib/Target/Xtensa/XtensaISelLowering.cpp |  32 +-
 llvm/lib/Target/Xtensa/XtensaInstrInfo.td     |  30 +
 llvm/lib/Target/Xtensa/XtensaSubtarget.h      |   8 +
 llvm/test/CodeGen/Xtensa/div.ll               | 366 ++++++++++++-
 llvm/test/CodeGen/Xtensa/mul.ll               | 515 ++++++++++++++++++
 llvm/test/CodeGen/Xtensa/rem.ll               |  49 ++
 llvm/test/MC/Xtensa/div.s                     |  24 +
 llvm/test/MC/Xtensa/mul.s                     |  29 +
 9 files changed, 1036 insertions(+), 37 deletions(-)
 create mode 100644 llvm/test/CodeGen/Xtensa/rem.ll
 create mode 100644 llvm/test/MC/Xtensa/div.s
 create mode 100644 llvm/test/MC/Xtensa/mul.s

diff --git a/llvm/lib/Target/Xtensa/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td
index 184828cd253f3..d2e0a711a3575 100644
--- a/llvm/lib/Target/Xtensa/XtensaFeatures.td
+++ b/llvm/lib/Target/Xtensa/XtensaFeatures.td
@@ -22,3 +22,23 @@ def FeatureBoolean          : SubtargetFeature<"bool", "HasBoolean", "true",
                                                "Enable Xtensa Boolean extension">;
 def HasBoolean              : Predicate<"Subtarget->hasBoolean()">,
                                          AssemblerPredicate<(all_of FeatureBoolean)>;
+
+def FeatureMul16            : SubtargetFeature<"mul16", "HasMul16", "true",
+                                               "Enable Xtensa Mul16 option">;
+def HasMul16                : Predicate<"Subtarget->hasMul16()">,
+                                         AssemblerPredicate<(all_of FeatureMul16)>;
+
+def FeatureMul32            : SubtargetFeature<"mul32", "HasMul32", "true",
+                                               "Enable Xtensa Mul32 option">;
+def HasMul32                : Predicate<"Subtarget->hasMul32()">,
+                                         AssemblerPredicate<(all_of FeatureMul32)>;
+
+def FeatureMul32High        : SubtargetFeature<"mul32high", "HasMul32High", "true",
+                                               "Enable Xtensa Mul32High option">;
+def HasMul32High            : Predicate<"Subtarget->hasMul32High()">,
+                                         AssemblerPredicate<(all_of FeatureMul32High)>;
+
+def FeatureDiv32            : SubtargetFeature<"div32", "HasDiv32", "true",
+                                               "Enable Xtensa Div32 option">;
+def HasDiv32                : Predicate<"Subtarget->hasDiv32()">,
+                                         AssemblerPredicate<(all_of FeatureDiv32)>;
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index 57f0cbbc36c24..0b0e41c1c7b4e 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -106,16 +106,34 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
   setCondCodeAction(ISD::SETUGT, MVT::i32, Expand);
   setCondCodeAction(ISD::SETULE, MVT::i32, Expand);
 
-  setOperationAction(ISD::MUL, MVT::i32, Expand);
-  setOperationAction(ISD::MULHU, MVT::i32, Expand);
-  setOperationAction(ISD::MULHS, MVT::i32, Expand);
+  if (Subtarget.hasMul32())
+    setOperationAction(ISD::MUL, MVT::i32, Legal);
+  else
+    setOperationAction(ISD::MUL, MVT::i32, Expand);
+
+  if (Subtarget.hasMul32High()) {
+    setOperationAction(ISD::MULHU, MVT::i32, Legal);
+    setOperationAction(ISD::MULHS, MVT::i32, Legal);
+  } else {
+    setOperationAction(ISD::MULHU, MVT::i32, Expand);
+    setOperationAction(ISD::MULHS, MVT::i32, Expand);
+  }
+
   setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
   setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
 
-  setOperationAction(ISD::SDIV, MVT::i32, Expand);
-  setOperationAction(ISD::UDIV, MVT::i32, Expand);
-  setOperationAction(ISD::SREM, MVT::i32, Expand);
-  setOperationAction(ISD::UREM, MVT::i32, Expand);
+  if (Subtarget.hasDiv32()) {
+    setOperationAction(ISD::SDIV, MVT::i32, Legal);
+    setOperationAction(ISD::UDIV, MVT::i32, Legal);
+    setOperationAction(ISD::SREM, MVT::i32, Legal);
+    setOperationAction(ISD::UREM, MVT::i32, Legal);
+  } else {
+    setOperationAction(ISD::SDIV, MVT::i32, Expand);
+    setOperationAction(ISD::UDIV, MVT::i32, Expand);
+    setOperationAction(ISD::SREM, MVT::i32, Expand);
+    setOperationAction(ISD::UREM, MVT::i32, Expand);
+  }
+
   setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
   setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
 
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index 1f397e3ecac35..23f2298b55c96 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -850,6 +850,36 @@ let Constraints = "$dr = $r, at earlyclobber $dr" in {
                    "movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
 }
 
+//===----------------------------------------------------------------------===//
+// Mul16 Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasMul16] in {
+  def MUL16S : RRR_Inst<0x00, 0x01, 0x0D, (outs AR:$r), (ins AR:$s, AR:$t),
+                       "mul16s\t$r, $s, $t", []>;
+  def MUL16U : RRR_Inst<0x00, 0x01, 0x0C, (outs AR:$r), (ins AR:$s, AR:$t),
+                       "mul16u\t$r, $s, $t", []>;
+}
+
+//===----------------------------------------------------------------------===//
+// Mul32 Instructions
+//===----------------------------------------------------------------------===//
+
+def MULL  : ArithLogic_RRR<0x08, 0x02, "mull", mul, 1>, Requires<[HasMul32]>;
+def MULUH : ArithLogic_RRR<0x0A, 0x02, "muluh", mulhu, 1>, Requires<[HasMul32High]>;
+def MULSH : ArithLogic_RRR<0x0B, 0x02, "mulsh", mulhs, 1>, Requires<[HasMul32High]>;
+
+//===----------------------------------------------------------------------===//
+// Div32 Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasDiv32] in {
+  def QUOS : ArithLogic_RRR<0x0D, 0x02, "quos", sdiv>;
+  def QUOU : ArithLogic_RRR<0x0C, 0x02, "quou", udiv>;
+  def REMS : ArithLogic_RRR<0x0F, 0x02, "rems", srem>;
+  def REMU : ArithLogic_RRR<0x0E, 0x02, "remu", urem>;
+}
+
 //===----------------------------------------------------------------------===//
 // DSP Instructions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index 770f73905b337..3c3c49dd716df 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
@@ -66,6 +66,14 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
 
   bool hasDensity() const { return HasDensity; }
 
+  bool hasMul16() const { return HasMul16; }
+
+  bool hasMul32() const { return HasMul32; }
+
+  bool hasMul32High() const { return HasMul32High; }
+
+  bool hasDiv32() const { return HasDiv32; }
+
   bool hasMAC16() const { return HasMAC16; }
 
   bool hasWindowed() const { return HasWindowed; }
diff --git a/llvm/test/CodeGen/Xtensa/div.ll b/llvm/test/CodeGen/Xtensa/div.ll
index 8d51c571efb4c..48630e3960b9a 100644
--- a/llvm/test/CodeGen/Xtensa/div.ll
+++ b/llvm/test/CodeGen/Xtensa/div.ll
@@ -1,10 +1,13 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc -mtriple=xtensa -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefix=XTENSA %s
+; RUN: llc -mtriple=xtensa -mattr=+div32 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=XTENSA-DIV %s
 
 define i32 @udiv(i32 %a, i32 %b) nounwind {
 ; XTENSA-LABEL: udiv:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    l32r a8, .LCPI0_0
@@ -13,13 +16,19 @@ define i32 @udiv(i32 %a, i32 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    quou a2, a2, a3
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i32 %a, %b
   ret i32 %1
 }
 
 define i32 @udiv_constant(i32 %a) nounwind {
 ; XTENSA-LABEL: udiv_constant:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    movi a3, 5
@@ -29,21 +38,34 @@ define i32 @udiv_constant(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv_constant:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    movi a8, 5
+; XTENSA-DIV-NEXT:    quou a2, a2, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i32 %a, 5
   ret i32 %1
 }
 
 define i32 @udiv_pow2(i32 %a) nounwind {
 ; XTENSA-LABEL: udiv_pow2:
-; XTENSA:         srli a2, a2, 3
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    srli a2, a2, 3
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv_pow2:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    srli a2, a2, 3
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i32 %a, 8
   ret i32 %1
 }
 
 define i32 @udiv_constant_lhs(i32 %a) nounwind {
 ; XTENSA-LABEL: udiv_constant_lhs:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    or a3, a2, a2
@@ -54,13 +76,20 @@ define i32 @udiv_constant_lhs(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv_constant_lhs:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    movi a8, 10
+; XTENSA-DIV-NEXT:    quou a2, a8, a2
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i32 10, %a
   ret i32 %1
 }
 
 define i64 @udiv64(i64 %a, i64 %b) nounwind {
 ; XTENSA-LABEL: udiv64:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    l32r a8, .LCPI4_0
@@ -69,13 +98,26 @@ define i64 @udiv64(i64 %a, i64 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv64:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    addi a8, a1, -16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI4_0
+; XTENSA-DIV-NEXT:    callx0 a8
+; XTENSA-DIV-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-DIV-NEXT:    addi a8, a1, 16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i64 %a, %b
   ret i64 %1
 }
 
 define i64 @udiv64_constant(i64 %a) nounwind {
 ; XTENSA-LABEL: udiv64_constant:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    movi a4, 5
@@ -86,13 +128,28 @@ define i64 @udiv64_constant(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv64_constant:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    addi a8, a1, -16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-DIV-NEXT:    movi a4, 5
+; XTENSA-DIV-NEXT:    movi a5, 0
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI5_0
+; XTENSA-DIV-NEXT:    callx0 a8
+; XTENSA-DIV-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-DIV-NEXT:    addi a8, a1, 16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i64 %a, 5
   ret i64 %1
 }
 
 define i64 @udiv64_constant_lhs(i64 %a) nounwind {
 ; XTENSA-LABEL: udiv64_constant_lhs:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    or a5, a3, a3
@@ -105,13 +162,30 @@ define i64 @udiv64_constant_lhs(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv64_constant_lhs:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    addi a8, a1, -16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-DIV-NEXT:    or a5, a3, a3
+; XTENSA-DIV-NEXT:    or a4, a2, a2
+; XTENSA-DIV-NEXT:    movi a2, 10
+; XTENSA-DIV-NEXT:    movi a3, 0
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI6_0
+; XTENSA-DIV-NEXT:    callx0 a8
+; XTENSA-DIV-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-DIV-NEXT:    addi a8, a1, 16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i64 10, %a
   ret i64 %1
 }
 
 define i8 @udiv8(i8 %a, i8 %b) nounwind {
 ; XTENSA-LABEL: udiv8:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    movi a8, 255
@@ -123,13 +197,22 @@ define i8 @udiv8(i8 %a, i8 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv8:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    movi a8, 255
+; XTENSA-DIV-NEXT:    and a9, a3, a8
+; XTENSA-DIV-NEXT:    and a8, a2, a8
+; XTENSA-DIV-NEXT:    quou a2, a8, a9
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i8 %a, %b
   ret i8 %1
 }
 
 define i8 @udiv8_constant(i8 %a) nounwind {
 ; XTENSA-LABEL: udiv8_constant:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    movi a8, 255
@@ -141,23 +224,40 @@ define i8 @udiv8_constant(i8 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv8_constant:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    movi a8, 255
+; XTENSA-DIV-NEXT:    and a8, a2, a8
+; XTENSA-DIV-NEXT:    movi a9, 5
+; XTENSA-DIV-NEXT:    quou a2, a8, a9
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i8 %a, 5
   ret i8 %1
 }
 
 define i8 @udiv8_pow2(i8 %a) nounwind {
 ; XTENSA-LABEL: udiv8_pow2:
-; XTENSA:         movi a8, 248
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    movi a8, 248
 ; XTENSA-NEXT:    and a8, a2, a8
 ; XTENSA-NEXT:    srli a2, a8, 3
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv8_pow2:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    movi a8, 248
+; XTENSA-DIV-NEXT:    and a8, a2, a8
+; XTENSA-DIV-NEXT:    srli a2, a8, 3
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i8 %a, 8
   ret i8 %1
 }
 
 define i8 @udiv8_constant_lhs(i8 %a) nounwind {
 ; XTENSA-LABEL: udiv8_constant_lhs:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    movi a8, 255
@@ -169,13 +269,22 @@ define i8 @udiv8_constant_lhs(i8 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv8_constant_lhs:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    movi a8, 255
+; XTENSA-DIV-NEXT:    and a8, a2, a8
+; XTENSA-DIV-NEXT:    movi a9, 10
+; XTENSA-DIV-NEXT:    quou a2, a9, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i8 10, %a
   ret i8 %1
 }
 
 define i16 @udiv16(i16 %a, i16 %b) nounwind {
 ; XTENSA-LABEL: udiv16:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    l32r a8, .LCPI11_0
@@ -187,13 +296,22 @@ define i16 @udiv16(i16 %a, i16 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv16:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI11_0
+; XTENSA-DIV-NEXT:    and a9, a3, a8
+; XTENSA-DIV-NEXT:    and a8, a2, a8
+; XTENSA-DIV-NEXT:    quou a2, a8, a9
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i16 %a, %b
   ret i16 %1
 }
 
 define i16 @udiv16_constant(i16 %a) nounwind {
 ; XTENSA-LABEL: udiv16_constant:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    l32r a8, .LCPI12_0
@@ -205,23 +323,40 @@ define i16 @udiv16_constant(i16 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv16_constant:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI12_0
+; XTENSA-DIV-NEXT:    and a8, a2, a8
+; XTENSA-DIV-NEXT:    movi a9, 5
+; XTENSA-DIV-NEXT:    quou a2, a8, a9
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i16 %a, 5
   ret i16 %1
 }
 
 define i16 @udiv16_pow2(i16 %a) nounwind {
 ; XTENSA-LABEL: udiv16_pow2:
-; XTENSA:         l32r a8, .LCPI13_0
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    l32r a8, .LCPI13_0
 ; XTENSA-NEXT:    and a8, a2, a8
 ; XTENSA-NEXT:    srli a2, a8, 3
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: udiv16_pow2:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI13_0
+; XTENSA-DIV-NEXT:    and a8, a2, a8
+; XTENSA-DIV-NEXT:    srli a2, a8, 3
+; XTENSA-DIV-NEXT:    ret
   %1 = udiv i16 %a, 8
   ret i16 %1
 }
 
 define i32 @sdiv(i32 %a, i32 %b) nounwind {
 ; XTENSA-LABEL: sdiv:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    l32r a8, .LCPI14_0
@@ -230,13 +365,19 @@ define i32 @sdiv(i32 %a, i32 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    quos a2, a2, a3
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i32 %a, %b
   ret i32 %1
 }
 
 define i32 @sdiv_constant_lhs(i32 %a) nounwind {
 ; XTENSA-LABEL: sdiv_constant_lhs:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    or a3, a2, a2
@@ -247,13 +388,20 @@ define i32 @sdiv_constant_lhs(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv_constant_lhs:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    movi a8, -10
+; XTENSA-DIV-NEXT:    quos a2, a8, a2
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i32 -10, %a
   ret i32 %1
 }
 
 define i64 @sdiv64(i64 %a, i64 %b) nounwind {
 ; XTENSA-LABEL: sdiv64:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    l32r a8, .LCPI16_0
@@ -262,13 +410,26 @@ define i64 @sdiv64(i64 %a, i64 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv64:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    addi a8, a1, -16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI16_0
+; XTENSA-DIV-NEXT:    callx0 a8
+; XTENSA-DIV-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-DIV-NEXT:    addi a8, a1, 16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i64 %a, %b
   ret i64 %1
 }
 
 define i64 @sdiv64_constant(i64 %a) nounwind {
 ; XTENSA-LABEL: sdiv64_constant:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    movi a4, 5
@@ -279,13 +440,28 @@ define i64 @sdiv64_constant(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv64_constant:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    addi a8, a1, -16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-DIV-NEXT:    movi a4, 5
+; XTENSA-DIV-NEXT:    movi a5, 0
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI17_0
+; XTENSA-DIV-NEXT:    callx0 a8
+; XTENSA-DIV-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-DIV-NEXT:    addi a8, a1, 16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i64 %a, 5
   ret i64 %1
 }
 
 define i64 @sdiv64_constant_lhs(i64 %a) nounwind {
 ; XTENSA-LABEL: sdiv64_constant_lhs:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    or a5, a3, a3
@@ -298,6 +474,22 @@ define i64 @sdiv64_constant_lhs(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv64_constant_lhs:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    addi a8, a1, -16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-DIV-NEXT:    or a5, a3, a3
+; XTENSA-DIV-NEXT:    or a4, a2, a2
+; XTENSA-DIV-NEXT:    movi a2, 10
+; XTENSA-DIV-NEXT:    movi a3, 0
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI18_0
+; XTENSA-DIV-NEXT:    callx0 a8
+; XTENSA-DIV-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-DIV-NEXT:    addi a8, a1, 16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i64 10, %a
   ret i64 %1
 }
@@ -305,7 +497,8 @@ define i64 @sdiv64_constant_lhs(i64 %a) nounwind {
 
 define i64 @sdiv64_sext_operands(i32 %a, i32 %b) nounwind {
 ; XTENSA-LABEL: sdiv64_sext_operands:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    or a4, a3, a3
@@ -317,6 +510,21 @@ define i64 @sdiv64_sext_operands(i32 %a, i32 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv64_sext_operands:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    addi a8, a1, -16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-DIV-NEXT:    or a4, a3, a3
+; XTENSA-DIV-NEXT:    srai a3, a2, 31
+; XTENSA-DIV-NEXT:    srai a5, a4, 31
+; XTENSA-DIV-NEXT:    l32r a8, .LCPI19_0
+; XTENSA-DIV-NEXT:    callx0 a8
+; XTENSA-DIV-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-DIV-NEXT:    addi a8, a1, 16
+; XTENSA-DIV-NEXT:    or a1, a8, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = sext i32 %a to i64
   %2 = sext i32 %b to i64
   %3 = sdiv i64 %1, %2
@@ -325,7 +533,8 @@ define i64 @sdiv64_sext_operands(i32 %a, i32 %b) nounwind {
 
 define i8 @sdiv8(i8 %a, i8 %b) nounwind {
 ; XTENSA-LABEL: sdiv8:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    slli a8, a2, 24
@@ -338,13 +547,23 @@ define i8 @sdiv8(i8 %a, i8 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv8:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    slli a8, a3, 24
+; XTENSA-DIV-NEXT:    srai a8, a8, 24
+; XTENSA-DIV-NEXT:    slli a9, a2, 24
+; XTENSA-DIV-NEXT:    srai a9, a9, 24
+; XTENSA-DIV-NEXT:    quos a2, a9, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i8 %a, %b
   ret i8 %1
 }
 
 define i8 @sdiv8_constant(i8 %a) nounwind {
 ; XTENSA-LABEL: sdiv8_constant:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    slli a8, a2, 24
@@ -356,13 +575,22 @@ define i8 @sdiv8_constant(i8 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv8_constant:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    slli a8, a2, 24
+; XTENSA-DIV-NEXT:    srai a8, a8, 24
+; XTENSA-DIV-NEXT:    movi a9, 5
+; XTENSA-DIV-NEXT:    quos a2, a8, a9
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i8 %a, 5
   ret i8 %1
 }
 
 define i8 @sdiv8_pow2(i8 %a) nounwind {
 ; XTENSA-LABEL: sdiv8_pow2:
-; XTENSA:         slli a8, a2, 24
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    slli a8, a2, 24
 ; XTENSA-NEXT:    srai a8, a8, 31
 ; XTENSA-NEXT:    movi a9, 7
 ; XTENSA-NEXT:    and a8, a8, a9
@@ -370,13 +598,25 @@ define i8 @sdiv8_pow2(i8 %a) nounwind {
 ; XTENSA-NEXT:    slli a8, a8, 24
 ; XTENSA-NEXT:    srai a2, a8, 27
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv8_pow2:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    slli a8, a2, 24
+; XTENSA-DIV-NEXT:    srai a8, a8, 31
+; XTENSA-DIV-NEXT:    movi a9, 7
+; XTENSA-DIV-NEXT:    and a8, a8, a9
+; XTENSA-DIV-NEXT:    add a8, a2, a8
+; XTENSA-DIV-NEXT:    slli a8, a8, 24
+; XTENSA-DIV-NEXT:    srai a2, a8, 27
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i8 %a, 8
   ret i8 %1
 }
 
 define i8 @sdiv8_constant_lhs(i8 %a) nounwind {
 ; XTENSA-LABEL: sdiv8_constant_lhs:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    slli a8, a2, 24
@@ -388,13 +628,22 @@ define i8 @sdiv8_constant_lhs(i8 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv8_constant_lhs:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    slli a8, a2, 24
+; XTENSA-DIV-NEXT:    srai a8, a8, 24
+; XTENSA-DIV-NEXT:    movi a9, -10
+; XTENSA-DIV-NEXT:    quos a2, a9, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i8 -10, %a
   ret i8 %1
 }
 
 define i16 @sdiv16(i16 %a, i16 %b) nounwind {
 ; XTENSA-LABEL: sdiv16:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    slli a8, a2, 16
@@ -407,13 +656,23 @@ define i16 @sdiv16(i16 %a, i16 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv16:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    slli a8, a3, 16
+; XTENSA-DIV-NEXT:    srai a8, a8, 16
+; XTENSA-DIV-NEXT:    slli a9, a2, 16
+; XTENSA-DIV-NEXT:    srai a9, a9, 16
+; XTENSA-DIV-NEXT:    quos a2, a9, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i16 %a, %b
   ret i16 %1
 }
 
 define i16 @sdiv16_constant(i16 %a) nounwind {
 ; XTENSA-LABEL: sdiv16_constant:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    slli a8, a2, 16
@@ -425,13 +684,22 @@ define i16 @sdiv16_constant(i16 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv16_constant:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    slli a8, a2, 16
+; XTENSA-DIV-NEXT:    srai a8, a8, 16
+; XTENSA-DIV-NEXT:    movi a9, 5
+; XTENSA-DIV-NEXT:    quos a2, a8, a9
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i16 %a, 5
   ret i16 %1
 }
 
 define i16 @sdiv16_constant_lhs(i16 %a) nounwind {
 ; XTENSA-LABEL: sdiv16_constant_lhs:
-; XTENSA:         addi a8, a1, -16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    addi a8, a1, -16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
 ; XTENSA-NEXT:    slli a8, a2, 16
@@ -443,35 +711,62 @@ define i16 @sdiv16_constant_lhs(i16 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv16_constant_lhs:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    slli a8, a2, 16
+; XTENSA-DIV-NEXT:    srai a8, a8, 16
+; XTENSA-DIV-NEXT:    movi a9, -10
+; XTENSA-DIV-NEXT:    quos a2, a9, a8
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i16 -10, %a
   ret i16 %1
 }
 
 define i32 @sdiv_pow2(i32 %a) nounwind {
 ; XTENSA-LABEL: sdiv_pow2:
-; XTENSA:         srai a8, a2, 31
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    srai a8, a2, 31
 ; XTENSA-NEXT:    extui a8, a8, 29, 3
 ; XTENSA-NEXT:    add a8, a2, a8
 ; XTENSA-NEXT:    srai a2, a8, 3
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv_pow2:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    srai a8, a2, 31
+; XTENSA-DIV-NEXT:    extui a8, a8, 29, 3
+; XTENSA-DIV-NEXT:    add a8, a2, a8
+; XTENSA-DIV-NEXT:    srai a2, a8, 3
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i32 %a, 8
   ret i32 %1
 }
 
 define i32 @sdiv_pow2_2(i32 %a) nounwind {
 ; XTENSA-LABEL: sdiv_pow2_2:
-; XTENSA:         srai a8, a2, 31
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    srai a8, a2, 31
 ; XTENSA-NEXT:    extui a8, a8, 16, 16
 ; XTENSA-NEXT:    add a8, a2, a8
 ; XTENSA-NEXT:    srai a2, a8, 16
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv_pow2_2:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    srai a8, a2, 31
+; XTENSA-DIV-NEXT:    extui a8, a8, 16, 16
+; XTENSA-DIV-NEXT:    add a8, a2, a8
+; XTENSA-DIV-NEXT:    srai a2, a8, 16
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i32 %a, 65536
   ret i32 %1
 }
 
 define i16 @sdiv16_pow2(i16 %a) nounwind {
 ; XTENSA-LABEL: sdiv16_pow2:
-; XTENSA:         slli a8, a2, 16
+; XTENSA:       # %bb.0:
+; XTENSA-NEXT:    slli a8, a2, 16
 ; XTENSA-NEXT:    srai a8, a8, 31
 ; XTENSA-NEXT:    movi a9, 7
 ; XTENSA-NEXT:    and a8, a8, a9
@@ -479,6 +774,17 @@ define i16 @sdiv16_pow2(i16 %a) nounwind {
 ; XTENSA-NEXT:    slli a8, a8, 16
 ; XTENSA-NEXT:    srai a2, a8, 19
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: sdiv16_pow2:
+; XTENSA-DIV:       # %bb.0:
+; XTENSA-DIV-NEXT:    slli a8, a2, 16
+; XTENSA-DIV-NEXT:    srai a8, a8, 31
+; XTENSA-DIV-NEXT:    movi a9, 7
+; XTENSA-DIV-NEXT:    and a8, a8, a9
+; XTENSA-DIV-NEXT:    add a8, a2, a8
+; XTENSA-DIV-NEXT:    slli a8, a8, 16
+; XTENSA-DIV-NEXT:    srai a2, a8, 19
+; XTENSA-DIV-NEXT:    ret
   %1 = sdiv i16 %a, 8
   ret i16 %1
 }
diff --git a/llvm/test/CodeGen/Xtensa/mul.ll b/llvm/test/CodeGen/Xtensa/mul.ll
index c5995bbc479a6..6901323822280 100644
--- a/llvm/test/CodeGen/Xtensa/mul.ll
+++ b/llvm/test/CodeGen/Xtensa/mul.ll
@@ -1,6 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc -mtriple=xtensa -verify-machineinstrs < %s \
 ; RUN: | FileCheck -check-prefix=XTENSA %s
+; RUN: llc -mtriple=xtensa -mattr=+mul32high,mul32 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=XTENSA-MUL %s
 
 define signext i32 @square(i32 %a) nounwind {
 ; XTENSA-LABEL: square:
@@ -15,6 +17,11 @@ define signext i32 @square(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: square:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    mull a2, a2, a2
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, %a
   ret i32 %1
 }
@@ -31,6 +38,11 @@ define signext i32 @mul(i32 %a, i32 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    mull a2, a2, a3
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, %b
   ret i32 %1
 }
@@ -48,6 +60,12 @@ define signext i32 @mul_constant(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul_constant:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 5
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 5
   ret i32 %1
 }
@@ -57,6 +75,11 @@ define i32 @mul_pow2(i32 %a) nounwind {
 ; XTENSA:       # %bb.0:
 ; XTENSA-NEXT:    slli a2, a2, 3
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul_pow2:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    slli a2, a2, 3
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 8
   ret i32 %1
 }
@@ -73,6 +96,16 @@ define i64 @mul64(i64 %a, i64 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul64:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    mull a8, a2, a5
+; XTENSA-MUL-NEXT:    muluh a9, a2, a4
+; XTENSA-MUL-NEXT:    add a8, a9, a8
+; XTENSA-MUL-NEXT:    mull a9, a3, a4
+; XTENSA-MUL-NEXT:    add a3, a8, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a4
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, %b
   ret i64 %1
 }
@@ -91,6 +124,15 @@ define i64 @mul64_constant(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul64_constant:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 5
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, 5
   ret i64 %1
 }
@@ -111,6 +153,11 @@ define i32 @mulhs(i32 %a, i32 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulhs:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    mulsh a2, a2, a3
+; XTENSA-MUL-NEXT:    ret
   %1 = sext i32 %a to i64
   %2 = sext i32 %b to i64
   %3 = mul i64 %1, %2
@@ -135,6 +182,12 @@ define i32 @mulhs_positive_constant(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulhs_positive_constant:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 5
+; XTENSA-MUL-NEXT:    mulsh a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = sext i32 %a to i64
   %2 = mul i64 %1, 5
   %3 = lshr i64 %2, 32
@@ -158,6 +211,12 @@ define i32 @mulhs_negative_constant(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulhs_negative_constant:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, -5
+; XTENSA-MUL-NEXT:    mulsh a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = sext i32 %a to i64
   %2 = mul i64 %1, -5
   %3 = lshr i64 %2, 32
@@ -181,6 +240,11 @@ define zeroext i32 @mulhu(i32 zeroext %a, i32 zeroext %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulhu:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    muluh a2, a2, a3
+; XTENSA-MUL-NEXT:    ret
   %1 = zext i32 %a to i64
   %2 = zext i32 %b to i64
   %3 = mul i64 %1, %2
@@ -205,6 +269,14 @@ define i32 @mulhsu(i32 %a, i32 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulhsu:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    muluh a8, a2, a3
+; XTENSA-MUL-NEXT:    srai a9, a3, 31
+; XTENSA-MUL-NEXT:    mull a9, a2, a9
+; XTENSA-MUL-NEXT:    add a2, a8, a9
+; XTENSA-MUL-NEXT:    ret
   %1 = zext i32 %a to i64
   %2 = sext i32 %b to i64
   %3 = mul i64 %1, %2
@@ -229,6 +301,12 @@ define i32 @mulhu_constant(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulhu_constant:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 5
+; XTENSA-MUL-NEXT:    muluh a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = zext i32 %a to i64
   %2 = mul i64 %1, 5
   %3 = lshr i64 %2, 32
@@ -249,6 +327,12 @@ define i32 @muli32_p65(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_p65:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 65
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 65
   ret i32 %1
 }
@@ -266,6 +350,12 @@ define i32 @muli32_p63(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_p63:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 63
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 63
   ret i32 %1
 }
@@ -284,6 +374,15 @@ define i64 @muli64_p65(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli64_p65:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 65
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, 65
   ret i64 %1
 }
@@ -302,6 +401,15 @@ define i64 @muli64_p63(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli64_p63:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 63
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, 63
   ret i64 %1
 }
@@ -319,6 +427,12 @@ define i32 @muli32_m63(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_m63:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, -63
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, -63
   ret i32 %1
 }
@@ -336,6 +450,12 @@ define i32 @muli32_m65(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_m65:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, -65
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, -65
   ret i32 %1
 }
@@ -354,6 +474,16 @@ define i64 @muli64_m63(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli64_m63:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, -63
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    sub a10, a10, a2
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, -63
   ret i64 %1
 }
@@ -372,6 +502,16 @@ define i64 @muli64_m65(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli64_m65:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, -65
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    sub a10, a10, a2
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, -65
   ret i64 %1
 }
@@ -389,6 +529,12 @@ define i32 @muli32_p384(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_p384:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    movi a8, 384
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 384
   ret i32 %1
 }
@@ -406,6 +552,12 @@ define i32 @muli32_p12288(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_p12288:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI21_0
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 12288
   ret i32 %1
 }
@@ -423,6 +575,12 @@ define i32 @muli32_p4352(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_p4352:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI22_0
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 4352
   ret i32 %1
 }
@@ -440,6 +598,12 @@ define i32 @muli32_p3840(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_p3840:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI23_0
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 3840
   ret i32 %1
 }
@@ -457,6 +621,12 @@ define i32 @muli32_m3840(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_m3840:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI24_0
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, -3840
   ret i32 %1
 }
@@ -474,6 +644,12 @@ define i32 @muli32_m4352(i32 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli32_m4352:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI25_0
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, -4352
   ret i32 %1
 }
@@ -492,6 +668,15 @@ define i64 @muli64_p4352(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli64_p4352:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI26_0
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, 4352
   ret i64 %1
 }
@@ -510,6 +695,15 @@ define i64 @muli64_p3840(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli64_p3840:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI27_0
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, 3840
   ret i64 %1
 }
@@ -528,6 +722,16 @@ define i64 @muli64_m4352(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli64_m4352:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI28_0
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    sub a10, a10, a2
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, -4352
   ret i64 %1
 }
@@ -546,6 +750,16 @@ define i64 @muli64_m3840(i64 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 16
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli64_m3840:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    l32r a8, .LCPI29_0
+; XTENSA-MUL-NEXT:    mull a9, a3, a8
+; XTENSA-MUL-NEXT:    muluh a10, a2, a8
+; XTENSA-MUL-NEXT:    sub a10, a10, a2
+; XTENSA-MUL-NEXT:    add a3, a10, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i64 %a, -3840
   ret i64 %1
 }
@@ -671,6 +885,94 @@ define i128 @muli128_m3840(i128 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 80
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli128_m3840:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    addi a8, a1, -48
+; XTENSA-MUL-NEXT:    or a1, a8, a8
+; XTENSA-MUL-NEXT:    s32i a12, a1, 32 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a13, a1, 28 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a14, a1, 24 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a15, a1, 20 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a5, a1, 16 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    l32r a10, .LCPI30_0
+; XTENSA-MUL-NEXT:    muluh a8, a2, a10
+; XTENSA-MUL-NEXT:    mull a7, a3, a10
+; XTENSA-MUL-NEXT:    add a8, a7, a8
+; XTENSA-MUL-NEXT:    movi a5, 0
+; XTENSA-MUL-NEXT:    movi a11, 1
+; XTENSA-MUL-NEXT:    or a9, a11, a11
+; XTENSA-MUL-NEXT:    bltu a8, a7, .LBB30_2
+; XTENSA-MUL-NEXT:  # %bb.1:
+; XTENSA-MUL-NEXT:    or a9, a5, a5
+; XTENSA-MUL-NEXT:  .LBB30_2:
+; XTENSA-MUL-NEXT:    muluh a7, a3, a10
+; XTENSA-MUL-NEXT:    add a15, a7, a9
+; XTENSA-MUL-NEXT:    sub a8, a8, a2
+; XTENSA-MUL-NEXT:    neg a7, a2
+; XTENSA-MUL-NEXT:    or a9, a11, a11
+; XTENSA-MUL-NEXT:    s32i a8, a1, 12 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a7, a1, 8 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    bltu a8, a7, .LBB30_4
+; XTENSA-MUL-NEXT:  # %bb.3:
+; XTENSA-MUL-NEXT:    or a9, a5, a5
+; XTENSA-MUL-NEXT:  .LBB30_4:
+; XTENSA-MUL-NEXT:    movi a8, -1
+; XTENSA-MUL-NEXT:    muluh a13, a2, a8
+; XTENSA-MUL-NEXT:    add a9, a13, a9
+; XTENSA-MUL-NEXT:    add a12, a15, a9
+; XTENSA-MUL-NEXT:    sub a6, a12, a3
+; XTENSA-MUL-NEXT:    mull a9, a4, a10
+; XTENSA-MUL-NEXT:    sub a14, a9, a2
+; XTENSA-MUL-NEXT:    add a9, a6, a14
+; XTENSA-MUL-NEXT:    or a7, a11, a11
+; XTENSA-MUL-NEXT:    s32i a9, a1, 4 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    bltu a9, a6, .LBB30_6
+; XTENSA-MUL-NEXT:  # %bb.5:
+; XTENSA-MUL-NEXT:    or a7, a5, a5
+; XTENSA-MUL-NEXT:  .LBB30_6:
+; XTENSA-MUL-NEXT:    s32i a7, a1, 0 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    neg a9, a3
+; XTENSA-MUL-NEXT:    or a7, a11, a11
+; XTENSA-MUL-NEXT:    bltu a6, a9, .LBB30_8
+; XTENSA-MUL-NEXT:  # %bb.7:
+; XTENSA-MUL-NEXT:    or a7, a5, a5
+; XTENSA-MUL-NEXT:  .LBB30_8:
+; XTENSA-MUL-NEXT:    or a6, a11, a11
+; XTENSA-MUL-NEXT:    bltu a12, a15, .LBB30_10
+; XTENSA-MUL-NEXT:  # %bb.9:
+; XTENSA-MUL-NEXT:    or a6, a5, a5
+; XTENSA-MUL-NEXT:  .LBB30_10:
+; XTENSA-MUL-NEXT:    muluh a8, a3, a8
+; XTENSA-MUL-NEXT:    add a8, a8, a6
+; XTENSA-MUL-NEXT:    add a8, a8, a7
+; XTENSA-MUL-NEXT:    l32i a9, a1, 16 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    mull a9, a9, a10
+; XTENSA-MUL-NEXT:    muluh a7, a4, a10
+; XTENSA-MUL-NEXT:    sub a7, a7, a4
+; XTENSA-MUL-NEXT:    add a9, a7, a9
+; XTENSA-MUL-NEXT:    sub a7, a13, a2
+; XTENSA-MUL-NEXT:    sub a7, a7, a3
+; XTENSA-MUL-NEXT:    add a7, a7, a9
+; XTENSA-MUL-NEXT:    l32i a9, a1, 8 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    bltu a14, a9, .LBB30_12
+; XTENSA-MUL-NEXT:  # %bb.11:
+; XTENSA-MUL-NEXT:    or a11, a5, a5
+; XTENSA-MUL-NEXT:  .LBB30_12:
+; XTENSA-MUL-NEXT:    add a9, a7, a11
+; XTENSA-MUL-NEXT:    add a8, a8, a9
+; XTENSA-MUL-NEXT:    l32i a9, a1, 0 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    add a5, a8, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a10
+; XTENSA-MUL-NEXT:    l32i a3, a1, 12 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a4, a1, 4 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a15, a1, 20 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a14, a1, 24 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a13, a1, 28 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a12, a1, 32 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    addi a8, a1, 48
+; XTENSA-MUL-NEXT:    or a1, a8, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i128 %a, -3840
   ret i128 %1
 }
@@ -796,6 +1098,94 @@ define i128 @muli128_m63(i128 %a) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 80
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muli128_m63:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    addi a8, a1, -48
+; XTENSA-MUL-NEXT:    or a1, a8, a8
+; XTENSA-MUL-NEXT:    s32i a12, a1, 32 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a13, a1, 28 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a14, a1, 24 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a15, a1, 20 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a5, a1, 16 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    movi a10, -63
+; XTENSA-MUL-NEXT:    muluh a8, a2, a10
+; XTENSA-MUL-NEXT:    mull a7, a3, a10
+; XTENSA-MUL-NEXT:    add a8, a7, a8
+; XTENSA-MUL-NEXT:    movi a5, 0
+; XTENSA-MUL-NEXT:    movi a11, 1
+; XTENSA-MUL-NEXT:    or a9, a11, a11
+; XTENSA-MUL-NEXT:    bltu a8, a7, .LBB31_2
+; XTENSA-MUL-NEXT:  # %bb.1:
+; XTENSA-MUL-NEXT:    or a9, a5, a5
+; XTENSA-MUL-NEXT:  .LBB31_2:
+; XTENSA-MUL-NEXT:    muluh a7, a3, a10
+; XTENSA-MUL-NEXT:    add a15, a7, a9
+; XTENSA-MUL-NEXT:    sub a8, a8, a2
+; XTENSA-MUL-NEXT:    neg a7, a2
+; XTENSA-MUL-NEXT:    or a9, a11, a11
+; XTENSA-MUL-NEXT:    s32i a8, a1, 12 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a7, a1, 8 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    bltu a8, a7, .LBB31_4
+; XTENSA-MUL-NEXT:  # %bb.3:
+; XTENSA-MUL-NEXT:    or a9, a5, a5
+; XTENSA-MUL-NEXT:  .LBB31_4:
+; XTENSA-MUL-NEXT:    movi a8, -1
+; XTENSA-MUL-NEXT:    muluh a13, a2, a8
+; XTENSA-MUL-NEXT:    add a9, a13, a9
+; XTENSA-MUL-NEXT:    add a12, a15, a9
+; XTENSA-MUL-NEXT:    sub a6, a12, a3
+; XTENSA-MUL-NEXT:    mull a9, a4, a10
+; XTENSA-MUL-NEXT:    sub a14, a9, a2
+; XTENSA-MUL-NEXT:    add a9, a6, a14
+; XTENSA-MUL-NEXT:    or a7, a11, a11
+; XTENSA-MUL-NEXT:    s32i a9, a1, 4 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    bltu a9, a6, .LBB31_6
+; XTENSA-MUL-NEXT:  # %bb.5:
+; XTENSA-MUL-NEXT:    or a7, a5, a5
+; XTENSA-MUL-NEXT:  .LBB31_6:
+; XTENSA-MUL-NEXT:    s32i a7, a1, 0 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    neg a9, a3
+; XTENSA-MUL-NEXT:    or a7, a11, a11
+; XTENSA-MUL-NEXT:    bltu a6, a9, .LBB31_8
+; XTENSA-MUL-NEXT:  # %bb.7:
+; XTENSA-MUL-NEXT:    or a7, a5, a5
+; XTENSA-MUL-NEXT:  .LBB31_8:
+; XTENSA-MUL-NEXT:    or a6, a11, a11
+; XTENSA-MUL-NEXT:    bltu a12, a15, .LBB31_10
+; XTENSA-MUL-NEXT:  # %bb.9:
+; XTENSA-MUL-NEXT:    or a6, a5, a5
+; XTENSA-MUL-NEXT:  .LBB31_10:
+; XTENSA-MUL-NEXT:    muluh a8, a3, a8
+; XTENSA-MUL-NEXT:    add a8, a8, a6
+; XTENSA-MUL-NEXT:    add a8, a8, a7
+; XTENSA-MUL-NEXT:    l32i a9, a1, 16 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    mull a9, a9, a10
+; XTENSA-MUL-NEXT:    muluh a7, a4, a10
+; XTENSA-MUL-NEXT:    sub a7, a7, a4
+; XTENSA-MUL-NEXT:    add a9, a7, a9
+; XTENSA-MUL-NEXT:    sub a7, a13, a2
+; XTENSA-MUL-NEXT:    sub a7, a7, a3
+; XTENSA-MUL-NEXT:    add a7, a7, a9
+; XTENSA-MUL-NEXT:    l32i a9, a1, 8 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    bltu a14, a9, .LBB31_12
+; XTENSA-MUL-NEXT:  # %bb.11:
+; XTENSA-MUL-NEXT:    or a11, a5, a5
+; XTENSA-MUL-NEXT:  .LBB31_12:
+; XTENSA-MUL-NEXT:    add a9, a7, a11
+; XTENSA-MUL-NEXT:    add a8, a8, a9
+; XTENSA-MUL-NEXT:    l32i a9, a1, 0 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    add a5, a8, a9
+; XTENSA-MUL-NEXT:    mull a2, a2, a10
+; XTENSA-MUL-NEXT:    l32i a3, a1, 12 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a4, a1, 4 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a15, a1, 20 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a14, a1, 24 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a13, a1, 28 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a12, a1, 32 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    addi a8, a1, 48
+; XTENSA-MUL-NEXT:    or a1, a8, a8
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i128 %a, -63
   ret i128 %1
 }
@@ -917,6 +1307,77 @@ define i64 @mulhsu_i64(i64 %a, i64 %b) nounwind {
 ; XTENSA-NEXT:    addi a8, a1, 64
 ; XTENSA-NEXT:    or a1, a8, a8
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulhsu_i64:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    addi a8, a1, -16
+; XTENSA-MUL-NEXT:    or a1, a8, a8
+; XTENSA-MUL-NEXT:    s32i a12, a1, 12 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a13, a1, 8 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a14, a1, 4 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    s32i a15, a1, 0 # 4-byte Folded Spill
+; XTENSA-MUL-NEXT:    muluh a8, a2, a4
+; XTENSA-MUL-NEXT:    mull a7, a3, a4
+; XTENSA-MUL-NEXT:    add a8, a7, a8
+; XTENSA-MUL-NEXT:    movi a10, 0
+; XTENSA-MUL-NEXT:    movi a9, 1
+; XTENSA-MUL-NEXT:    or a11, a9, a9
+; XTENSA-MUL-NEXT:    bltu a8, a7, .LBB32_2
+; XTENSA-MUL-NEXT:  # %bb.1:
+; XTENSA-MUL-NEXT:    or a11, a10, a10
+; XTENSA-MUL-NEXT:  .LBB32_2:
+; XTENSA-MUL-NEXT:    muluh a7, a3, a4
+; XTENSA-MUL-NEXT:    add a11, a7, a11
+; XTENSA-MUL-NEXT:    mull a7, a2, a5
+; XTENSA-MUL-NEXT:    add a6, a7, a8
+; XTENSA-MUL-NEXT:    or a8, a9, a9
+; XTENSA-MUL-NEXT:    bltu a6, a7, .LBB32_4
+; XTENSA-MUL-NEXT:  # %bb.3:
+; XTENSA-MUL-NEXT:    or a8, a10, a10
+; XTENSA-MUL-NEXT:  .LBB32_4:
+; XTENSA-MUL-NEXT:    muluh a7, a2, a5
+; XTENSA-MUL-NEXT:    add a8, a7, a8
+; XTENSA-MUL-NEXT:    add a12, a11, a8
+; XTENSA-MUL-NEXT:    mull a14, a3, a5
+; XTENSA-MUL-NEXT:    add a15, a14, a12
+; XTENSA-MUL-NEXT:    srai a6, a5, 31
+; XTENSA-MUL-NEXT:    mull a7, a6, a2
+; XTENSA-MUL-NEXT:    add a8, a15, a7
+; XTENSA-MUL-NEXT:    or a4, a9, a9
+; XTENSA-MUL-NEXT:    bgeu a8, a15, .LBB32_9
+; XTENSA-MUL-NEXT:  # %bb.5:
+; XTENSA-MUL-NEXT:    or a13, a9, a9
+; XTENSA-MUL-NEXT:    bgeu a15, a14, .LBB32_10
+; XTENSA-MUL-NEXT:  .LBB32_6:
+; XTENSA-MUL-NEXT:    bltu a12, a11, .LBB32_8
+; XTENSA-MUL-NEXT:  .LBB32_7:
+; XTENSA-MUL-NEXT:    or a9, a10, a10
+; XTENSA-MUL-NEXT:  .LBB32_8:
+; XTENSA-MUL-NEXT:    muluh a10, a3, a5
+; XTENSA-MUL-NEXT:    add a9, a10, a9
+; XTENSA-MUL-NEXT:    add a9, a9, a13
+; XTENSA-MUL-NEXT:    mull a10, a6, a3
+; XTENSA-MUL-NEXT:    muluh a11, a6, a2
+; XTENSA-MUL-NEXT:    add a10, a11, a10
+; XTENSA-MUL-NEXT:    add a10, a10, a7
+; XTENSA-MUL-NEXT:    add a9, a9, a10
+; XTENSA-MUL-NEXT:    add a3, a9, a4
+; XTENSA-MUL-NEXT:    or a2, a8, a8
+; XTENSA-MUL-NEXT:    l32i a15, a1, 0 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a14, a1, 4 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a13, a1, 8 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    l32i a12, a1, 12 # 4-byte Folded Reload
+; XTENSA-MUL-NEXT:    addi a8, a1, 16
+; XTENSA-MUL-NEXT:    or a1, a8, a8
+; XTENSA-MUL-NEXT:    ret
+; XTENSA-MUL-NEXT:  .LBB32_9:
+; XTENSA-MUL-NEXT:    or a4, a10, a10
+; XTENSA-MUL-NEXT:    or a13, a9, a9
+; XTENSA-MUL-NEXT:    bltu a15, a14, .LBB32_6
+; XTENSA-MUL-NEXT:  .LBB32_10:
+; XTENSA-MUL-NEXT:    or a13, a10, a10
+; XTENSA-MUL-NEXT:    bgeu a12, a11, .LBB32_7
+; XTENSA-MUL-NEXT:    j .LBB32_8
   %1 = zext i64 %a to i128
   %2 = sext i64 %b to i128
   %3 = mul i128 %1, %2
@@ -933,6 +1394,14 @@ define i8 @muladd_demand(i8 %x, i8 %y) nounwind {
 ; XTENSA-NEXT:    movi a9, 15
 ; XTENSA-NEXT:    and a2, a8, a9
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muladd_demand:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    slli a8, a2, 1
+; XTENSA-MUL-NEXT:    sub a8, a3, a8
+; XTENSA-MUL-NEXT:    movi a9, 15
+; XTENSA-MUL-NEXT:    and a2, a8, a9
+; XTENSA-MUL-NEXT:    ret
   %m = mul i8 %x, 14
   %a = add i8 %y, %m
   %r = and i8 %a, 15
@@ -946,6 +1415,13 @@ define i8 @mulsub_demand(i8 %x, i8 %y) nounwind {
 ; XTENSA-NEXT:    movi a9, 15
 ; XTENSA-NEXT:    and a2, a8, a9
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulsub_demand:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    addx2 a8, a2, a3
+; XTENSA-MUL-NEXT:    movi a9, 15
+; XTENSA-MUL-NEXT:    and a2, a8, a9
+; XTENSA-MUL-NEXT:    ret
   %m = mul i8 %x, 14
   %a = sub i8 %y, %m
   %r = and i8 %a, 15
@@ -960,6 +1436,14 @@ define i8 @muladd_demand_2(i8 %x, i8 %y) nounwind {
 ; XTENSA-NEXT:    movi a9, -16
 ; XTENSA-NEXT:    or a2, a8, a9
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: muladd_demand_2:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    slli a8, a2, 1
+; XTENSA-MUL-NEXT:    sub a8, a3, a8
+; XTENSA-MUL-NEXT:    movi a9, -16
+; XTENSA-MUL-NEXT:    or a2, a8, a9
+; XTENSA-MUL-NEXT:    ret
   %m = mul i8 %x, 14
   %a = add i8 %y, %m
   %r = or i8 %a, 240
@@ -973,6 +1457,13 @@ define i8 @mulsub_demand_2(i8 %x, i8 %y) nounwind {
 ; XTENSA-NEXT:    movi a9, -16
 ; XTENSA-NEXT:    or a2, a8, a9
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mulsub_demand_2:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    addx2 a8, a2, a3
+; XTENSA-MUL-NEXT:    movi a9, -16
+; XTENSA-MUL-NEXT:    or a2, a8, a9
+; XTENSA-MUL-NEXT:    ret
   %m = mul i8 %x, 14
   %a = sub i8 %y, %m
   %r = or i8 %a, 240
@@ -984,6 +1475,11 @@ define signext i32 @mul_imm_2(i32 %a) nounwind {
 ; XTENSA:       # %bb.0:
 ; XTENSA-NEXT:    slli a2, a2, 1
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul_imm_2:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    slli a2, a2, 1
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 2
   ret i32 %1
 }
@@ -993,6 +1489,11 @@ define signext i32 @mul_imm_1024(i32 %a) nounwind {
 ; XTENSA:       # %bb.0:
 ; XTENSA-NEXT:    slli a2, a2, 10
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul_imm_1024:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    slli a2, a2, 10
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 1024
   ret i32 %1
 }
@@ -1002,6 +1503,11 @@ define signext i32 @mul_imm_16384(i32 %a) nounwind {
 ; XTENSA:       # %bb.0:
 ; XTENSA-NEXT:    slli a2, a2, 14
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul_imm_16384:
+; XTENSA-MUL:       # %bb.0:
+; XTENSA-MUL-NEXT:    slli a2, a2, 14
+; XTENSA-MUL-NEXT:    ret
   %1 = mul i32 %a, 16384
   ret i32 %1
 }
@@ -1015,6 +1521,15 @@ define <4 x i32> @mul_vec_splat_constant(<4 x i32> %a) {
 ; XTENSA-NEXT:    slli a4, a4, 2
 ; XTENSA-NEXT:    slli a5, a5, 2
 ; XTENSA-NEXT:    ret
+;
+; XTENSA-MUL-LABEL: mul_vec_splat_constant:
+; XTENSA-MUL:         .cfi_startproc
+; XTENSA-MUL-NEXT:  # %bb.0:
+; XTENSA-MUL-NEXT:    slli a2, a2, 2
+; XTENSA-MUL-NEXT:    slli a3, a3, 2
+; XTENSA-MUL-NEXT:    slli a4, a4, 2
+; XTENSA-MUL-NEXT:    slli a5, a5, 2
+; XTENSA-MUL-NEXT:    ret
   %mul = mul <4 x i32> %a, <i32 4, i32 4, i32 4, i32 4>
   ret <4 x i32> %mul
 }
diff --git a/llvm/test/CodeGen/Xtensa/rem.ll b/llvm/test/CodeGen/Xtensa/rem.ll
new file mode 100644
index 0000000000000..5246cb4f3cdf7
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/rem.ll
@@ -0,0 +1,49 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=xtensa -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=XTENSA %s
+; RUN: llc -mtriple=xtensa -mattr=+div32 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=XTENSA-DIV %s
+
+define i32 @srem(i32 signext %a0, i32 signext %a1) nounwind readnone {
+; XTENSA-LABEL: srem:
+; XTENSA:       # %bb.0: # %entry
+; XTENSA-NEXT:    addi a8, a1, -16
+; XTENSA-NEXT:    or a1, a8, a8
+; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT:    l32r a8, .LCPI0_0
+; XTENSA-NEXT:    callx0 a8
+; XTENSA-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT:    addi a8, a1, 16
+; XTENSA-NEXT:    or a1, a8, a8
+; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: srem:
+; XTENSA-DIV:       # %bb.0: # %entry
+; XTENSA-DIV-NEXT:    rems a2, a2, a3
+; XTENSA-DIV-NEXT:    ret
+entry:
+  %rem = srem i32 %a0, %a1
+  ret i32 %rem
+}
+
+define i32 @urem(i32 signext %a0, i32 signext %a1) nounwind readnone {
+; XTENSA-LABEL: urem:
+; XTENSA:       # %bb.0: # %entry
+; XTENSA-NEXT:    addi a8, a1, -16
+; XTENSA-NEXT:    or a1, a8, a8
+; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
+; XTENSA-NEXT:    l32r a8, .LCPI1_0
+; XTENSA-NEXT:    callx0 a8
+; XTENSA-NEXT:    l32i a0, a1, 0 # 4-byte Folded Reload
+; XTENSA-NEXT:    addi a8, a1, 16
+; XTENSA-NEXT:    or a1, a8, a8
+; XTENSA-NEXT:    ret
+;
+; XTENSA-DIV-LABEL: urem:
+; XTENSA-DIV:       # %bb.0: # %entry
+; XTENSA-DIV-NEXT:    remu a2, a2, a3
+; XTENSA-DIV-NEXT:    ret
+entry:
+  %rem = urem i32 %a0, %a1
+  ret i32 %rem
+}
diff --git a/llvm/test/MC/Xtensa/div.s b/llvm/test/MC/Xtensa/div.s
new file mode 100644
index 0000000000000..05af7f9dbd081
--- /dev/null
+++ b/llvm/test/MC/Xtensa/div.s
@@ -0,0 +1,24 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+div32 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+.align	4
+
+# Instruction format RRR
+# CHECK-INST: quos a3, a4, a5
+# CHECK: encoding: [0x50,0x34,0xd2]
+quos a3, a4, a5
+
+# Instruction format RRR
+# CHECK-INST: quou a3, a4, a5
+# CHECK: encoding: [0x50,0x34,0xc2]
+quou a3, a4, a5
+
+# Instruction format RRR
+# CHECK-INST: rems a3, a4, a5
+# CHECK: encoding:  [0x50,0x34,0xf2]
+rems a3, a4, a5
+
+# Instruction format RRR
+# CHECK-INST: remu a3, a4, a5
+# CHECK: encoding:  [0x50,0x34,0xe2]
+remu a3, a4, a5
diff --git a/llvm/test/MC/Xtensa/mul.s b/llvm/test/MC/Xtensa/mul.s
new file mode 100644
index 0000000000000..d7096a8128cd6
--- /dev/null
+++ b/llvm/test/MC/Xtensa/mul.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+mul16,mul32high,mul32 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+.align	4
+
+# Instruction format RRR
+# CHECK-INST: mul16s a3, a4, a5
+# CHECK: encoding: [0x50,0x34,0xd1]
+mul16s a3, a4, a5
+
+# Instruction format RRR
+# CHECK-INST: mul16u a3, a4, a5
+# CHECK: encoding: [0x50,0x34,0xc1]
+mul16u a3, a4, a5
+
+# Instruction format RRR
+# CHECK-INST: mull a3, a4, a5
+# CHECK: encoding:  [0x50,0x34,0x82]
+mull a3, a4, a5
+
+# Instruction format RRR
+# CHECK-INST: muluh a3, a4, a5
+# CHECK: encoding:  [0x50,0x34,0xa2]
+muluh a3, a4, a5
+
+# Instruction format RRR
+# CHECK-INST: mulsh a3, a4, a5
+# CHECK: encoding:  [0x50,0x34,0xb2]
+mulsh a3, a4, a5



More information about the llvm-commits mailing list