llvm/llvm/test/CodeGen/Xtensa/mul.ll

; 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

define signext i32 @square(i32 %a) nounwind {
; XTENSA-LABEL: square:
; XTENSA:         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:    or a3, a2, a2
; 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
  %1 = mul i32 %a, %a
  ret i32 %1
}

define signext i32 @mul(i32 %a, i32 %b) nounwind {
; XTENSA-LABEL: mul:
; XTENSA:         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
  %1 = mul i32 %a, %b
  ret i32 %1
}

define signext i32 @mul_constant(i32 %a) nounwind {
; XTENSA-LABEL: mul_constant:
; XTENSA:         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
; XTENSA-NEXT:    l32r a8, .LCPI2_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
  %1 = mul i32 %a, 5
  ret i32 %1
}

define i32 @mul_pow2(i32 %a) nounwind {
; XTENSA-LABEL: mul_pow2:
; XTENSA:         slli a2, a2, 3
; XTENSA-NEXT:    ret
  %1 = mul i32 %a, 8
  ret i32 %1
}

define i64 @mul64(i64 %a, i64 %b) nounwind {
; XTENSA-LABEL: mul64:
; XTENSA:         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
; 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
  %1 = mul i64 %a, %b
  ret i64 %1
}

define i64 @mul64_constant(i64 %a) nounwind {
; XTENSA-LABEL: mul64_constant:
; XTENSA:         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
; XTENSA-NEXT:    movi a5, 0
; XTENSA-NEXT:    l32r a8, .LCPI5_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
  %1 = mul i64 %a, 5
  ret i64 %1
}

define i32 @mulhs(i32 %a, i32 %b) nounwind {
; XTENSA-LABEL: mulhs:
; XTENSA:         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
; XTENSA-NEXT:    srai a3, a2, 31
; XTENSA-NEXT:    srai a5, a4, 31
; XTENSA-NEXT:    l32r a8, .LCPI6_0
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    or a2, a3, a3
; 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
  %1 = sext i32 %a to i64
  %2 = sext i32 %b to i64
  %3 = mul i64 %1, %2
  %4 = lshr i64 %3, 32
  %5 = trunc i64 %4 to i32
  ret i32 %5
}

define i32 @mulhs_positive_constant(i32 %a) nounwind {
; XTENSA-LABEL: mulhs_positive_constant:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    srai a3, a2, 31
; XTENSA-NEXT:    movi a4, 5
; XTENSA-NEXT:    movi a5, 0
; XTENSA-NEXT:    l32r a8, .LCPI7_0
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    or a2, a3, a3
; 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
  %1 = sext i32 %a to i64
  %2 = mul i64 %1, 5
  %3 = lshr i64 %2, 32
  %4 = trunc i64 %3 to i32
  ret i32 %4
}

define i32 @mulhs_negative_constant(i32 %a) nounwind {
; XTENSA-LABEL: mulhs_negative_constant:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    srai a3, a2, 31
; XTENSA-NEXT:    movi a4, -5
; XTENSA-NEXT:    movi a5, -1
; XTENSA-NEXT:    l32r a8, .LCPI8_0
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    or a2, a3, a3
; 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
  %1 = sext i32 %a to i64
  %2 = mul i64 %1, -5
  %3 = lshr i64 %2, 32
  %4 = trunc i64 %3 to i32
  ret i32 %4
}

define zeroext i32 @mulhu(i32 zeroext %a, i32 zeroext %b) nounwind {
; XTENSA-LABEL: mulhu:
; XTENSA:         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
; XTENSA-NEXT:    movi a3, 0
; XTENSA-NEXT:    l32r a8, .LCPI9_0
; XTENSA-NEXT:    or a5, a3, a3
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    or a2, a3, a3
; 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
  %1 = zext i32 %a to i64
  %2 = zext i32 %b to i64
  %3 = mul i64 %1, %2
  %4 = lshr i64 %3, 32
  %5 = trunc i64 %4 to i32
  ret i32 %5
}

