[llvm] [X86] Lower scalar integer div/rem to FP division (PR #216589)
Ankit Kumar Tiwari via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 10:18:51 PDT 2026
https://github.com/ankit-cybertron updated https://github.com/llvm/llvm-project/pull/216589
>From c357a0f0d52fc616e2eab2e9b1dbda78eac7bae4 Mon Sep 17 00:00:00 2001
From: Ankit Kumar Tiwari <ankit.cybertron at gmail.com>
Date: Sun, 16 Aug 2026 22:43:07 +0530
Subject: [PATCH 1/3] Baseline Test
---
llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll | 119 +++++++++++++++++++
1 file changed, 119 insertions(+)
create mode 100644 llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
diff --git a/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll b/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
new file mode 100644
index 0000000000000..10100c65cab3f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
@@ -0,0 +1,119 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s
+
+define i32 @sdiv_i32(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: sdiv_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: cltd
+; CHECK-NEXT: idivl %esi
+; CHECK-NEXT: retq
+ %r = sdiv i32 %a, %b
+ ret i32 %r
+}
+
+define i16 @sdiv_i16(i16 %a, i16 %b) nounwind {
+; CHECK-LABEL: sdiv_i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
+; CHECK-NEXT: cwtd
+; CHECK-NEXT: idivw %si
+; CHECK-NEXT: retq
+ %r = sdiv i16 %a, %b
+ ret i16 %r
+}
+
+define i8 @sdiv_i8(i8 %a, i8 %b) nounwind {
+; CHECK-LABEL: sdiv_i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movsbl %dil, %eax
+; CHECK-NEXT: idivb %sil
+; CHECK-NEXT: retq
+ %r = sdiv i8 %a, %b
+ ret i8 %r
+}
+
+define i32 @udiv_i32(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: udiv_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: xorl %edx, %edx
+; CHECK-NEXT: divl %esi
+; CHECK-NEXT: retq
+ %r = udiv i32 %a, %b
+ ret i32 %r
+}
+
+define i16 @udiv_i16(i16 %a, i16 %b) nounwind {
+; CHECK-LABEL: udiv_i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
+; CHECK-NEXT: xorl %edx, %edx
+; CHECK-NEXT: divw %si
+; CHECK-NEXT: retq
+ %r = udiv i16 %a, %b
+ ret i16 %r
+}
+
+define i8 @udiv_i8(i8 %a, i8 %b) nounwind {
+; CHECK-LABEL: udiv_i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movzbl %dil, %eax
+; CHECK-NEXT: divb %sil
+; CHECK-NEXT: retq
+ %r = udiv i8 %a, %b
+ ret i8 %r
+}
+
+define i32 @urem_i32(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: urem_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: xorl %edx, %edx
+; CHECK-NEXT: divl %esi
+; CHECK-NEXT: movl %edx, %eax
+; CHECK-NEXT: retq
+ %r = urem i32 %a, %b
+ ret i32 %r
+}
+
+define i64 @sdiv_i64(i64 %a, i64 %b) nounwind {
+; CHECK-LABEL: sdiv_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: cqto
+; CHECK-NEXT: idivq %rsi
+; CHECK-NEXT: retq
+ %r = sdiv i64 %a, %b
+ ret i64 %r
+}
+
+define i32 @sdiv_i32_const(i32 %a) nounwind {
+; CHECK-LABEL: sdiv_i32_const:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movslq %edi, %rax
+; CHECK-NEXT: imulq $-1840700269, %rax, %rcx # imm = 0x92492493
+; CHECK-NEXT: shrq $32, %rcx
+; CHECK-NEXT: addl %ecx, %eax
+; CHECK-NEXT: movl %eax, %ecx
+; CHECK-NEXT: shrl $31, %ecx
+; CHECK-NEXT: sarl $2, %eax
+; CHECK-NEXT: addl %ecx, %eax
+; CHECK-NEXT: # kill: def $eax killed $eax killed $rax
+; CHECK-NEXT: retq
+ %r = sdiv i32 %a, 7
+ ret i32 %r
+}
+
+define i32 @sdiv_i32_noimplicitfloat(i32 %a, i32 %b) nounwind noimplicitfloat {
+; CHECK-LABEL: sdiv_i32_noimplicitfloat:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: cltd
+; CHECK-NEXT: idivl %esi
+; CHECK-NEXT: retq
+ %r = sdiv i32 %a, %b
+ ret i32 %r
+}
>From 16b6894b87f43e531c8768e3f27eb0d85d8a5cd8 Mon Sep 17 00:00:00 2001
From: Ankit Kumar Tiwari <ankit.cybertron at gmail.com>
Date: Sun, 16 Aug 2026 23:12:51 +0530
Subject: [PATCH 2/3] [X86] Lower scalar i8/i16/i32 integer div/rem to FP
division
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 34 ++++++++----
llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll | 58 ++++++++++++++------
2 files changed, 66 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 0dc3340a13c73..1f10178fabd72 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -50720,8 +50720,8 @@ static SDValue combineIntDivRem(SDNode *N, SelectionDAG &DAG,
EVT VT = N->getValueType(0);
SDLoc DL(N);
- // Vector division never survives op legalization to reach later rounds.
- if (!VT.isVector() || !Subtarget.hasSSE2())
+
+ if (!Subtarget.hasSSE2())
return SDValue();
SDValue Dividend = N->getOperand(0);
@@ -50735,9 +50735,17 @@ static SDValue combineIntDivRem(SDNode *N, SelectionDAG &DAG,
bool IsRem = Opc == ISD::UREM || Opc == ISD::SREM;
bool IsSigned = Opc == ISD::SDIV || Opc == ISD::SREM;
+ // Scalar functions that do not use XMM registers must not get this combine.
+ if (!VT.isVector() &&
+ (Subtarget.useSoftFloat() ||
+ DAG.getMachineFunction().getFunction().hasFnAttribute(
+ Attribute::NoImplicitFloat)))
+ return SDValue();
+
// If the result is only read back as scalar extracts, scalarization computes
// just the demanded lanes.
- if (all_of(N->users(), [](const SDNode *U) {
+ if (VT.isVector() &&
+ all_of(N->users(), [](const SDNode *U) {
return U->getOpcode() == ISD::EXTRACT_VECTOR_ELT;
}))
return SDValue();
@@ -50764,16 +50772,21 @@ static SDValue combineIntDivRem(SDNode *N, SelectionDAG &DAG,
MVT FPSclVT = MVT::f64;
if (EltBits <= 16 || BothFitFP(APFloat::IEEEsingle()))
FPSclVT = MVT::f32;
- EVT FPVT = VT.changeVectorElementType(*DAG.getContext(), FPSclVT);
+ EVT FPVT = VT.isVector()
+ ? VT.changeVectorElementType(*DAG.getContext(), FPSclVT)
+ : EVT(FPSclVT);
bool IsStrict = DAG.getMachineFunction().getFunction().hasFnAttribute(
Attribute::StrictFP);
if (IsStrict) {
+ // Scalar strictfp support is not implemented yet.
+ if (!VT.isVector())
+ return SDValue();
// The SAE forms are 512-bit only. Inputs widen into a zmm below, which
// requires 512-bit types to be legal and a power of 2 lane count.
if (!Subtarget.useAVX512Regs() || !isPowerOf2_32(VT.getVectorNumElements()))
return SDValue();
- } else if (!IsSigned && VT.getScalarSizeInBits() == 32 &&
+ } else if (VT.isVector() && !IsSigned && VT.getScalarSizeInBits() == 32 &&
!Subtarget.hasAVX2()) {
// Unsigned i32 needs FP_TO_UINT(f64->u32) which is emulated and a loss
// for latency and code size before AVX2.
@@ -50781,11 +50794,12 @@ static SDValue combineIntDivRem(SDNode *N, SelectionDAG &DAG,
}
// Nothing will split an illegal FP type after type legalization and the
- // strict SAE divide is 512-bit only.
- bool FPVTUsable = IsStrict
- ? FPVT.getSizeInBits() <= 512
- : DCI.isBeforeLegalize() ||
- DAG.getTargetLoweringInfo().isTypeLegal(FPVT);
+ // strict SAE divide is 512-bit only. Scalar f32/f64 are always legal.
+ bool FPVTUsable = !VT.isVector() ||
+ (IsStrict
+ ? FPVT.getSizeInBits() <= 512
+ : DCI.isBeforeLegalize() ||
+ DAG.getTargetLoweringInfo().isTypeLegal(FPVT));
// Halve the divide while the integer halves stay legal.
if (!FPVTUsable) {
diff --git a/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll b/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
index 10100c65cab3f..c752a26703275 100644
--- a/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
+++ b/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
@@ -4,9 +4,10 @@
define i32 @sdiv_i32(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: sdiv_i32:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %eax
-; CHECK-NEXT: cltd
-; CHECK-NEXT: idivl %esi
+; CHECK-NEXT: vcvtsi2sd %esi, %xmm15, %xmm0
+; CHECK-NEXT: vcvtsi2sd %edi, %xmm15, %xmm1
+; CHECK-NEXT: vdivsd %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttsd2si %xmm0, %eax
; CHECK-NEXT: retq
%r = sdiv i32 %a, %b
ret i32 %r
@@ -15,10 +16,13 @@ define i32 @sdiv_i32(i32 %a, i32 %b) nounwind {
define i16 @sdiv_i16(i16 %a, i16 %b) nounwind {
; CHECK-LABEL: sdiv_i16:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: movswl %si, %eax
+; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
+; CHECK-NEXT: movswl %di, %eax
+; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm1
+; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttss2si %xmm0, %eax
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT: cwtd
-; CHECK-NEXT: idivw %si
; CHECK-NEXT: retq
%r = sdiv i16 %a, %b
ret i16 %r
@@ -27,8 +31,13 @@ define i16 @sdiv_i16(i16 %a, i16 %b) nounwind {
define i8 @sdiv_i8(i8 %a, i8 %b) nounwind {
; CHECK-LABEL: sdiv_i8:
; CHECK: # %bb.0:
+; CHECK-NEXT: movsbl %sil, %eax
+; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
; CHECK-NEXT: movsbl %dil, %eax
-; CHECK-NEXT: idivb %sil
+; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm1
+; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttss2si %xmm0, %eax
+; CHECK-NEXT: # kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%r = sdiv i8 %a, %b
ret i8 %r
@@ -37,9 +46,13 @@ define i8 @sdiv_i8(i8 %a, i8 %b) nounwind {
define i32 @udiv_i32(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: udiv_i32:
; CHECK: # %bb.0:
+; CHECK-NEXT: movl %esi, %eax
+; CHECK-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0
; CHECK-NEXT: movl %edi, %eax
-; CHECK-NEXT: xorl %edx, %edx
-; CHECK-NEXT: divl %esi
+; CHECK-NEXT: vcvtsi2sd %rax, %xmm15, %xmm1
+; CHECK-NEXT: vdivsd %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttsd2si %xmm0, %rax
+; CHECK-NEXT: # kill: def $eax killed $eax killed $rax
; CHECK-NEXT: retq
%r = udiv i32 %a, %b
ret i32 %r
@@ -48,10 +61,13 @@ define i32 @udiv_i32(i32 %a, i32 %b) nounwind {
define i16 @udiv_i16(i16 %a, i16 %b) nounwind {
; CHECK-LABEL: udiv_i16:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: movzwl %si, %eax
+; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
+; CHECK-NEXT: movzwl %di, %eax
+; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm1
+; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttss2si %xmm0, %eax
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT: xorl %edx, %edx
-; CHECK-NEXT: divw %si
; CHECK-NEXT: retq
%r = udiv i16 %a, %b
ret i16 %r
@@ -60,8 +76,13 @@ define i16 @udiv_i16(i16 %a, i16 %b) nounwind {
define i8 @udiv_i8(i8 %a, i8 %b) nounwind {
; CHECK-LABEL: udiv_i8:
; CHECK: # %bb.0:
+; CHECK-NEXT: movzbl %sil, %eax
+; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
; CHECK-NEXT: movzbl %dil, %eax
-; CHECK-NEXT: divb %sil
+; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm1
+; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttss2si %xmm0, %eax
+; CHECK-NEXT: # kill: def $al killed $al killed $eax
; CHECK-NEXT: retq
%r = udiv i8 %a, %b
ret i8 %r
@@ -71,9 +92,14 @@ define i32 @urem_i32(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: urem_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %edi, %eax
-; CHECK-NEXT: xorl %edx, %edx
-; CHECK-NEXT: divl %esi
-; CHECK-NEXT: movl %edx, %eax
+; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: vcvtsi2sd %rcx, %xmm15, %xmm0
+; CHECK-NEXT: movl %edi, %ecx
+; CHECK-NEXT: vcvtsi2sd %rcx, %xmm15, %xmm1
+; CHECK-NEXT: vdivsd %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttsd2si %xmm0, %rcx
+; CHECK-NEXT: imull %esi, %ecx
+; CHECK-NEXT: subl %ecx, %eax
; CHECK-NEXT: retq
%r = urem i32 %a, %b
ret i32 %r
>From cc7692dc738def9c8dbc3e4a0b48b77624ad7090 Mon Sep 17 00:00:00 2001
From: Ankit Kumar Tiwari <ankit.cybertron at gmail.com>
Date: Tue, 18 Aug 2026 01:19:49 +0530
Subject: [PATCH 3/3] Fix scalar test parameter extensions
---
llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll | 112 +++++++++----------
1 file changed, 52 insertions(+), 60 deletions(-)
diff --git a/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll b/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
index c752a26703275..d1b9d041944fa 100644
--- a/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
+++ b/llvm/test/CodeGen/X86/scalar-intdiv-to-fp.ll
@@ -13,36 +13,6 @@ define i32 @sdiv_i32(i32 %a, i32 %b) nounwind {
ret i32 %r
}
-define i16 @sdiv_i16(i16 %a, i16 %b) nounwind {
-; CHECK-LABEL: sdiv_i16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: movswl %si, %eax
-; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
-; CHECK-NEXT: movswl %di, %eax
-; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm1
-; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
-; CHECK-NEXT: vcvttss2si %xmm0, %eax
-; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT: retq
- %r = sdiv i16 %a, %b
- ret i16 %r
-}
-
-define i8 @sdiv_i8(i8 %a, i8 %b) nounwind {
-; CHECK-LABEL: sdiv_i8:
-; CHECK: # %bb.0:
-; CHECK-NEXT: movsbl %sil, %eax
-; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
-; CHECK-NEXT: movsbl %dil, %eax
-; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm1
-; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
-; CHECK-NEXT: vcvttss2si %xmm0, %eax
-; CHECK-NEXT: # kill: def $al killed $al killed $eax
-; CHECK-NEXT: retq
- %r = sdiv i8 %a, %b
- ret i8 %r
-}
-
define i32 @udiv_i32(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: udiv_i32:
; CHECK: # %bb.0:
@@ -58,36 +28,6 @@ define i32 @udiv_i32(i32 %a, i32 %b) nounwind {
ret i32 %r
}
-define i16 @udiv_i16(i16 %a, i16 %b) nounwind {
-; CHECK-LABEL: udiv_i16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: movzwl %si, %eax
-; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
-; CHECK-NEXT: movzwl %di, %eax
-; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm1
-; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
-; CHECK-NEXT: vcvttss2si %xmm0, %eax
-; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT: retq
- %r = udiv i16 %a, %b
- ret i16 %r
-}
-
-define i8 @udiv_i8(i8 %a, i8 %b) nounwind {
-; CHECK-LABEL: udiv_i8:
-; CHECK: # %bb.0:
-; CHECK-NEXT: movzbl %sil, %eax
-; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
-; CHECK-NEXT: movzbl %dil, %eax
-; CHECK-NEXT: vcvtsi2ss %eax, %xmm15, %xmm1
-; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
-; CHECK-NEXT: vcvttss2si %xmm0, %eax
-; CHECK-NEXT: # kill: def $al killed $al killed $eax
-; CHECK-NEXT: retq
- %r = udiv i8 %a, %b
- ret i8 %r
-}
-
define i32 @urem_i32(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: urem_i32:
; CHECK: # %bb.0:
@@ -143,3 +83,55 @@ define i32 @sdiv_i32_noimplicitfloat(i32 %a, i32 %b) nounwind noimplicitfloat {
%r = sdiv i32 %a, %b
ret i32 %r
}
+
+define signext i8 @sdiv_i8(i8 signext %a, i8 signext %b) nounwind {
+; CHECK-LABEL: sdiv_i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vcvtsi2ss %esi, %xmm15, %xmm0
+; CHECK-NEXT: vcvtsi2ss %edi, %xmm15, %xmm1
+; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttss2si %xmm0, %eax
+; CHECK-NEXT: # kill: def $al killed $al killed $eax
+; CHECK-NEXT: retq
+ %r = sdiv i8 %a, %b
+ ret i8 %r
+}
+
+define zeroext i8 @udiv_i8(i8 zeroext %a, i8 zeroext %b) nounwind {
+; CHECK-LABEL: udiv_i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vcvtsi2ss %esi, %xmm15, %xmm0
+; CHECK-NEXT: vcvtsi2ss %edi, %xmm15, %xmm1
+; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttss2si %xmm0, %eax
+; CHECK-NEXT: # kill: def $al killed $al killed $eax
+; CHECK-NEXT: retq
+ %r = udiv i8 %a, %b
+ ret i8 %r
+}
+
+define signext i16 @sdiv_i16(i16 signext %a, i16 signext %b) nounwind {
+; CHECK-LABEL: sdiv_i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vcvtsi2ss %esi, %xmm15, %xmm0
+; CHECK-NEXT: vcvtsi2ss %edi, %xmm15, %xmm1
+; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttss2si %xmm0, %eax
+; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
+; CHECK-NEXT: retq
+ %r = sdiv i16 %a, %b
+ ret i16 %r
+}
+
+define zeroext i16 @udiv_i16(i16 zeroext %a, i16 zeroext %b) nounwind {
+; CHECK-LABEL: udiv_i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vcvtsi2ss %esi, %xmm15, %xmm0
+; CHECK-NEXT: vcvtsi2ss %edi, %xmm15, %xmm1
+; CHECK-NEXT: vdivss %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: vcvttss2si %xmm0, %eax
+; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
+; CHECK-NEXT: retq
+ %r = udiv i16 %a, %b
+ ret i16 %r
+}
More information about the llvm-commits
mailing list