define i32 @mulhsu(i32 %a, i32 %b) nounwind {
; XTENSA-LABEL: mulhsu:
; XTENSA:         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
; XTENSA-NEXT:    srai a5, a4, 31
; XTENSA-NEXT:    movi a3, 0
; XTENSA-NEXT:    l32r a8, .LCPI10_0
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    or a2, a3, a3
; 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
  %1 = zext i32 %a to i64
  %2 = sext i32 %b to i64
  %3 = mul i64 %1, %2
  %4 = lshr i64 %3, 32
  %5 = trunc i64 %4 to i32
  ret i32 %5
}

define i32 @mulhu_constant(i32 %a) nounwind {
; XTENSA-LABEL: mulhu_constant:
; XTENSA:         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
; XTENSA-NEXT:    movi a3, 0
; XTENSA-NEXT:    l32r a8, .LCPI11_0
; XTENSA-NEXT:    or a5, a3, a3
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    or a2, a3, a3
; 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
  %1 = zext i32 %a to i64
  %2 = mul i64 %1, 5
  %3 = lshr i64 %2, 32
  %4 = trunc i64 %3 to i32
  ret i32 %4
}

define i32 @muli32_p65(i32 %a) nounwind {
; XTENSA-LABEL: muli32_p65:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a3, 65
; XTENSA-NEXT:    l32r a8, .LCPI12_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
  %1 = mul i32 %a, 65
  ret i32 %1
}

define i32 @muli32_p63(i32 %a) nounwind {
; XTENSA-LABEL: muli32_p63:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a3, 63
; XTENSA-NEXT:    l32r a8, .LCPI13_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
  %1 = mul i32 %a, 63
  ret i32 %1
}

define i64 @muli64_p65(i64 %a) nounwind {
; XTENSA-LABEL: muli64_p65:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a4, 65
; XTENSA-NEXT:    movi a5, 0
; XTENSA-NEXT:    l32r a8, .LCPI14_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
  %1 = mul i64 %a, 65
  ret i64 %1
}

define i64 @muli64_p63(i64 %a) nounwind {
; XTENSA-LABEL: muli64_p63:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a4, 63
; XTENSA-NEXT:    movi a5, 0
; XTENSA-NEXT:    l32r a8, .LCPI15_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
  %1 = mul i64 %a, 63
  ret i64 %1
}

define i32 @muli32_m63(i32 %a) nounwind {
; XTENSA-LABEL: muli32_m63:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a3, -63
; XTENSA-NEXT:    l32r a8, .LCPI16_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
  %1 = mul i32 %a, -63
  ret i32 %1
}

define i32 @muli32_m65(i32 %a) nounwind {
; XTENSA-LABEL: muli32_m65:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a3, -65
; XTENSA-NEXT:    l32r a8, .LCPI17_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
  %1 = mul i32 %a, -65
  ret i32 %1
}

define i64 @muli64_m63(i64 %a) nounwind {
; XTENSA-LABEL: muli64_m63:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a4, -63
; XTENSA-NEXT:    movi a5, -1
; XTENSA-NEXT:    l32r a8, .LCPI18_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
  %1 = mul i64 %a, -63
  ret i64 %1
}

define i64 @muli64_m65(i64 %a) nounwind {
; XTENSA-LABEL: muli64_m65:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a4, -65
; XTENSA-NEXT:    movi a5, -1
; XTENSA-NEXT:    l32r a8, .LCPI19_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
  %1 = mul i64 %a, -65
  ret i64 %1
}

define i32 @muli32_p384(i32 %a) nounwind {
; XTENSA-LABEL: muli32_p384:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a3, 384
; XTENSA-NEXT:    l32r a8, .LCPI20_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
  %1 = mul i32 %a, 384
  ret i32 %1
}

define i32 @muli32_p12288(i32 %a) nounwind {
; XTENSA-LABEL: muli32_p12288:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a3, .LCPI21_0
; XTENSA-NEXT:    l32r a8, .LCPI21_1
; 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
  %1 = mul i32 %a, 12288
  ret i32 %1
}

define i32 @muli32_p4352(i32 %a) nounwind {
; XTENSA-LABEL: muli32_p4352:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a3, .LCPI22_0
; XTENSA-NEXT:    l32r a8, .LCPI22_1
; 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
  %1 = mul i32 %a, 4352
  ret i32 %1
}

define i32 @muli32_p3840(i32 %a) nounwind {
; XTENSA-LABEL: muli32_p3840:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a3, .LCPI23_0
; XTENSA-NEXT:    l32r a8, .LCPI23_1
; 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
  %1 = mul i32 %a, 3840
  ret i32 %1
}

define i32 @muli32_m3840(i32 %a) nounwind {
; XTENSA-LABEL: muli32_m3840:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a3, .LCPI24_0
; XTENSA-NEXT:    l32r a8, .LCPI24_1
; 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
  %1 = mul i32 %a, -3840
  ret i32 %1
}

define i32 @muli32_m4352(i32 %a) nounwind {
; XTENSA-LABEL: muli32_m4352:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a3, .LCPI25_0
; XTENSA-NEXT:    l32r a8, .LCPI25_1
; 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
  %1 = mul i32 %a, -4352
  ret i32 %1
}

define i64 @muli64_p4352(i64 %a) nounwind {
; XTENSA-LABEL: muli64_p4352:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a4, .LCPI26_0
; XTENSA-NEXT:    movi a5, 0
; XTENSA-NEXT:    l32r a8, .LCPI26_1
; 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
  %1 = mul i64 %a, 4352
  ret i64 %1
}

define i64 @muli64_p3840(i64 %a) nounwind {
; XTENSA-LABEL: muli64_p3840:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a4, .LCPI27_0
; XTENSA-NEXT:    movi a5, 0
; XTENSA-NEXT:    l32r a8, .LCPI27_1
; 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
  %1 = mul i64 %a, 3840
  ret i64 %1
}

define i64 @muli64_m4352(i64 %a) nounwind {
; XTENSA-LABEL: muli64_m4352:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a4, .LCPI28_0
; XTENSA-NEXT:    movi a5, -1
; XTENSA-NEXT:    l32r a8, .LCPI28_1
; 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
  %1 = mul i64 %a, -4352
  ret i64 %1
}

define i64 @muli64_m3840(i64 %a) nounwind {
; XTENSA-LABEL: muli64_m3840:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 0 # 4-byte Folded Spill
; XTENSA-NEXT:    l32r a4, .LCPI29_0
; XTENSA-NEXT:    movi a5, -1
; XTENSA-NEXT:    l32r a8, .LCPI29_1
; 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
  %1 = mul i64 %a, -3840
  ret i64 %1
}

define i128 @muli128_m3840(i128 %a) nounwind {
; XTENSA-LABEL: muli128_m3840:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 8 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a7, -1
; XTENSA-NEXT:    s32i a7, a1, 4
; XTENSA-NEXT:    s32i a7, a1, 0
; XTENSA-NEXT:    l32r a6, .LCPI30_0
; XTENSA-NEXT:    l32r a8, .LCPI30_1
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    l32i a0, a1, 8 # 4-byte Folded Reload
; XTENSA-NEXT:    addi a8, a1, 16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    ret
  %1 = mul i128 %a, -3840
  ret i128 %1
}

define i128 @muli128_m63(i128 %a) nounwind {
; XTENSA-LABEL: muli128_m63:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 8 # 4-byte Folded Spill
; XTENSA-NEXT:    movi a7, -1
; XTENSA-NEXT:    s32i a7, a1, 4
; XTENSA-NEXT:    s32i a7, a1, 0
; XTENSA-NEXT:    movi a6, -63
; XTENSA-NEXT:    l32r a8, .LCPI31_0
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    l32i a0, a1, 8 # 4-byte Folded Reload
; XTENSA-NEXT:    addi a8, a1, 16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    ret
  %1 = mul i128 %a, -63
  ret i128 %1
}

define i64 @mulhsu_i64(i64 %a, i64 %b) nounwind {
; XTENSA-LABEL: mulhsu_i64:
; XTENSA:         addi a8, a1, -16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    s32i a0, a1, 8 # 4-byte Folded Spill
; XTENSA-NEXT:    or a7, a5, a5
; XTENSA-NEXT:    or a6, a4, a4
; XTENSA-NEXT:    srai a8, a7, 31
; XTENSA-NEXT:    s32i a8, a1, 4
; XTENSA-NEXT:    s32i a8, a1, 0
; XTENSA-NEXT:    movi a4, 0
; XTENSA-NEXT:    l32r a8, .LCPI32_0
; XTENSA-NEXT:    or a5, a4, a4
; XTENSA-NEXT:    callx0 a8
; XTENSA-NEXT:    or a2, a4, a4
; XTENSA-NEXT:    or a3, a5, a5
; XTENSA-NEXT:    l32i a0, a1, 8 # 4-byte Folded Reload
; XTENSA-NEXT:    addi a8, a1, 16
; XTENSA-NEXT:    or a1, a8, a8
; XTENSA-NEXT:    ret
  %1 = zext i64 %a to i128
  %2 = sext i64 %b to i128
  %3 = mul i128 %1, %2
  %4 = lshr i128 %3, 64
  %5 = trunc i128 %4 to i64
  ret i64 %5
}

define i8 @muladd_demand(i8 %x, i8 %y) nounwind {
; XTENSA-LABEL: muladd_demand:
; XTENSA:         slli a8, a2, 1
; XTENSA-NEXT:    sub a8, a3, a8
; XTENSA-NEXT:    movi a9, 15
; XTENSA-NEXT:    and a2, a8, a9
; XTENSA-NEXT:    ret
  %m = mul i8 %x, 14
  %a = add i8 %y, %m
  %r = and i8 %a, 15
  ret i8 %r
}

define i8 @mulsub_demand(i8 %x, i8 %y) nounwind {
; XTENSA-LABEL: mulsub_demand:
; XTENSA:         addx2 a8, a2, a3
; XTENSA-NEXT:    movi a9, 15
; XTENSA-NEXT:    and a2, a8, a9
; XTENSA-NEXT:    ret
  %m = mul i8 %x, 14
  %a = sub i8 %y, %m
  %r = and i8 %a, 15
  ret i8 %r
}

define i8 @muladd_demand_2(i8 %x, i8 %y) nounwind {
; XTENSA-LABEL: muladd_demand_2:
; XTENSA:         slli a8, a2, 1
; XTENSA-NEXT:    sub a8, a3, a8
; XTENSA-NEXT:    movi a9, -16
; XTENSA-NEXT:    or a2, a8, a9
; XTENSA-NEXT:    ret
  %m = mul i8 %x, 14
  %a = add i8 %y, %m
  %r = or i8 %a, 240
  ret i8 %r
}

define i8 @mulsub_demand_2(i8 %x, i8 %y) nounwind {
; XTENSA-LABEL: mulsub_demand_2:
; XTENSA:         addx2 a8, a2, a3
; XTENSA-NEXT:    movi a9, -16
; XTENSA-NEXT:    or a2, a8, a9
; XTENSA-NEXT:    ret
  %m = mul i8 %x, 14
  %a = sub i8 %y, %m
  %r = or i8 %a, 240
  ret i8 %r
}

define signext i32 @mul_imm_2(i32 %a) nounwind {
; XTENSA-LABEL: mul_imm_2:
; XTENSA:         slli a2, a2, 1
; XTENSA-NEXT:    ret
  %1 = mul i32 %a, 2
  ret i32 %1
}

define signext i32 @mul_imm_1024(i32 %a) nounwind {
; XTENSA-LABEL: mul_imm_1024:
; XTENSA:         slli a2, a2, 10
; XTENSA-NEXT:    ret
  %1 = mul i32 %a, 1024
  ret i32 %1
}

define signext i32 @mul_imm_16384(i32 %a) nounwind {
; XTENSA-LABEL: mul_imm_16384:
; XTENSA:         slli a2, a2, 14
; XTENSA-NEXT:    ret
  %1 = mul i32 %a, 16384
  ret i32 %1
}

define <4 x i32> @mul_vec_splat_constant(<4 x i32> %a) {
; XTENSA-LABEL: mul_vec_splat_constant:
; XTENSA:         slli a2, a2, 2
; XTENSA-NEXT:    slli a3, a3, 2
; XTENSA-NEXT:    slli a4, a4, 2
; XTENSA-NEXT:    slli a5, a5, 2
; XTENSA-NEXT:    ret
  %mul = mul <4 x i32> %a, <i32 4, i32 4, i32 4, i32 4>
  ret <4 x i32> %mul
}