[llvm] [GlobalISel] [AArch64] Skip redundant shift amount masking during isel (PR #223136)

Deepak Shirke via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 11:16:01 PDT 2026


https://github.com/deepakshirkem updated https://github.com/llvm/llvm-project/pull/223136

>From 2742d985c4f012a9f487f54fc583a52612309e32 Mon Sep 17 00:00:00 2001
From: deepakshirkem <deepakshirke509 at gmail.com>
Date: Mon, 14 Sep 2026 18:14:17 +0530
Subject: [PATCH] AArch64: Skip redundant shift amount masking using isel
 ComplexPattern

AArch64 shift instructions (LSL/LSR/ASR) only use the low 5 bits (i32)
or 6 bits (i64) of the shift amount. Add SelectShiftMask ComplexPattern
and GIComplexOperandMatcher that strip redundant AND masks or zero-extensions
from shift amounts during instruction selection, when the mask exactly
covers a narrow type (byte, halfword, or word).

This mirrors what AArch64DAGToDAGISel::tryShiftAmountMod does, and adds
equivalent GlobalISel support via GIComplexPatternEquiv.
---
 .../Target/AArch64/AArch64ISelDAGToDAG.cpp    |   22 +
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |   18 +
 .../GISel/AArch64InstructionSelector.cpp      |   59 +
 .../AArch64/GlobalISel/shift-amount-mod.ll    |   79 +
 llvm/test/CodeGen/AArch64/extract-bits.ll     |   42 +-
 llvm/test/CodeGen/AArch64/extract-lowbits.ll  |   20 +-
 llvm/test/CodeGen/AArch64/fcvt-i256.ll        | 1346 ++++++-----------
 llvm/test/CodeGen/AArch64/frem-power2.ll      |    6 +-
 llvm/test/CodeGen/AArch64/fsh.ll              |   37 +-
 llvm/test/CodeGen/AArch64/funnel-shift.ll     |  130 +-
 ...st-and-by-const-from-lshr-in-eqcmp-zero.ll |   47 +-
 ...ist-and-by-const-from-shl-in-eqcmp-zero.ll |   24 +-
 llvm/test/CodeGen/AArch64/select_const.ll     |    3 -
 llvm/test/CodeGen/AArch64/shift-mod.ll        |   10 +-
 llvm/test/CodeGen/AArch64/shift.ll            |   96 +-
 15 files changed, 785 insertions(+), 1154 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/shift-amount-mod.ll

diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 531478517ef9a..add0af20b6f9c 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -89,6 +89,9 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
   bool SelectLogicalShiftedRegister(SDValue N, SDValue &Reg, SDValue &Shift) {
     return SelectShiftedRegister(N, true, Reg, Shift);
   }
+  template <unsigned ShiftWidth>
+  bool SelectShiftMask(SDValue N, SDValue &ShAmt);
+
   bool SelectAddrModeIndexed7S8(SDValue N, SDValue &Base, SDValue &OffImm) {
     return SelectAddrModeIndexed7S(N, 1, Base, OffImm);
   }
@@ -765,6 +768,25 @@ bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
 /// SelectArithImmed - Select an immediate value that can be represented as
 /// a 12-bit value shifted left by either 0 or 12.  If so, return true with
 /// Val set to the 12-bit value and Shift set to the shifter operand.
+template <unsigned ShiftWidth>
+bool AArch64DAGToDAGISel::SelectShiftMask(SDValue N, SDValue &ShAmt) {
+  // AArch64 shift instructions only use the low log2(ShiftWidth) bits of the
+  // shift amount. If the shift amount has a redundant AND mask that exactly
+  // covers a narrow type, we can remove it.
+  // Note: do not strip ZERO_EXTEND/ANY_EXTEND here as that can cause
+  // register class mismatches (e.g. returning a 32-bit value for an i64 shift).
+  if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1)) &&
+      N.getValueType() == (ShiftWidth == 32 ? MVT::i32 : MVT::i64)) {
+    uint64_t Mask = N.getConstantOperandVal(1);
+    // Only remove AND if it exactly masks a narrow type (byte, halfword, word).
+    if (Mask == 0xff || Mask == 0xffff || Mask == 0xffffffff)
+      N = N.getOperand(0);
+  }
+
+  ShAmt = N;
+  return true;
+}
+
 bool AArch64DAGToDAGISel::SelectArithImmed(SDValue N, SDValue &Val,
                                            SDValue &Shift) {
   // This function is called from the addsub_shifted_imm ComplexPattern,
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index ac2f9b16ca229..b230e61bb8c17 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -2967,6 +2967,24 @@ def : ShiftAlias<"lsrv", LSRVXr, GPR64>;
 def : ShiftAlias<"rorv", RORVWr, GPR32>;
 def : ShiftAlias<"rorv", RORVXr, GPR64>;
 
+// ComplexPattern to match shift amounts with redundant AND masks.
+// AArch64 shift instructions only use the low 5 bits (i32) or 6 bits (i64),
+// so AND masks that cover those bits are redundant.
+def shiftMask32 : ComplexPattern<i32, 1, "SelectShiftMask<32>", [], [], 0>;
+def gi_shift_mask32 : GIComplexOperandMatcher<s32, "selectShiftMask32">,
+                      GIComplexPatternEquiv<shiftMask32>;
+
+def : Pat<(i32 (shl GPR32:$Rn, shiftMask32:$Rm)), (LSLVWr GPR32:$Rn, shiftMask32:$Rm)>;
+def : Pat<(i32 (srl GPR32:$Rn, shiftMask32:$Rm)), (LSRVWr GPR32:$Rn, shiftMask32:$Rm)>;
+def : Pat<(i32 (sra GPR32:$Rn, shiftMask32:$Rm)), (ASRVWr GPR32:$Rn, shiftMask32:$Rm)>;
+def shiftMask64 : ComplexPattern<i64, 1, "SelectShiftMask<64>", [], [], 0>;
+def gi_shift_mask64 : GIComplexOperandMatcher<s64, "selectShiftMask64">,
+                      GIComplexPatternEquiv<shiftMask64>;
+
+def : Pat<(i64 (shl GPR64:$Rn, shiftMask64:$Rm)), (LSLVXr GPR64:$Rn, shiftMask64:$Rm)>;
+def : Pat<(i64 (srl GPR64:$Rn, shiftMask64:$Rm)), (LSRVXr GPR64:$Rn, shiftMask64:$Rm)>;
+def : Pat<(i64 (sra GPR64:$Rn, shiftMask64:$Rm)), (ASRVXr GPR64:$Rn, shiftMask64:$Rm)>;
+
 // Multiply-add
 let AddedComplexity = 5 in {
 defm MADD : MulAccum<0, "madd">;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 0499d7771683e..4b543e43ef435 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -385,6 +385,8 @@ class AArch64InstructionSelector : public InstructionSelector {
   ComplexRendererFns selectShiftA_64(const MachineOperand &Root) const;
   ComplexRendererFns selectShiftB_64(const MachineOperand &Root) const;
 
+  ComplexRendererFns selectShiftMask32(MachineOperand &Root) const;
+  ComplexRendererFns selectShiftMask64(MachineOperand &Root) const;
   ComplexRendererFns select12BitValueWithLeftShift(uint64_t Immed) const;
   ComplexRendererFns selectArithImmed(MachineOperand &Root) const;
   ComplexRendererFns selectNegArithImmed(MachineOperand &Root) const;
@@ -7302,6 +7304,63 @@ AArch64InstructionSelector::selectShiftB_64(const MachineOperand &Root) const {
   return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(Enc); }}};
 }
 
+InstructionSelector::ComplexRendererFns
+AArch64InstructionSelector::selectShiftMask32(MachineOperand &Root) const {
+  if (!Root.isReg())
+    return std::nullopt;
+
+  MachineRegisterInfo &MRI =
+      Root.getParent()->getParent()->getParent()->getRegInfo();
+
+  Register ShAmtReg = Root.getReg();
+
+  // Peek through zext.
+  Register ZExtSrcReg;
+  if (mi_match(ShAmtReg, MRI, m_GZExt(m_Reg(ZExtSrcReg))))
+    ShAmtReg = ZExtSrcReg;
+
+  // Remove redundant AND mask. AArch64 i32 shift instructions only use
+  // the low 5 bits of the shift amount, so an AND that covers those bits
+  // is redundant.
+  APInt AndMask;
+  Register AndSrcReg;
+  if (mi_match(ShAmtReg, MRI, m_GAnd(m_Reg(AndSrcReg), m_ICst(AndMask)))) {
+    APInt ShMask(AndMask.getBitWidth(), 31);
+    if (ShMask.isSubsetOf(AndMask))
+      ShAmtReg = AndSrcReg;
+  }
+
+  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
+}
+
+InstructionSelector::ComplexRendererFns
+AArch64InstructionSelector::selectShiftMask64(MachineOperand &Root) const {
+  if (!Root.isReg())
+    return std::nullopt;
+
+  MachineRegisterInfo &MRI =
+      Root.getParent()->getParent()->getParent()->getRegInfo();
+
+  Register ShAmtReg = Root.getReg();
+
+  // Peek through zext.
+  Register ZExtSrcReg;
+  if (mi_match(ShAmtReg, MRI, m_GZExt(m_Reg(ZExtSrcReg))))
+    ShAmtReg = ZExtSrcReg;
+
+  // Remove redundant AND mask introduced by legalization of a narrow zext.
+  // Only remove if the mask exactly covers a byte, halfword, or word.
+  APInt AndMask;
+  Register AndSrcReg;
+  if (mi_match(ShAmtReg, MRI, m_GAnd(m_Reg(AndSrcReg), m_ICst(AndMask)))) {
+    uint64_t UMask = AndMask.getZExtValue();
+    if (UMask == 0xff || UMask == 0xffff || UMask == 0xffffffff)
+      ShAmtReg = AndSrcReg;
+  }
+
+  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
+}
+
 /// Helper to select an immediate value that can be represented as a 12-bit
 /// value shifted left by either 0 or 12. If it is possible to do so, return
 /// the immediate and shift value. If not, return std::nullopt.
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/shift-amount-mod.ll b/llvm/test/CodeGen/AArch64/GlobalISel/shift-amount-mod.ll
new file mode 100644
index 0000000000000..75fd645e0cdf9
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/shift-amount-mod.ll
@@ -0,0 +1,79 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -global-isel -mtriple=aarch64 < %s | FileCheck %s --check-prefixes=CHECK,GI
+; RUN: llc -global-isel=0 -mtriple=aarch64 < %s | FileCheck %s --check-prefixes=CHECK,SD
+
+define i32 @shl_i32_i8(i32 %x, i8 %amt) {
+; CHECK-LABEL: shl_i32_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsl w0, w0, w1
+; CHECK-NEXT:    ret
+  %ext = zext i8 %amt to i32
+  %r = shl i32 %x, %ext
+  ret i32 %r
+}
+
+define i32 @lshr_i32_i8(i32 %x, i8 %amt) {
+; CHECK-LABEL: lshr_i32_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsr w0, w0, w1
+; CHECK-NEXT:    ret
+  %ext = zext i8 %amt to i32
+  %r = lshr i32 %x, %ext
+  ret i32 %r
+}
+
+define i32 @ashr_i32_i8(i32 %x, i8 %amt) {
+; CHECK-LABEL: ashr_i32_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    asr w0, w0, w1
+; CHECK-NEXT:    ret
+  %ext = zext i8 %amt to i32
+  %r = ashr i32 %x, %ext
+  ret i32 %r
+}
+
+define i32 @shl_i32_i16(i32 %x, i16 %amt) {
+; CHECK-LABEL: shl_i32_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsl w0, w0, w1
+; CHECK-NEXT:    ret
+  %ext = zext i16 %amt to i32
+  %r = shl i32 %x, %ext
+  ret i32 %r
+}
+
+define i64 @shl_i64_i8(i64 %x, i8 %amt) {
+; CHECK-LABEL: shl_i64_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT:    lsl x0, x0, x1
+; CHECK-NEXT:    ret
+  %ext = zext i8 %amt to i64
+  %r = shl i64 %x, %ext
+  ret i64 %r
+}
+
+define i64 @lshr_i64_i8(i64 %x, i8 %amt) {
+; CHECK-LABEL: lshr_i64_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT:    lsr x0, x0, x1
+; CHECK-NEXT:    ret
+  %ext = zext i8 %amt to i64
+  %r = lshr i64 %x, %ext
+  ret i64 %r
+}
+
+define i64 @ashr_i64_i16(i64 %x, i16 %amt) {
+; CHECK-LABEL: ashr_i64_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT:    asr x0, x0, x1
+; CHECK-NEXT:    ret
+  %ext = zext i16 %amt to i64
+  %r = ashr i64 %x, %ext
+  ret i64 %r
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; GI: {{.*}}
+; SD: {{.*}}
diff --git a/llvm/test/CodeGen/AArch64/extract-bits.ll b/llvm/test/CodeGen/AArch64/extract-bits.ll
index 5a96116142b51..5d9cfe9be48b6 100644
--- a/llvm/test/CodeGen/AArch64/extract-bits.ll
+++ b/llvm/test/CodeGen/AArch64/extract-bits.ll
@@ -159,11 +159,11 @@ define i64 @bextr64_a0_arithmetic(i64 %val, i64 %numskipbits, i64 %numlowbits) n
 define i64 @bextr64_a1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
 ; CHECK-LABEL: bextr64_a1_indexzext:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mov w8, #1 // =0x1
-; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    lsr x9, x0, x1
-; CHECK-NEXT:    lsl x8, x8, x2
+; CHECK-NEXT:    mov w8, w2
+; CHECK-NEXT:    mov w9, #1 // =0x1
+; CHECK-NEXT:    mov w10, w1
+; CHECK-NEXT:    lsl x8, x9, x8
+; CHECK-NEXT:    lsr x9, x0, x10
 ; CHECK-NEXT:    sub x8, x8, #1
 ; CHECK-NEXT:    and x0, x8, x9
 ; CHECK-NEXT:    ret
@@ -198,11 +198,11 @@ define i64 @bextr64_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroex
 ; CHECK-LABEL: bextr64_a3_load_indexzext:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ldr x8, [x0]
-; CHECK-NEXT:    mov w9, #1 // =0x1
-; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    lsl x9, x9, x2
-; CHECK-NEXT:    lsr x8, x8, x1
+; CHECK-NEXT:    mov w9, w2
+; CHECK-NEXT:    mov w10, #1 // =0x1
+; CHECK-NEXT:    mov w11, w1
+; CHECK-NEXT:    lsl x9, x10, x9
+; CHECK-NEXT:    lsr x8, x8, x11
 ; CHECK-NEXT:    sub x9, x9, #1
 ; CHECK-NEXT:    and x0, x9, x8
 ; CHECK-NEXT:    ret
@@ -397,12 +397,12 @@ define i64 @bextr64_b0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
 define i64 @bextr64_b1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {
 ; CHECK-LABEL: bextr64_b1_indexzext:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mov x8, #-1 // =0xffffffffffffffff
-; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    lsr x9, x0, x1
-; CHECK-NEXT:    lsl x8, x8, x2
-; CHECK-NEXT:    bic x0, x9, x8
+; CHECK-NEXT:    mov w8, w1
+; CHECK-NEXT:    mov w9, w2
+; CHECK-NEXT:    mov x10, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    lsr x8, x0, x8
+; CHECK-NEXT:    lsl x9, x10, x9
+; CHECK-NEXT:    bic x0, x8, x9
 ; CHECK-NEXT:    ret
   %skip = zext i8 %numskipbits to i64
   %shifted = lshr i64 %val, %skip
@@ -434,11 +434,11 @@ define i64 @bextr64_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroex
 ; CHECK-LABEL: bextr64_b3_load_indexzext:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ldr x8, [x0]
-; CHECK-NEXT:    mov x9, #-1 // =0xffffffffffffffff
-; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    lsl x9, x9, x2
-; CHECK-NEXT:    lsr x8, x8, x1
+; CHECK-NEXT:    mov w9, w1
+; CHECK-NEXT:    mov w10, w2
+; CHECK-NEXT:    mov x11, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    lsr x8, x8, x9
+; CHECK-NEXT:    lsl x9, x11, x10
 ; CHECK-NEXT:    bic x0, x8, x9
 ; CHECK-NEXT:    ret
   %val = load i64, ptr %w
diff --git a/llvm/test/CodeGen/AArch64/extract-lowbits.ll b/llvm/test/CodeGen/AArch64/extract-lowbits.ll
index 368440c65df84..1696de12944e9 100644
--- a/llvm/test/CodeGen/AArch64/extract-lowbits.ll
+++ b/llvm/test/CodeGen/AArch64/extract-lowbits.ll
@@ -130,8 +130,8 @@ define i64 @bzhi64_a1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind {
 ; CHECK-LABEL: bzhi64_a1_indexzext:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    mov w8, #1 // =0x1
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    lsl x8, x8, x1
+; CHECK-NEXT:    mov w9, w1
+; CHECK-NEXT:    lsl x8, x8, x9
 ; CHECK-NEXT:    sub x8, x8, #1
 ; CHECK-NEXT:    and x0, x8, x0
 ; CHECK-NEXT:    ret
@@ -162,9 +162,9 @@ define i64 @bzhi64_a3_load_indexzext(ptr %w, i8 zeroext %numlowbits) nounwind {
 ; CHECK-LABEL: bzhi64_a3_load_indexzext:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    mov w8, #1 // =0x1
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
+; CHECK-NEXT:    mov w9, w1
+; CHECK-NEXT:    lsl x8, x8, x9
 ; CHECK-NEXT:    ldr x9, [x0]
-; CHECK-NEXT:    lsl x8, x8, x1
 ; CHECK-NEXT:    sub x8, x8, #1
 ; CHECK-NEXT:    and x0, x8, x9
 ; CHECK-NEXT:    ret
@@ -284,8 +284,8 @@ define i64 @bzhi64_b1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind {
 ; CHECK-LABEL: bzhi64_b1_indexzext:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    mov x8, #-1 // =0xffffffffffffffff
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    lsl x8, x8, x1
+; CHECK-NEXT:    mov w9, w1
+; CHECK-NEXT:    lsl x8, x8, x9
 ; CHECK-NEXT:    bic x0, x0, x8
 ; CHECK-NEXT:    ret
   %conv = zext i8 %numlowbits to i64
@@ -314,10 +314,10 @@ define i64 @bzhi64_b3_load_indexzext(ptr %w, i8 zeroext %numlowbits) nounwind {
 ; CHECK-LABEL: bzhi64_b3_load_indexzext:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    mov x8, #-1 // =0xffffffffffffffff
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    ldr x9, [x0]
-; CHECK-NEXT:    lsl x8, x8, x1
-; CHECK-NEXT:    bic x0, x9, x8
+; CHECK-NEXT:    mov w9, w1
+; CHECK-NEXT:    ldr x10, [x0]
+; CHECK-NEXT:    lsl x8, x8, x9
+; CHECK-NEXT:    bic x0, x10, x8
 ; CHECK-NEXT:    ret
   %val = load i64, ptr %w
   %conv = zext i8 %numlowbits to i64
diff --git a/llvm/test/CodeGen/AArch64/fcvt-i256.ll b/llvm/test/CodeGen/AArch64/fcvt-i256.ll
index d7d9d04187506..60587a25db95b 100644
--- a/llvm/test/CodeGen/AArch64/fcvt-i256.ll
+++ b/llvm/test/CodeGen/AArch64/fcvt-i256.ll
@@ -552,45 +552,210 @@ define double @u256_to_f64(i256 %val) {
 }
 
 define i256 @f32_to_s256(float %val) {
-; CHECK-SD-LABEL: f32_to_s256:
+; CHECK-LABEL: f32_to_s256:
+; CHECK:       // %bb.0: // %fp-to-i-entry
+; CHECK-NEXT:    fmov w8, s0
+; CHECK-NEXT:    ubfx w10, w8, #23, #8
+; CHECK-NEXT:    cmp w10, #127
+; CHECK-NEXT:    b.hs .LBB4_2
+; CHECK-NEXT:  // %bb.1:
+; CHECK-NEXT:    mov x0, xzr
+; CHECK-NEXT:    mov x1, xzr
+; CHECK-NEXT:    mov x2, xzr
+; CHECK-NEXT:    mov x3, xzr
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB4_2: // %fp-to-i-if-check.exp.size
+; CHECK-NEXT:    sbfx x9, x8, #31, #1
+; CHECK-NEXT:    mov w11, #8388608 // =0x800000
+; CHECK-NEXT:    cmp w10, #149
+; CHECK-NEXT:    bfxil w11, w8, #0, #23
+; CHECK-NEXT:    orr x8, x9, #0x1
+; CHECK-NEXT:    b.hi .LBB4_4
+; CHECK-NEXT:  // %bb.3: // %fp-to-i-if-exp.small
+; CHECK-NEXT:    mov w12, #150 // =0x96
+; CHECK-NEXT:    sub w10, w12, w10
+; CHECK-NEXT:    lsr w10, w11, w10
+; CHECK-NEXT:    umulh x13, x10, x8
+; CHECK-NEXT:    umulh x12, x10, x9
+; CHECK-NEXT:    umulh x11, x9, x10
+; CHECK-NEXT:    smull x14, w10, w9
+; CHECK-NEXT:    smull x15, w9, w10
+; CHECK-NEXT:    smull x9, w9, w10
+; CHECK-NEXT:    adds x1, x14, x13
+; CHECK-NEXT:    smull x0, w10, w8
+; CHECK-NEXT:    adcs x2, x15, x12
+; CHECK-NEXT:    adc x3, x11, x9
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB4_4: // %fp-to-i-if-exp.large
+; CHECK-NEXT:    sub sp, sp, #64
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-NEXT:    movi v0.2d, #0000000000000000
+; CHECK-NEXT:    sub w10, w10, #150
+; CHECK-NEXT:    str x11, [sp, #32]
+; CHECK-NEXT:    lsr x11, x10, #3
+; CHECK-NEXT:    mov x12, sp
+; CHECK-NEXT:    str xzr, [sp, #56]
+; CHECK-NEXT:    add x12, x12, #32
+; CHECK-NEXT:    and x16, x10, #0x3f
+; CHECK-NEXT:    mvn w2, w10
+; CHECK-NEXT:    and x11, x11, #0x18
+; CHECK-NEXT:    eor x16, x16, #0x3f
+; CHECK-NEXT:    stur q0, [sp, #40]
+; CHECK-NEXT:    sub x11, x12, x11
+; CHECK-NEXT:    stp q0, q0, [sp]
+; CHECK-NEXT:    ldp x12, x15, [x11]
+; CHECK-NEXT:    ldp x1, x11, [x11, #16]
+; CHECK-NEXT:    lsl x18, x15, x10
+; CHECK-NEXT:    lsr x15, x15, #1
+; CHECK-NEXT:    lsl x13, x12, x10
+; CHECK-NEXT:    lsr x12, x12, #1
+; CHECK-NEXT:    lsl x4, x1, x10
+; CHECK-NEXT:    lsr x1, x1, #1
+; CHECK-NEXT:    lsr x15, x15, x2
+; CHECK-NEXT:    lsl x10, x11, x10
+; CHECK-NEXT:    umulh x14, x13, x8
+; CHECK-NEXT:    lsr x12, x12, x16
+; CHECK-NEXT:    lsr x11, x1, x16
+; CHECK-NEXT:    orr x15, x4, x15
+; CHECK-NEXT:    mul x0, x13, x9
+; CHECK-NEXT:    orr x12, x18, x12
+; CHECK-NEXT:    orr x10, x10, x11
+; CHECK-NEXT:    umulh x4, x8, x15
+; CHECK-NEXT:    mul x3, x12, x8
+; CHECK-NEXT:    umulh x11, x9, x13
+; CHECK-NEXT:    umulh x18, x12, x8
+; CHECK-NEXT:    adds x14, x3, x14
+; CHECK-NEXT:    umulh x17, x13, x9
+; CHECK-NEXT:    madd x10, x8, x10, x4
+; CHECK-NEXT:    cinc x18, x18, hs
+; CHECK-NEXT:    adds x1, x0, x14
+; CHECK-NEXT:    madd x11, x9, x12, x11
+; CHECK-NEXT:    mul x16, x12, x9
+; CHECK-NEXT:    umulh x2, x12, x9
+; CHECK-NEXT:    madd x10, x9, x15, x10
+; CHECK-NEXT:    mul x12, x8, x15
+; CHECK-NEXT:    mul x15, x9, x13
+; CHECK-NEXT:    madd x9, x9, x13, x11
+; CHECK-NEXT:    cinc x11, x17, hs
+; CHECK-NEXT:    adds x11, x18, x11
+; CHECK-NEXT:    mul x0, x13, x8
+; CHECK-NEXT:    cset w8, hs
+; CHECK-NEXT:    adds x11, x16, x11
+; CHECK-NEXT:    adc x8, x2, x8
+; CHECK-NEXT:    adds x12, x15, x12
+; CHECK-NEXT:    adc x9, x9, x10
+; CHECK-NEXT:    adds x2, x11, x12
+; CHECK-NEXT:    adc x3, x8, x9
+; CHECK-NEXT:    add sp, sp, #64
+; CHECK-NEXT:    ret
+  %result = fptosi float %val to i256
+  ret i256 %result
+}
+
+define i256 @f32_to_u256(float %val) {
+; CHECK-LABEL: f32_to_u256:
+; CHECK:       // %bb.0: // %fp-to-i-entry
+; CHECK-NEXT:    fmov w10, s0
+; CHECK-NEXT:    ubfx w9, w10, #23, #8
+; CHECK-NEXT:    cmp w9, #127
+; CHECK-NEXT:    b.hs .LBB5_2
+; CHECK-NEXT:  // %bb.1:
+; CHECK-NEXT:    mov x0, xzr
+; CHECK-NEXT:    mov x1, xzr
+; CHECK-NEXT:    mov x2, xzr
+; CHECK-NEXT:    mov x3, xzr
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB5_2: // %fp-to-i-if-check.exp.size
+; CHECK-NEXT:    mov w8, #8388608 // =0x800000
+; CHECK-NEXT:    cmp w9, #149
+; CHECK-NEXT:    bfxil w8, w10, #0, #23
+; CHECK-NEXT:    b.hi .LBB5_4
+; CHECK-NEXT:  // %bb.3: // %fp-to-i-if-exp.small
+; CHECK-NEXT:    mov w10, #150 // =0x96
+; CHECK-NEXT:    mov x1, xzr
+; CHECK-NEXT:    mov x2, xzr
+; CHECK-NEXT:    sub w9, w10, w9
+; CHECK-NEXT:    mov x3, xzr
+; CHECK-NEXT:    lsr w0, w8, w9
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB5_4: // %fp-to-i-if-exp.large
+; CHECK-NEXT:    sub sp, sp, #64
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-NEXT:    movi v0.2d, #0000000000000000
+; CHECK-NEXT:    sub w9, w9, #150
+; CHECK-NEXT:    str x8, [sp, #32]
+; CHECK-NEXT:    lsr x8, x9, #3
+; CHECK-NEXT:    mov x10, sp
+; CHECK-NEXT:    str xzr, [sp, #56]
+; CHECK-NEXT:    add x10, x10, #32
+; CHECK-NEXT:    and x13, x9, #0x3f
+; CHECK-NEXT:    mvn w17, w9
+; CHECK-NEXT:    and x8, x8, #0x18
+; CHECK-NEXT:    eor x13, x13, #0x3f
+; CHECK-NEXT:    stur q0, [sp, #40]
+; CHECK-NEXT:    sub x8, x10, x8
+; CHECK-NEXT:    stp q0, q0, [sp]
+; CHECK-NEXT:    ldp x11, x10, [x8, #8]
+; CHECK-NEXT:    ldr x12, [x8]
+; CHECK-NEXT:    ldr x8, [x8, #24]
+; CHECK-NEXT:    lsr x16, x12, #1
+; CHECK-NEXT:    lsl x0, x12, x9
+; CHECK-NEXT:    lsr x14, x10, #1
+; CHECK-NEXT:    lsr x15, x11, #1
+; CHECK-NEXT:    lsl x8, x8, x9
+; CHECK-NEXT:    lsl x10, x10, x9
+; CHECK-NEXT:    lsl x11, x11, x9
+; CHECK-NEXT:    lsr x15, x15, x17
+; CHECK-NEXT:    lsr x14, x14, x13
+; CHECK-NEXT:    lsr x13, x16, x13
+; CHECK-NEXT:    orr x3, x8, x14
+; CHECK-NEXT:    orr x2, x10, x15
+; CHECK-NEXT:    orr x1, x11, x13
+; CHECK-NEXT:    add sp, sp, #64
+; CHECK-NEXT:    ret
+  %result = fptoui float %val to i256
+  ret i256 %result
+}
+
+define i256 @f64_to_s256(double %val) {
+; CHECK-SD-LABEL: f64_to_s256:
 ; CHECK-SD:       // %bb.0: // %fp-to-i-entry
-; CHECK-SD-NEXT:    fmov w8, s0
-; CHECK-SD-NEXT:    ubfx w10, w8, #23, #8
-; CHECK-SD-NEXT:    cmp w10, #127
-; CHECK-SD-NEXT:    b.hs .LBB4_2
+; CHECK-SD-NEXT:    fmov x8, d0
+; CHECK-SD-NEXT:    ubfx x10, x8, #52, #11
+; CHECK-SD-NEXT:    cmp x10, #1023
+; CHECK-SD-NEXT:    b.hs .LBB6_2
 ; CHECK-SD-NEXT:  // %bb.1:
 ; CHECK-SD-NEXT:    mov x0, xzr
 ; CHECK-SD-NEXT:    mov x1, xzr
 ; CHECK-SD-NEXT:    mov x2, xzr
 ; CHECK-SD-NEXT:    mov x3, xzr
 ; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB4_2: // %fp-to-i-if-check.exp.size
-; CHECK-SD-NEXT:    sbfx x9, x8, #31, #1
-; CHECK-SD-NEXT:    mov w11, #8388608 // =0x800000
-; CHECK-SD-NEXT:    cmp w10, #149
-; CHECK-SD-NEXT:    bfxil w11, w8, #0, #23
+; CHECK-SD-NEXT:  .LBB6_2: // %fp-to-i-if-check.exp.size
+; CHECK-SD-NEXT:    asr x9, x8, #63
+; CHECK-SD-NEXT:    mov x11, #4503599627370496 // =0x10000000000000
+; CHECK-SD-NEXT:    cmp x10, #1074
+; CHECK-SD-NEXT:    bfxil x11, x8, #0, #52
 ; CHECK-SD-NEXT:    orr x8, x9, #0x1
-; CHECK-SD-NEXT:    b.hi .LBB4_4
+; CHECK-SD-NEXT:    b.hi .LBB6_4
 ; CHECK-SD-NEXT:  // %bb.3: // %fp-to-i-if-exp.small
-; CHECK-SD-NEXT:    mov w12, #150 // =0x96
-; CHECK-SD-NEXT:    sub w10, w12, w10
-; CHECK-SD-NEXT:    lsr w10, w11, w10
+; CHECK-SD-NEXT:    mov w12, #1075 // =0x433
+; CHECK-SD-NEXT:    sub x10, x12, x10
+; CHECK-SD-NEXT:    lsr x10, x11, x10
 ; CHECK-SD-NEXT:    umulh x13, x10, x8
-; CHECK-SD-NEXT:    umulh x12, x10, x9
-; CHECK-SD-NEXT:    umulh x11, x9, x10
-; CHECK-SD-NEXT:    smull x14, w10, w9
-; CHECK-SD-NEXT:    smull x15, w9, w10
-; CHECK-SD-NEXT:    smull x9, w9, w10
+; CHECK-SD-NEXT:    mul x14, x10, x9
+; CHECK-SD-NEXT:    mul x11, x9, x10
+; CHECK-SD-NEXT:    umulh x12, x9, x10
 ; CHECK-SD-NEXT:    adds x1, x14, x13
-; CHECK-SD-NEXT:    smull x0, w10, w8
-; CHECK-SD-NEXT:    adcs x2, x15, x12
-; CHECK-SD-NEXT:    adc x3, x11, x9
+; CHECK-SD-NEXT:    umulh x9, x10, x9
+; CHECK-SD-NEXT:    mul x0, x10, x8
+; CHECK-SD-NEXT:    adcs x2, x11, x9
+; CHECK-SD-NEXT:    adc x3, x12, x11
 ; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB4_4: // %fp-to-i-if-exp.large
+; CHECK-SD-NEXT:  .LBB6_4: // %fp-to-i-if-exp.large
 ; CHECK-SD-NEXT:    sub sp, sp, #64
 ; CHECK-SD-NEXT:    .cfi_def_cfa_offset 64
 ; CHECK-SD-NEXT:    movi v0.2d, #0000000000000000
-; CHECK-SD-NEXT:    sub w10, w10, #150
+; CHECK-SD-NEXT:    sub x10, x10, #1075
 ; CHECK-SD-NEXT:    str x11, [sp, #32]
 ; CHECK-SD-NEXT:    lsr x11, x10, #3
 ; CHECK-SD-NEXT:    mov x12, sp
@@ -649,55 +814,54 @@ define i256 @f32_to_s256(float %val) {
 ; CHECK-SD-NEXT:    add sp, sp, #64
 ; CHECK-SD-NEXT:    ret
 ;
-; CHECK-GI-LABEL: f32_to_s256:
+; CHECK-GI-LABEL: f64_to_s256:
 ; CHECK-GI:       // %bb.0: // %fp-to-i-entry
-; CHECK-GI-NEXT:    fmov w8, s0
+; CHECK-GI-NEXT:    fmov x8, d0
 ; CHECK-GI-NEXT:    mov x0, xzr
 ; CHECK-GI-NEXT:    mov x1, xzr
 ; CHECK-GI-NEXT:    mov x2, xzr
 ; CHECK-GI-NEXT:    mov x3, xzr
-; CHECK-GI-NEXT:    ubfx w11, w8, #23, #8
-; CHECK-GI-NEXT:    cmn w8, #1
+; CHECK-GI-NEXT:    ubfx x11, x8, #52, #11
+; CHECK-GI-NEXT:    cmn x8, #1
 ; CHECK-GI-NEXT:    cset w9, le
-; CHECK-GI-NEXT:    cmp w11, #127
-; CHECK-GI-NEXT:    b.lo .LBB4_4
+; CHECK-GI-NEXT:    cmp x11, #1023
+; CHECK-GI-NEXT:    b.lo .LBB6_4
 ; CHECK-GI-NEXT:  // %bb.1: // %fp-to-i-if-check.exp.size
 ; CHECK-GI-NEXT:    sbfx x10, x9, #0, #1
-; CHECK-GI-NEXT:    and w12, w8, #0x7fffff
-; CHECK-GI-NEXT:    cmp w11, #150
+; CHECK-GI-NEXT:    and x12, x8, #0xfffffffffffff
+; CHECK-GI-NEXT:    cmp x11, #1075
 ; CHECK-GI-NEXT:    asr x9, x10, #63
 ; CHECK-GI-NEXT:    orr x8, x10, #0x1
-; CHECK-GI-NEXT:    orr w10, w12, #0x800000
-; CHECK-GI-NEXT:    b.hs .LBB4_3
+; CHECK-GI-NEXT:    orr x10, x12, #0x10000000000000
+; CHECK-GI-NEXT:    b.hs .LBB6_3
 ; CHECK-GI-NEXT:  // %bb.2: // %fp-to-i-if-exp.small
-; CHECK-GI-NEXT:    mov w12, #150 // =0x96
-; CHECK-GI-NEXT:    umulh x15, x9, xzr
-; CHECK-GI-NEXT:    sub w11, w12, w11
-; CHECK-GI-NEXT:    lsr w10, w10, w11
-; CHECK-GI-NEXT:    umulh x12, x8, xzr
+; CHECK-GI-NEXT:    mov w12, #1075 // =0x433
+; CHECK-GI-NEXT:    umulh x13, x8, xzr
+; CHECK-GI-NEXT:    sub x11, x12, x11
+; CHECK-GI-NEXT:    lsr x10, x10, x11
+; CHECK-GI-NEXT:    umulh x14, x9, xzr
 ; CHECK-GI-NEXT:    umulh x11, x10, x8
-; CHECK-GI-NEXT:    umulh x13, x10, x9
-; CHECK-GI-NEXT:    smull x14, w10, w9
-; CHECK-GI-NEXT:    smull x16, w10, w9
-; CHECK-GI-NEXT:    smull x0, w10, w8
-; CHECK-GI-NEXT:    adds x1, x11, x14
-; CHECK-GI-NEXT:    add x14, x12, x15
-; CHECK-GI-NEXT:    add x12, x12, x13
-; CHECK-GI-NEXT:    cset w11, hs
-; CHECK-GI-NEXT:    adds x12, x12, x16
-; CHECK-GI-NEXT:    add x13, x14, x13
-; CHECK-GI-NEXT:    and x11, x11, #0x1
-; CHECK-GI-NEXT:    smaddl x9, w10, w9, x13
+; CHECK-GI-NEXT:    mul x12, x10, x9
+; CHECK-GI-NEXT:    umulh x15, x10, x9
+; CHECK-GI-NEXT:    mul x0, x10, x8
+; CHECK-GI-NEXT:    adds x1, x11, x12
+; CHECK-GI-NEXT:    add x11, x13, x14
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    add x13, x13, x15
+; CHECK-GI-NEXT:    add x11, x11, x15
+; CHECK-GI-NEXT:    madd x9, x10, x9, x11
+; CHECK-GI-NEXT:    and x11, x14, #0x1
+; CHECK-GI-NEXT:    adds x12, x13, x12
 ; CHECK-GI-NEXT:    cset w13, hs
 ; CHECK-GI-NEXT:    adds x2, x12, x11
-; CHECK-GI-NEXT:    and x8, x13, #0x1
-; CHECK-GI-NEXT:    cset w10, hs
-; CHECK-GI-NEXT:    and x10, x10, #0x1
-; CHECK-GI-NEXT:    add x8, x9, x8
-; CHECK-GI-NEXT:    add x3, x8, x10
+; CHECK-GI-NEXT:    cset w8, hs
+; CHECK-GI-NEXT:    and x10, x13, #0x1
+; CHECK-GI-NEXT:    and x8, x8, #0x1
+; CHECK-GI-NEXT:    add x8, x10, x8
+; CHECK-GI-NEXT:    add x3, x9, x8
 ; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB4_3: // %fp-to-i-if-exp.large
-; CHECK-GI-NEXT:    sub w11, w11, #150
+; CHECK-GI-NEXT:  .LBB6_3: // %fp-to-i-if-exp.large
+; CHECK-GI-NEXT:    sub x11, x11, #1075
 ; CHECK-GI-NEXT:    mov w13, #64 // =0x40
 ; CHECK-GI-NEXT:    mov w12, #128 // =0x80
 ; CHECK-GI-NEXT:    sub x14, x11, #64
@@ -778,99 +942,99 @@ define i256 @f32_to_s256(float %val) {
 ; CHECK-GI-NEXT:    and x10, x11, #0x1
 ; CHECK-GI-NEXT:    add x9, x9, x10
 ; CHECK-GI-NEXT:    add x3, x8, x9
-; CHECK-GI-NEXT:  .LBB4_4: // %fp-to-i-cleanup
+; CHECK-GI-NEXT:  .LBB6_4: // %fp-to-i-cleanup
 ; CHECK-GI-NEXT:    ret
-  %result = fptosi float %val to i256
+  %result = fptosi double %val to i256
   ret i256 %result
 }
 
-define i256 @f32_to_u256(float %val) {
-; CHECK-SD-LABEL: f32_to_u256:
+define i256 @f64_to_u256(double %val) {
+; CHECK-SD-LABEL: f64_to_u256:
 ; CHECK-SD:       // %bb.0: // %fp-to-i-entry
-; CHECK-SD-NEXT:    fmov w10, s0
-; CHECK-SD-NEXT:    ubfx w9, w10, #23, #8
-; CHECK-SD-NEXT:    cmp w9, #127
-; CHECK-SD-NEXT:    b.hs .LBB5_2
+; CHECK-SD-NEXT:    fmov x10, d0
+; CHECK-SD-NEXT:    ubfx x8, x10, #52, #11
+; CHECK-SD-NEXT:    cmp x8, #1023
+; CHECK-SD-NEXT:    b.hs .LBB7_2
 ; CHECK-SD-NEXT:  // %bb.1:
 ; CHECK-SD-NEXT:    mov x0, xzr
 ; CHECK-SD-NEXT:    mov x1, xzr
 ; CHECK-SD-NEXT:    mov x2, xzr
 ; CHECK-SD-NEXT:    mov x3, xzr
 ; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB5_2: // %fp-to-i-if-check.exp.size
-; CHECK-SD-NEXT:    mov w8, #8388608 // =0x800000
-; CHECK-SD-NEXT:    cmp w9, #149
-; CHECK-SD-NEXT:    bfxil w8, w10, #0, #23
-; CHECK-SD-NEXT:    b.hi .LBB5_4
+; CHECK-SD-NEXT:  .LBB7_2: // %fp-to-i-if-check.exp.size
+; CHECK-SD-NEXT:    mov x9, #4503599627370496 // =0x10000000000000
+; CHECK-SD-NEXT:    cmp x8, #1074
+; CHECK-SD-NEXT:    bfxil x9, x10, #0, #52
+; CHECK-SD-NEXT:    b.hi .LBB7_4
 ; CHECK-SD-NEXT:  // %bb.3: // %fp-to-i-if-exp.small
-; CHECK-SD-NEXT:    mov w10, #150 // =0x96
+; CHECK-SD-NEXT:    mov w10, #1075 // =0x433
 ; CHECK-SD-NEXT:    mov x1, xzr
 ; CHECK-SD-NEXT:    mov x2, xzr
-; CHECK-SD-NEXT:    sub w9, w10, w9
+; CHECK-SD-NEXT:    sub x8, x10, x8
 ; CHECK-SD-NEXT:    mov x3, xzr
-; CHECK-SD-NEXT:    lsr w0, w8, w9
+; CHECK-SD-NEXT:    lsr x0, x9, x8
 ; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB5_4: // %fp-to-i-if-exp.large
+; CHECK-SD-NEXT:  .LBB7_4: // %fp-to-i-if-exp.large
 ; CHECK-SD-NEXT:    sub sp, sp, #64
 ; CHECK-SD-NEXT:    .cfi_def_cfa_offset 64
 ; CHECK-SD-NEXT:    movi v0.2d, #0000000000000000
-; CHECK-SD-NEXT:    sub w9, w9, #150
-; CHECK-SD-NEXT:    str x8, [sp, #32]
-; CHECK-SD-NEXT:    lsr x8, x9, #3
+; CHECK-SD-NEXT:    sub x8, x8, #1075
+; CHECK-SD-NEXT:    str x9, [sp, #32]
+; CHECK-SD-NEXT:    lsr x9, x8, #3
 ; CHECK-SD-NEXT:    mov x10, sp
 ; CHECK-SD-NEXT:    str xzr, [sp, #56]
 ; CHECK-SD-NEXT:    add x10, x10, #32
-; CHECK-SD-NEXT:    and x13, x9, #0x3f
-; CHECK-SD-NEXT:    mvn w17, w9
-; CHECK-SD-NEXT:    and x8, x8, #0x18
+; CHECK-SD-NEXT:    and x13, x8, #0x3f
+; CHECK-SD-NEXT:    mvn w17, w8
+; CHECK-SD-NEXT:    and x9, x9, #0x18
 ; CHECK-SD-NEXT:    eor x13, x13, #0x3f
 ; CHECK-SD-NEXT:    stur q0, [sp, #40]
-; CHECK-SD-NEXT:    sub x8, x10, x8
+; CHECK-SD-NEXT:    sub x9, x10, x9
 ; CHECK-SD-NEXT:    stp q0, q0, [sp]
-; CHECK-SD-NEXT:    ldp x11, x10, [x8, #8]
-; CHECK-SD-NEXT:    ldr x12, [x8]
-; CHECK-SD-NEXT:    ldr x8, [x8, #24]
+; CHECK-SD-NEXT:    ldp x11, x10, [x9, #8]
+; CHECK-SD-NEXT:    ldr x12, [x9]
+; CHECK-SD-NEXT:    ldr x9, [x9, #24]
 ; CHECK-SD-NEXT:    lsr x16, x12, #1
-; CHECK-SD-NEXT:    lsl x0, x12, x9
+; CHECK-SD-NEXT:    lsl x0, x12, x8
 ; CHECK-SD-NEXT:    lsr x14, x10, #1
 ; CHECK-SD-NEXT:    lsr x15, x11, #1
-; CHECK-SD-NEXT:    lsl x8, x8, x9
-; CHECK-SD-NEXT:    lsl x10, x10, x9
-; CHECK-SD-NEXT:    lsl x11, x11, x9
+; CHECK-SD-NEXT:    lsl x9, x9, x8
+; CHECK-SD-NEXT:    lsl x10, x10, x8
+; CHECK-SD-NEXT:    lsl x11, x11, x8
 ; CHECK-SD-NEXT:    lsr x15, x15, x17
 ; CHECK-SD-NEXT:    lsr x14, x14, x13
 ; CHECK-SD-NEXT:    lsr x13, x16, x13
-; CHECK-SD-NEXT:    orr x3, x8, x14
+; CHECK-SD-NEXT:    orr x3, x9, x14
 ; CHECK-SD-NEXT:    orr x2, x10, x15
 ; CHECK-SD-NEXT:    orr x1, x11, x13
 ; CHECK-SD-NEXT:    add sp, sp, #64
 ; CHECK-SD-NEXT:    ret
 ;
-; CHECK-GI-LABEL: f32_to_u256:
+; CHECK-GI-LABEL: f64_to_u256:
 ; CHECK-GI:       // %bb.0: // %fp-to-i-entry
-; CHECK-GI-NEXT:    fmov w8, s0
+; CHECK-GI-NEXT:    fmov x8, d0
 ; CHECK-GI-NEXT:    mov x0, xzr
 ; CHECK-GI-NEXT:    mov x1, xzr
 ; CHECK-GI-NEXT:    mov x2, xzr
 ; CHECK-GI-NEXT:    mov x3, xzr
-; CHECK-GI-NEXT:    ubfx w9, w8, #23, #8
-; CHECK-GI-NEXT:    cmp w9, #127
-; CHECK-GI-NEXT:    b.lo .LBB5_4
+; CHECK-GI-NEXT:    ubfx x9, x8, #52, #11
+; CHECK-GI-NEXT:    cmp x9, #1023
+; CHECK-GI-NEXT:    b.lo .LBB7_4
 ; CHECK-GI-NEXT:  // %bb.1: // %fp-to-i-if-check.exp.size
-; CHECK-GI-NEXT:    and w8, w8, #0x7fffff
-; CHECK-GI-NEXT:    cmp w9, #150
-; CHECK-GI-NEXT:    orr w8, w8, #0x800000
-; CHECK-GI-NEXT:    b.hs .LBB5_3
+; CHECK-GI-NEXT:    and x8, x8, #0xfffffffffffff
+; CHECK-GI-NEXT:    cmp x9, #1075
+; CHECK-GI-NEXT:    orr x8, x8, #0x10000000000000
+; CHECK-GI-NEXT:    b.hs .LBB7_3
 ; CHECK-GI-NEXT:  // %bb.2: // %fp-to-i-if-exp.small
-; CHECK-GI-NEXT:    mov w10, #150 // =0x96
+; CHECK-GI-NEXT:    mov w10, #1075 // =0x433
 ; CHECK-GI-NEXT:    mov x1, xzr
 ; CHECK-GI-NEXT:    mov x2, xzr
-; CHECK-GI-NEXT:    sub w9, w10, w9
+; CHECK-GI-NEXT:    sub x9, x10, x9
 ; CHECK-GI-NEXT:    mov x3, xzr
-; CHECK-GI-NEXT:    lsr w0, w8, w9
+; CHECK-GI-NEXT:    lsr x0, x8, x9
 ; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB5_3: // %fp-to-i-if-exp.large
-; CHECK-GI-NEXT:    sub w9, w9, #150
+; CHECK-GI-NEXT:  .LBB7_3: // %fp-to-i-if-exp.large
+; CHECK-GI-NEXT:    sub x9, x9, #1075
 ; CHECK-GI-NEXT:    mov w11, #64 // =0x40
 ; CHECK-GI-NEXT:    mov w10, #128 // =0x80
 ; CHECK-GI-NEXT:    sub x12, x9, #64
@@ -908,800 +1072,204 @@ define i256 @f32_to_u256(float %val) {
 ; CHECK-GI-NEXT:    cmp x9, #0
 ; CHECK-GI-NEXT:    csel x2, xzr, x8, eq
 ; CHECK-GI-NEXT:    csel x3, xzr, x10, eq
-; CHECK-GI-NEXT:  .LBB5_4: // %fp-to-i-cleanup
+; CHECK-GI-NEXT:  .LBB7_4: // %fp-to-i-cleanup
 ; CHECK-GI-NEXT:    ret
-  %result = fptoui float %val to i256
+  %result = fptoui double %val to i256
   ret i256 %result
 }
 
-define i256 @f64_to_s256(double %val) {
-; CHECK-SD-LABEL: f64_to_s256:
-; CHECK-SD:       // %bb.0: // %fp-to-i-entry
-; CHECK-SD-NEXT:    fmov x8, d0
-; CHECK-SD-NEXT:    ubfx x10, x8, #52, #11
-; CHECK-SD-NEXT:    cmp x10, #1023
-; CHECK-SD-NEXT:    b.hs .LBB6_2
-; CHECK-SD-NEXT:  // %bb.1:
-; CHECK-SD-NEXT:    mov x0, xzr
-; CHECK-SD-NEXT:    mov x1, xzr
-; CHECK-SD-NEXT:    mov x2, xzr
-; CHECK-SD-NEXT:    mov x3, xzr
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB6_2: // %fp-to-i-if-check.exp.size
-; CHECK-SD-NEXT:    asr x9, x8, #63
-; CHECK-SD-NEXT:    mov x11, #4503599627370496 // =0x10000000000000
-; CHECK-SD-NEXT:    cmp x10, #1074
-; CHECK-SD-NEXT:    bfxil x11, x8, #0, #52
-; CHECK-SD-NEXT:    orr x8, x9, #0x1
-; CHECK-SD-NEXT:    b.hi .LBB6_4
-; CHECK-SD-NEXT:  // %bb.3: // %fp-to-i-if-exp.small
-; CHECK-SD-NEXT:    mov w12, #1075 // =0x433
-; CHECK-SD-NEXT:    sub x10, x12, x10
-; CHECK-SD-NEXT:    lsr x10, x11, x10
-; CHECK-SD-NEXT:    umulh x13, x10, x8
-; CHECK-SD-NEXT:    mul x14, x10, x9
-; CHECK-SD-NEXT:    mul x11, x9, x10
-; CHECK-SD-NEXT:    umulh x12, x9, x10
-; CHECK-SD-NEXT:    adds x1, x14, x13
-; CHECK-SD-NEXT:    umulh x9, x10, x9
-; CHECK-SD-NEXT:    mul x0, x10, x8
-; CHECK-SD-NEXT:    adcs x2, x11, x9
-; CHECK-SD-NEXT:    adc x3, x12, x11
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB6_4: // %fp-to-i-if-exp.large
-; CHECK-SD-NEXT:    sub sp, sp, #64
-; CHECK-SD-NEXT:    .cfi_def_cfa_offset 64
-; CHECK-SD-NEXT:    movi v0.2d, #0000000000000000
-; CHECK-SD-NEXT:    sub x10, x10, #1075
-; CHECK-SD-NEXT:    str x11, [sp, #32]
-; CHECK-SD-NEXT:    lsr x11, x10, #3
-; CHECK-SD-NEXT:    mov x12, sp
-; CHECK-SD-NEXT:    str xzr, [sp, #56]
-; CHECK-SD-NEXT:    add x12, x12, #32
-; CHECK-SD-NEXT:    and x16, x10, #0x3f
-; CHECK-SD-NEXT:    mvn w2, w10
-; CHECK-SD-NEXT:    and x11, x11, #0x18
-; CHECK-SD-NEXT:    eor x16, x16, #0x3f
-; CHECK-SD-NEXT:    stur q0, [sp, #40]
-; CHECK-SD-NEXT:    sub x11, x12, x11
-; CHECK-SD-NEXT:    stp q0, q0, [sp]
-; CHECK-SD-NEXT:    ldp x12, x15, [x11]
-; CHECK-SD-NEXT:    ldp x1, x11, [x11, #16]
-; CHECK-SD-NEXT:    lsl x18, x15, x10
-; CHECK-SD-NEXT:    lsr x15, x15, #1
-; CHECK-SD-NEXT:    lsl x13, x12, x10
-; CHECK-SD-NEXT:    lsr x12, x12, #1
-; CHECK-SD-NEXT:    lsl x4, x1, x10
-; CHECK-SD-NEXT:    lsr x1, x1, #1
-; CHECK-SD-NEXT:    lsr x15, x15, x2
-; CHECK-SD-NEXT:    lsl x10, x11, x10
-; CHECK-SD-NEXT:    umulh x14, x13, x8
-; CHECK-SD-NEXT:    lsr x12, x12, x16
-; CHECK-SD-NEXT:    lsr x11, x1, x16
-; CHECK-SD-NEXT:    orr x15, x4, x15
-; CHECK-SD-NEXT:    mul x0, x13, x9
-; CHECK-SD-NEXT:    orr x12, x18, x12
-; CHECK-SD-NEXT:    orr x10, x10, x11
-; CHECK-SD-NEXT:    umulh x4, x8, x15
-; CHECK-SD-NEXT:    mul x3, x12, x8
-; CHECK-SD-NEXT:    umulh x11, x9, x13
-; CHECK-SD-NEXT:    umulh x18, x12, x8
-; CHECK-SD-NEXT:    adds x14, x3, x14
-; CHECK-SD-NEXT:    umulh x17, x13, x9
-; CHECK-SD-NEXT:    madd x10, x8, x10, x4
-; CHECK-SD-NEXT:    cinc x18, x18, hs
-; CHECK-SD-NEXT:    adds x1, x0, x14
-; CHECK-SD-NEXT:    madd x11, x9, x12, x11
-; CHECK-SD-NEXT:    mul x16, x12, x9
-; CHECK-SD-NEXT:    umulh x2, x12, x9
-; CHECK-SD-NEXT:    madd x10, x9, x15, x10
-; CHECK-SD-NEXT:    mul x12, x8, x15
-; CHECK-SD-NEXT:    mul x15, x9, x13
-; CHECK-SD-NEXT:    madd x9, x9, x13, x11
-; CHECK-SD-NEXT:    cinc x11, x17, hs
-; CHECK-SD-NEXT:    adds x11, x18, x11
-; CHECK-SD-NEXT:    mul x0, x13, x8
-; CHECK-SD-NEXT:    cset w8, hs
-; CHECK-SD-NEXT:    adds x11, x16, x11
-; CHECK-SD-NEXT:    adc x8, x2, x8
-; CHECK-SD-NEXT:    adds x12, x15, x12
-; CHECK-SD-NEXT:    adc x9, x9, x10
-; CHECK-SD-NEXT:    adds x2, x11, x12
-; CHECK-SD-NEXT:    adc x3, x8, x9
-; CHECK-SD-NEXT:    add sp, sp, #64
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: f64_to_s256:
-; CHECK-GI:       // %bb.0: // %fp-to-i-entry
-; CHECK-GI-NEXT:    fmov x8, d0
-; CHECK-GI-NEXT:    mov x0, xzr
-; CHECK-GI-NEXT:    mov x1, xzr
-; CHECK-GI-NEXT:    mov x2, xzr
-; CHECK-GI-NEXT:    mov x3, xzr
-; CHECK-GI-NEXT:    ubfx x11, x8, #52, #11
-; CHECK-GI-NEXT:    cmn x8, #1
-; CHECK-GI-NEXT:    cset w9, le
-; CHECK-GI-NEXT:    cmp x11, #1023
-; CHECK-GI-NEXT:    b.lo .LBB6_4
-; CHECK-GI-NEXT:  // %bb.1: // %fp-to-i-if-check.exp.size
-; CHECK-GI-NEXT:    sbfx x10, x9, #0, #1
-; CHECK-GI-NEXT:    and x12, x8, #0xfffffffffffff
-; CHECK-GI-NEXT:    cmp x11, #1075
-; CHECK-GI-NEXT:    asr x9, x10, #63
-; CHECK-GI-NEXT:    orr x8, x10, #0x1
-; CHECK-GI-NEXT:    orr x10, x12, #0x10000000000000
-; CHECK-GI-NEXT:    b.hs .LBB6_3
-; CHECK-GI-NEXT:  // %bb.2: // %fp-to-i-if-exp.small
-; CHECK-GI-NEXT:    mov w12, #1075 // =0x433
-; CHECK-GI-NEXT:    umulh x13, x8, xzr
-; CHECK-GI-NEXT:    sub x11, x12, x11
-; CHECK-GI-NEXT:    lsr x10, x10, x11
-; CHECK-GI-NEXT:    umulh x14, x9, xzr
-; CHECK-GI-NEXT:    umulh x11, x10, x8
-; CHECK-GI-NEXT:    mul x12, x10, x9
-; CHECK-GI-NEXT:    umulh x15, x10, x9
-; CHECK-GI-NEXT:    mul x0, x10, x8
-; CHECK-GI-NEXT:    adds x1, x11, x12
-; CHECK-GI-NEXT:    add x11, x13, x14
-; CHECK-GI-NEXT:    cset w14, hs
-; CHECK-GI-NEXT:    add x13, x13, x15
-; CHECK-GI-NEXT:    add x11, x11, x15
-; CHECK-GI-NEXT:    madd x9, x10, x9, x11
-; CHECK-GI-NEXT:    and x11, x14, #0x1
-; CHECK-GI-NEXT:    adds x12, x13, x12
-; CHECK-GI-NEXT:    cset w13, hs
-; CHECK-GI-NEXT:    adds x2, x12, x11
-; CHECK-GI-NEXT:    cset w8, hs
-; CHECK-GI-NEXT:    and x10, x13, #0x1
-; CHECK-GI-NEXT:    and x8, x8, #0x1
-; CHECK-GI-NEXT:    add x8, x10, x8
-; CHECK-GI-NEXT:    add x3, x9, x8
-; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB6_3: // %fp-to-i-if-exp.large
-; CHECK-GI-NEXT:    sub x11, x11, #1075
-; CHECK-GI-NEXT:    mov w13, #64 // =0x40
-; CHECK-GI-NEXT:    mov w12, #128 // =0x80
-; CHECK-GI-NEXT:    sub x14, x11, #64
-; CHECK-GI-NEXT:    sub x15, x13, x11
-; CHECK-GI-NEXT:    lsl x16, x10, x11
-; CHECK-GI-NEXT:    lsr x15, x10, x15
-; CHECK-GI-NEXT:    lsl x14, x10, x14
-; CHECK-GI-NEXT:    sub x12, x12, x11
-; CHECK-GI-NEXT:    cmp x11, #64
-; CHECK-GI-NEXT:    sub x17, x11, #128
-; CHECK-GI-NEXT:    lsr x18, x10, x12
-; CHECK-GI-NEXT:    csel x16, x16, xzr, lo
-; CHECK-GI-NEXT:    csel x14, x15, x14, lo
-; CHECK-GI-NEXT:    cmp x11, #0
-; CHECK-GI-NEXT:    sub x15, x17, #64
-; CHECK-GI-NEXT:    csel x14, xzr, x14, eq
-; CHECK-GI-NEXT:    cmp x12, #64
-; CHECK-GI-NEXT:    sub x13, x13, x17
-; CHECK-GI-NEXT:    csel x18, x18, xzr, lo
-; CHECK-GI-NEXT:    cmp x12, #0
-; CHECK-GI-NEXT:    lsl x12, x10, x17
-; CHECK-GI-NEXT:    lsr x13, x10, x13
-; CHECK-GI-NEXT:    lsl x15, x10, x15
-; CHECK-GI-NEXT:    csel x18, x10, x18, eq
-; CHECK-GI-NEXT:    cmp x17, #64
-; CHECK-GI-NEXT:    csel x12, x12, xzr, lo
-; CHECK-GI-NEXT:    csel x10, x13, x15, lo
-; CHECK-GI-NEXT:    cmp x17, #0
-; CHECK-GI-NEXT:    csel x13, xzr, x10, eq
-; CHECK-GI-NEXT:    cmp x11, #128
-; CHECK-GI-NEXT:    csel x10, x16, xzr, lo
-; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
-; CHECK-GI-NEXT:    csel x12, x18, x12, lo
-; CHECK-GI-NEXT:    csel x13, xzr, x13, lo
-; CHECK-GI-NEXT:    cmp x11, #0
-; CHECK-GI-NEXT:    umulh x11, x10, x9
-; CHECK-GI-NEXT:    csel x12, xzr, x12, eq
-; CHECK-GI-NEXT:    csel x13, xzr, x13, eq
-; CHECK-GI-NEXT:    umulh x18, x14, x9
-; CHECK-GI-NEXT:    umulh x17, x12, x8
-; CHECK-GI-NEXT:    umulh x15, x10, x8
-; CHECK-GI-NEXT:    add x18, x18, x11
-; CHECK-GI-NEXT:    mul x16, x10, x9
-; CHECK-GI-NEXT:    add x17, x17, x18
-; CHECK-GI-NEXT:    mul x0, x14, x8
-; CHECK-GI-NEXT:    madd x17, x10, x9, x17
-; CHECK-GI-NEXT:    adds x15, x15, x16
-; CHECK-GI-NEXT:    umulh x2, x14, x8
-; CHECK-GI-NEXT:    cset w3, hs
-; CHECK-GI-NEXT:    adds x1, x15, x0
-; CHECK-GI-NEXT:    mul x18, x14, x9
-; CHECK-GI-NEXT:    cset w15, hs
-; CHECK-GI-NEXT:    madd x14, x14, x9, x17
-; CHECK-GI-NEXT:    adds x11, x2, x11
-; CHECK-GI-NEXT:    mul x17, x12, x8
-; CHECK-GI-NEXT:    cset w0, hs
-; CHECK-GI-NEXT:    adds x11, x11, x16
-; CHECK-GI-NEXT:    and x16, x0, #0x1
-; CHECK-GI-NEXT:    madd x9, x12, x9, x14
-; CHECK-GI-NEXT:    and x12, x3, #0x1
-; CHECK-GI-NEXT:    and x14, x15, #0x1
-; CHECK-GI-NEXT:    cset w15, hs
-; CHECK-GI-NEXT:    adds x11, x11, x18
-; CHECK-GI-NEXT:    and x15, x15, #0x1
-; CHECK-GI-NEXT:    mul x0, x10, x8
-; CHECK-GI-NEXT:    add x10, x12, x14
-; CHECK-GI-NEXT:    cset w14, hs
-; CHECK-GI-NEXT:    adds x11, x11, x17
-; CHECK-GI-NEXT:    add x12, x16, x15
-; CHECK-GI-NEXT:    madd x8, x13, x8, x9
-; CHECK-GI-NEXT:    and x9, x14, #0x1
-; CHECK-GI-NEXT:    cset w13, hs
-; CHECK-GI-NEXT:    adds x2, x11, x10
-; CHECK-GI-NEXT:    add x9, x12, x9
-; CHECK-GI-NEXT:    and x10, x13, #0x1
-; CHECK-GI-NEXT:    cset w11, hs
-; CHECK-GI-NEXT:    add x9, x9, x10
-; CHECK-GI-NEXT:    and x10, x11, #0x1
-; CHECK-GI-NEXT:    add x9, x9, x10
-; CHECK-GI-NEXT:    add x3, x8, x9
-; CHECK-GI-NEXT:  .LBB6_4: // %fp-to-i-cleanup
-; CHECK-GI-NEXT:    ret
-  %result = fptosi double %val to i256
-  ret i256 %result
-}
-
-define i256 @f64_to_u256(double %val) {
-; CHECK-SD-LABEL: f64_to_u256:
-; CHECK-SD:       // %bb.0: // %fp-to-i-entry
-; CHECK-SD-NEXT:    fmov x10, d0
-; CHECK-SD-NEXT:    ubfx x8, x10, #52, #11
-; CHECK-SD-NEXT:    cmp x8, #1023
-; CHECK-SD-NEXT:    b.hs .LBB7_2
-; CHECK-SD-NEXT:  // %bb.1:
-; CHECK-SD-NEXT:    mov x0, xzr
-; CHECK-SD-NEXT:    mov x1, xzr
-; CHECK-SD-NEXT:    mov x2, xzr
-; CHECK-SD-NEXT:    mov x3, xzr
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB7_2: // %fp-to-i-if-check.exp.size
-; CHECK-SD-NEXT:    mov x9, #4503599627370496 // =0x10000000000000
-; CHECK-SD-NEXT:    cmp x8, #1074
-; CHECK-SD-NEXT:    bfxil x9, x10, #0, #52
-; CHECK-SD-NEXT:    b.hi .LBB7_4
-; CHECK-SD-NEXT:  // %bb.3: // %fp-to-i-if-exp.small
-; CHECK-SD-NEXT:    mov w10, #1075 // =0x433
-; CHECK-SD-NEXT:    mov x1, xzr
-; CHECK-SD-NEXT:    mov x2, xzr
-; CHECK-SD-NEXT:    sub x8, x10, x8
-; CHECK-SD-NEXT:    mov x3, xzr
-; CHECK-SD-NEXT:    lsr x0, x9, x8
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB7_4: // %fp-to-i-if-exp.large
-; CHECK-SD-NEXT:    sub sp, sp, #64
-; CHECK-SD-NEXT:    .cfi_def_cfa_offset 64
-; CHECK-SD-NEXT:    movi v0.2d, #0000000000000000
-; CHECK-SD-NEXT:    sub x8, x8, #1075
-; CHECK-SD-NEXT:    str x9, [sp, #32]
-; CHECK-SD-NEXT:    lsr x9, x8, #3
-; CHECK-SD-NEXT:    mov x10, sp
-; CHECK-SD-NEXT:    str xzr, [sp, #56]
-; CHECK-SD-NEXT:    add x10, x10, #32
-; CHECK-SD-NEXT:    and x13, x8, #0x3f
-; CHECK-SD-NEXT:    mvn w17, w8
-; CHECK-SD-NEXT:    and x9, x9, #0x18
-; CHECK-SD-NEXT:    eor x13, x13, #0x3f
-; CHECK-SD-NEXT:    stur q0, [sp, #40]
-; CHECK-SD-NEXT:    sub x9, x10, x9
-; CHECK-SD-NEXT:    stp q0, q0, [sp]
-; CHECK-SD-NEXT:    ldp x11, x10, [x9, #8]
-; CHECK-SD-NEXT:    ldr x12, [x9]
-; CHECK-SD-NEXT:    ldr x9, [x9, #24]
-; CHECK-SD-NEXT:    lsr x16, x12, #1
-; CHECK-SD-NEXT:    lsl x0, x12, x8
-; CHECK-SD-NEXT:    lsr x14, x10, #1
-; CHECK-SD-NEXT:    lsr x15, x11, #1
-; CHECK-SD-NEXT:    lsl x9, x9, x8
-; CHECK-SD-NEXT:    lsl x10, x10, x8
-; CHECK-SD-NEXT:    lsl x11, x11, x8
-; CHECK-SD-NEXT:    lsr x15, x15, x17
-; CHECK-SD-NEXT:    lsr x14, x14, x13
-; CHECK-SD-NEXT:    lsr x13, x16, x13
-; CHECK-SD-NEXT:    orr x3, x9, x14
-; CHECK-SD-NEXT:    orr x2, x10, x15
-; CHECK-SD-NEXT:    orr x1, x11, x13
-; CHECK-SD-NEXT:    add sp, sp, #64
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: f64_to_u256:
-; CHECK-GI:       // %bb.0: // %fp-to-i-entry
-; CHECK-GI-NEXT:    fmov x8, d0
-; CHECK-GI-NEXT:    mov x0, xzr
-; CHECK-GI-NEXT:    mov x1, xzr
-; CHECK-GI-NEXT:    mov x2, xzr
-; CHECK-GI-NEXT:    mov x3, xzr
-; CHECK-GI-NEXT:    ubfx x9, x8, #52, #11
-; CHECK-GI-NEXT:    cmp x9, #1023
-; CHECK-GI-NEXT:    b.lo .LBB7_4
-; CHECK-GI-NEXT:  // %bb.1: // %fp-to-i-if-check.exp.size
-; CHECK-GI-NEXT:    and x8, x8, #0xfffffffffffff
-; CHECK-GI-NEXT:    cmp x9, #1075
-; CHECK-GI-NEXT:    orr x8, x8, #0x10000000000000
-; CHECK-GI-NEXT:    b.hs .LBB7_3
-; CHECK-GI-NEXT:  // %bb.2: // %fp-to-i-if-exp.small
-; CHECK-GI-NEXT:    mov w10, #1075 // =0x433
-; CHECK-GI-NEXT:    mov x1, xzr
-; CHECK-GI-NEXT:    mov x2, xzr
-; CHECK-GI-NEXT:    sub x9, x10, x9
-; CHECK-GI-NEXT:    mov x3, xzr
-; CHECK-GI-NEXT:    lsr x0, x8, x9
-; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB7_3: // %fp-to-i-if-exp.large
-; CHECK-GI-NEXT:    sub x9, x9, #1075
-; CHECK-GI-NEXT:    mov w11, #64 // =0x40
-; CHECK-GI-NEXT:    mov w10, #128 // =0x80
-; CHECK-GI-NEXT:    sub x12, x9, #64
-; CHECK-GI-NEXT:    sub x13, x11, x9
-; CHECK-GI-NEXT:    lsl x14, x8, x9
-; CHECK-GI-NEXT:    lsr x13, x8, x13
-; CHECK-GI-NEXT:    lsl x12, x8, x12
-; CHECK-GI-NEXT:    sub x10, x10, x9
-; CHECK-GI-NEXT:    cmp x9, #64
-; CHECK-GI-NEXT:    sub x15, x9, #128
-; CHECK-GI-NEXT:    lsr x16, x8, x10
-; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
-; CHECK-GI-NEXT:    csel x12, x13, x12, lo
-; CHECK-GI-NEXT:    cmp x9, #0
-; CHECK-GI-NEXT:    sub x13, x15, #64
-; CHECK-GI-NEXT:    csel x12, xzr, x12, eq
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    sub x11, x11, x15
-; CHECK-GI-NEXT:    csel x16, x16, xzr, lo
-; CHECK-GI-NEXT:    cmp x10, #0
-; CHECK-GI-NEXT:    lsl x10, x8, x15
-; CHECK-GI-NEXT:    lsr x11, x8, x11
-; CHECK-GI-NEXT:    lsl x13, x8, x13
-; CHECK-GI-NEXT:    csel x8, x8, x16, eq
-; CHECK-GI-NEXT:    cmp x15, #64
-; CHECK-GI-NEXT:    csel x10, x10, xzr, lo
-; CHECK-GI-NEXT:    csel x11, x11, x13, lo
-; CHECK-GI-NEXT:    cmp x15, #0
-; CHECK-GI-NEXT:    csel x11, xzr, x11, eq
-; CHECK-GI-NEXT:    cmp x9, #128
-; CHECK-GI-NEXT:    csel x0, x14, xzr, lo
-; CHECK-GI-NEXT:    csel x1, x12, xzr, lo
-; CHECK-GI-NEXT:    csel x8, x8, x10, lo
-; CHECK-GI-NEXT:    csel x10, xzr, x11, lo
-; CHECK-GI-NEXT:    cmp x9, #0
-; CHECK-GI-NEXT:    csel x2, xzr, x8, eq
-; CHECK-GI-NEXT:    csel x3, xzr, x10, eq
-; CHECK-GI-NEXT:  .LBB7_4: // %fp-to-i-cleanup
-; CHECK-GI-NEXT:    ret
-  %result = fptoui double %val to i256
-  ret i256 %result
-}
-
-define i256 @f32_to_s256_sat(float %val) {
-; CHECK-SD-LABEL: f32_to_s256_sat:
-; CHECK-SD:       // %bb.0: // %fp-to-i-entry
-; CHECK-SD-NEXT:    fmov w8, s0
-; CHECK-SD-NEXT:    mov x0, xzr
-; CHECK-SD-NEXT:    ubfx w10, w8, #23, #8
-; CHECK-SD-NEXT:    cmp w10, #127
-; CHECK-SD-NEXT:    b.lo .LBB8_5
-; CHECK-SD-NEXT:  // %bb.1: // %fp-to-i-entry
-; CHECK-SD-NEXT:    fcmp s0, s0
-; CHECK-SD-NEXT:    mov x1, x0
-; CHECK-SD-NEXT:    mov x2, x0
-; CHECK-SD-NEXT:    mov x3, x0
-; CHECK-SD-NEXT:    b.vs .LBB8_7
-; CHECK-SD-NEXT:  // %bb.2: // %fp-to-i-if-check.saturate
-; CHECK-SD-NEXT:    cmp w10, #255
-; CHECK-SD-NEXT:    b.hs .LBB8_8
-; CHECK-SD-NEXT:  // %bb.3: // %fp-to-i-if-check.exp.size
-; CHECK-SD-NEXT:    sbfx x9, x8, #31, #1
-; CHECK-SD-NEXT:    mov w11, #8388608 // =0x800000
-; CHECK-SD-NEXT:    cmp w10, #149
-; CHECK-SD-NEXT:    bfxil w11, w8, #0, #23
-; CHECK-SD-NEXT:    orr x8, x9, #0x1
-; CHECK-SD-NEXT:    b.hi .LBB8_6
-; CHECK-SD-NEXT:  // %bb.4: // %fp-to-i-if-exp.small
-; CHECK-SD-NEXT:    mov w12, #150 // =0x96
-; CHECK-SD-NEXT:    sub w10, w12, w10
-; CHECK-SD-NEXT:    lsr w10, w11, w10
-; CHECK-SD-NEXT:    umulh x13, x10, x8
-; CHECK-SD-NEXT:    umulh x12, x10, x9
-; CHECK-SD-NEXT:    umulh x11, x9, x10
-; CHECK-SD-NEXT:    smull x14, w10, w9
-; CHECK-SD-NEXT:    smull x15, w9, w10
-; CHECK-SD-NEXT:    smull x9, w9, w10
-; CHECK-SD-NEXT:    adds x1, x14, x13
-; CHECK-SD-NEXT:    smull x0, w10, w8
-; CHECK-SD-NEXT:    adcs x2, x15, x12
-; CHECK-SD-NEXT:    adc x3, x11, x9
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB8_5:
-; CHECK-SD-NEXT:    mov x1, x0
-; CHECK-SD-NEXT:    mov x2, x0
-; CHECK-SD-NEXT:    mov x3, x0
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB8_6: // %fp-to-i-if-exp.large
-; CHECK-SD-NEXT:    sub sp, sp, #64
-; CHECK-SD-NEXT:    .cfi_def_cfa_offset 64
-; CHECK-SD-NEXT:    movi v0.2d, #0000000000000000
-; CHECK-SD-NEXT:    sub w10, w10, #150
-; CHECK-SD-NEXT:    str x11, [sp, #32]
-; CHECK-SD-NEXT:    lsr x11, x10, #3
-; CHECK-SD-NEXT:    mov x12, sp
-; CHECK-SD-NEXT:    str xzr, [sp, #56]
-; CHECK-SD-NEXT:    add x12, x12, #32
-; CHECK-SD-NEXT:    and x16, x10, #0x3f
-; CHECK-SD-NEXT:    mvn w2, w10
-; CHECK-SD-NEXT:    and x11, x11, #0x18
-; CHECK-SD-NEXT:    eor x16, x16, #0x3f
-; CHECK-SD-NEXT:    stur q0, [sp, #40]
-; CHECK-SD-NEXT:    sub x11, x12, x11
-; CHECK-SD-NEXT:    stp q0, q0, [sp]
-; CHECK-SD-NEXT:    ldp x12, x15, [x11]
-; CHECK-SD-NEXT:    ldp x1, x11, [x11, #16]
-; CHECK-SD-NEXT:    lsl x18, x15, x10
-; CHECK-SD-NEXT:    lsr x15, x15, #1
-; CHECK-SD-NEXT:    lsl x13, x12, x10
-; CHECK-SD-NEXT:    lsr x12, x12, #1
-; CHECK-SD-NEXT:    lsl x4, x1, x10
-; CHECK-SD-NEXT:    lsr x1, x1, #1
-; CHECK-SD-NEXT:    lsr x15, x15, x2
-; CHECK-SD-NEXT:    lsl x10, x11, x10
-; CHECK-SD-NEXT:    umulh x14, x13, x8
-; CHECK-SD-NEXT:    lsr x12, x12, x16
-; CHECK-SD-NEXT:    lsr x11, x1, x16
-; CHECK-SD-NEXT:    orr x15, x4, x15
-; CHECK-SD-NEXT:    mul x0, x13, x9
-; CHECK-SD-NEXT:    orr x12, x18, x12
-; CHECK-SD-NEXT:    orr x10, x10, x11
-; CHECK-SD-NEXT:    umulh x4, x8, x15
-; CHECK-SD-NEXT:    mul x3, x12, x8
-; CHECK-SD-NEXT:    umulh x11, x9, x13
-; CHECK-SD-NEXT:    umulh x18, x12, x8
-; CHECK-SD-NEXT:    adds x14, x3, x14
-; CHECK-SD-NEXT:    umulh x17, x13, x9
-; CHECK-SD-NEXT:    madd x10, x8, x10, x4
-; CHECK-SD-NEXT:    cinc x18, x18, hs
-; CHECK-SD-NEXT:    adds x1, x0, x14
-; CHECK-SD-NEXT:    madd x11, x9, x12, x11
-; CHECK-SD-NEXT:    mul x16, x12, x9
-; CHECK-SD-NEXT:    umulh x2, x12, x9
-; CHECK-SD-NEXT:    madd x10, x9, x15, x10
-; CHECK-SD-NEXT:    mul x12, x8, x15
-; CHECK-SD-NEXT:    mul x15, x9, x13
-; CHECK-SD-NEXT:    madd x9, x9, x13, x11
-; CHECK-SD-NEXT:    cinc x11, x17, hs
-; CHECK-SD-NEXT:    adds x11, x18, x11
-; CHECK-SD-NEXT:    mul x0, x13, x8
-; CHECK-SD-NEXT:    cset w8, hs
-; CHECK-SD-NEXT:    adds x11, x16, x11
-; CHECK-SD-NEXT:    adc x8, x2, x8
-; CHECK-SD-NEXT:    adds x12, x15, x12
-; CHECK-SD-NEXT:    adc x9, x9, x10
-; CHECK-SD-NEXT:    adds x2, x11, x12
-; CHECK-SD-NEXT:    adc x3, x8, x9
-; CHECK-SD-NEXT:    add sp, sp, #64
-; CHECK-SD-NEXT:  .LBB8_7: // %fp-to-i-cleanup
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB8_8: // %fp-to-i-if-saturate
-; CHECK-SD-NEXT:    // kill: def $w8 killed $w8 killed $x8 def $x8
-; CHECK-SD-NEXT:    sbfx x8, x8, #31, #1
-; CHECK-SD-NEXT:    mvn x0, x8
-; CHECK-SD-NEXT:    eor x3, x8, #0x7fffffffffffffff
-; CHECK-SD-NEXT:    mov x1, x0
-; CHECK-SD-NEXT:    mov x2, x0
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: f32_to_s256_sat:
-; CHECK-GI:       // %bb.0: // %fp-to-i-entry
-; CHECK-GI-NEXT:    fmov w8, s0
-; CHECK-GI-NEXT:    ubfx w11, w8, #23, #8
-; CHECK-GI-NEXT:    cmn w8, #1
-; CHECK-GI-NEXT:    cset w9, le
-; CHECK-GI-NEXT:    cmp w11, #127
-; CHECK-GI-NEXT:    b.lo .LBB8_5
-; CHECK-GI-NEXT:  // %bb.1: // %fp-to-i-entry
-; CHECK-GI-NEXT:    fcmp s0, s0
-; CHECK-GI-NEXT:    b.vs .LBB8_5
-; CHECK-GI-NEXT:  // %bb.2: // %fp-to-i-if-check.saturate
-; CHECK-GI-NEXT:    cmp w11, #255
-; CHECK-GI-NEXT:    b.hs .LBB8_7
-; CHECK-GI-NEXT:  // %bb.3: // %fp-to-i-if-check.exp.size
-; CHECK-GI-NEXT:    sbfx x10, x9, #0, #1
-; CHECK-GI-NEXT:    and w12, w8, #0x7fffff
-; CHECK-GI-NEXT:    cmp w11, #150
-; CHECK-GI-NEXT:    asr x9, x10, #63
-; CHECK-GI-NEXT:    orr x8, x10, #0x1
-; CHECK-GI-NEXT:    orr w10, w12, #0x800000
-; CHECK-GI-NEXT:    b.hs .LBB8_6
-; CHECK-GI-NEXT:  // %bb.4: // %fp-to-i-if-exp.small
-; CHECK-GI-NEXT:    mov w12, #150 // =0x96
-; CHECK-GI-NEXT:    umulh x15, x9, xzr
-; CHECK-GI-NEXT:    sub w11, w12, w11
-; CHECK-GI-NEXT:    lsr w10, w10, w11
-; CHECK-GI-NEXT:    umulh x12, x8, xzr
-; CHECK-GI-NEXT:    umulh x11, x10, x8
-; CHECK-GI-NEXT:    umulh x13, x10, x9
-; CHECK-GI-NEXT:    smull x14, w10, w9
-; CHECK-GI-NEXT:    smull x16, w10, w9
-; CHECK-GI-NEXT:    smull x0, w10, w8
-; CHECK-GI-NEXT:    adds x1, x11, x14
-; CHECK-GI-NEXT:    add x14, x12, x15
-; CHECK-GI-NEXT:    add x12, x12, x13
-; CHECK-GI-NEXT:    cset w11, hs
-; CHECK-GI-NEXT:    adds x12, x12, x16
-; CHECK-GI-NEXT:    add x13, x14, x13
-; CHECK-GI-NEXT:    and x11, x11, #0x1
-; CHECK-GI-NEXT:    smaddl x9, w10, w9, x13
-; CHECK-GI-NEXT:    cset w13, hs
-; CHECK-GI-NEXT:    adds x2, x12, x11
-; CHECK-GI-NEXT:    and x8, x13, #0x1
-; CHECK-GI-NEXT:    cset w10, hs
-; CHECK-GI-NEXT:    and x10, x10, #0x1
-; CHECK-GI-NEXT:    add x8, x9, x8
-; CHECK-GI-NEXT:    add x3, x8, x10
-; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB8_5:
-; CHECK-GI-NEXT:    mov x0, xzr
-; CHECK-GI-NEXT:    mov x1, xzr
-; CHECK-GI-NEXT:    mov x2, xzr
-; CHECK-GI-NEXT:    mov x3, xzr
-; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB8_6: // %fp-to-i-if-exp.large
-; CHECK-GI-NEXT:    sub w11, w11, #150
-; CHECK-GI-NEXT:    mov w13, #64 // =0x40
-; CHECK-GI-NEXT:    mov w12, #128 // =0x80
-; CHECK-GI-NEXT:    sub x14, x11, #64
-; CHECK-GI-NEXT:    sub x15, x13, x11
-; CHECK-GI-NEXT:    lsl x16, x10, x11
-; CHECK-GI-NEXT:    lsr x15, x10, x15
-; CHECK-GI-NEXT:    lsl x14, x10, x14
-; CHECK-GI-NEXT:    sub x12, x12, x11
-; CHECK-GI-NEXT:    cmp x11, #64
-; CHECK-GI-NEXT:    sub x17, x11, #128
-; CHECK-GI-NEXT:    lsr x18, x10, x12
-; CHECK-GI-NEXT:    csel x16, x16, xzr, lo
-; CHECK-GI-NEXT:    csel x14, x15, x14, lo
-; CHECK-GI-NEXT:    cmp x11, #0
-; CHECK-GI-NEXT:    sub x15, x17, #64
-; CHECK-GI-NEXT:    csel x14, xzr, x14, eq
-; CHECK-GI-NEXT:    cmp x12, #64
-; CHECK-GI-NEXT:    sub x13, x13, x17
-; CHECK-GI-NEXT:    csel x18, x18, xzr, lo
-; CHECK-GI-NEXT:    cmp x12, #0
-; CHECK-GI-NEXT:    lsl x12, x10, x17
-; CHECK-GI-NEXT:    lsr x13, x10, x13
-; CHECK-GI-NEXT:    lsl x15, x10, x15
-; CHECK-GI-NEXT:    csel x18, x10, x18, eq
-; CHECK-GI-NEXT:    cmp x17, #64
-; CHECK-GI-NEXT:    csel x12, x12, xzr, lo
-; CHECK-GI-NEXT:    csel x10, x13, x15, lo
-; CHECK-GI-NEXT:    cmp x17, #0
-; CHECK-GI-NEXT:    csel x13, xzr, x10, eq
-; CHECK-GI-NEXT:    cmp x11, #128
-; CHECK-GI-NEXT:    csel x10, x16, xzr, lo
-; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
-; CHECK-GI-NEXT:    csel x12, x18, x12, lo
-; CHECK-GI-NEXT:    csel x13, xzr, x13, lo
-; CHECK-GI-NEXT:    cmp x11, #0
-; CHECK-GI-NEXT:    umulh x11, x10, x9
-; CHECK-GI-NEXT:    csel x12, xzr, x12, eq
-; CHECK-GI-NEXT:    csel x13, xzr, x13, eq
-; CHECK-GI-NEXT:    umulh x18, x14, x9
-; CHECK-GI-NEXT:    umulh x17, x12, x8
-; CHECK-GI-NEXT:    umulh x15, x10, x8
-; CHECK-GI-NEXT:    add x18, x18, x11
-; CHECK-GI-NEXT:    mul x16, x10, x9
-; CHECK-GI-NEXT:    add x17, x17, x18
-; CHECK-GI-NEXT:    mul x0, x14, x8
-; CHECK-GI-NEXT:    madd x17, x10, x9, x17
-; CHECK-GI-NEXT:    adds x15, x15, x16
-; CHECK-GI-NEXT:    umulh x2, x14, x8
-; CHECK-GI-NEXT:    cset w3, hs
-; CHECK-GI-NEXT:    adds x1, x15, x0
-; CHECK-GI-NEXT:    mul x18, x14, x9
-; CHECK-GI-NEXT:    cset w15, hs
-; CHECK-GI-NEXT:    madd x14, x14, x9, x17
-; CHECK-GI-NEXT:    adds x11, x2, x11
-; CHECK-GI-NEXT:    mul x17, x12, x8
-; CHECK-GI-NEXT:    cset w0, hs
-; CHECK-GI-NEXT:    adds x11, x11, x16
-; CHECK-GI-NEXT:    and x16, x0, #0x1
-; CHECK-GI-NEXT:    madd x9, x12, x9, x14
-; CHECK-GI-NEXT:    and x12, x3, #0x1
-; CHECK-GI-NEXT:    and x14, x15, #0x1
-; CHECK-GI-NEXT:    cset w15, hs
-; CHECK-GI-NEXT:    adds x11, x11, x18
-; CHECK-GI-NEXT:    and x15, x15, #0x1
-; CHECK-GI-NEXT:    mul x0, x10, x8
-; CHECK-GI-NEXT:    add x10, x12, x14
-; CHECK-GI-NEXT:    cset w14, hs
-; CHECK-GI-NEXT:    adds x11, x11, x17
-; CHECK-GI-NEXT:    add x12, x16, x15
-; CHECK-GI-NEXT:    madd x8, x13, x8, x9
-; CHECK-GI-NEXT:    and x9, x14, #0x1
-; CHECK-GI-NEXT:    cset w13, hs
-; CHECK-GI-NEXT:    adds x2, x11, x10
-; CHECK-GI-NEXT:    add x9, x12, x9
-; CHECK-GI-NEXT:    and x10, x13, #0x1
-; CHECK-GI-NEXT:    cset w11, hs
-; CHECK-GI-NEXT:    add x9, x9, x10
-; CHECK-GI-NEXT:    and x10, x11, #0x1
-; CHECK-GI-NEXT:    add x9, x9, x10
-; CHECK-GI-NEXT:    add x3, x8, x9
-; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB8_7: // %fp-to-i-if-saturate
-; CHECK-GI-NEXT:    cmn w8, #1
-; CHECK-GI-NEXT:    mov w9, wzr
-; CHECK-GI-NEXT:    cset w8, gt
-; CHECK-GI-NEXT:    cmp w9, #1
-; CHECK-GI-NEXT:    mov x9, #-9223372036854775808 // =0x8000000000000000
-; CHECK-GI-NEXT:    sbfx x0, x8, #0, #1
-; CHECK-GI-NEXT:    asr x8, x0, #63
-; CHECK-GI-NEXT:    adcs x1, x8, xzr
-; CHECK-GI-NEXT:    adcs x2, x8, xzr
-; CHECK-GI-NEXT:    adc x3, x8, x9
-; CHECK-GI-NEXT:    ret
+define i256 @f32_to_s256_sat(float %val) {
+; CHECK-LABEL: f32_to_s256_sat:
+; CHECK:       // %bb.0: // %fp-to-i-entry
+; CHECK-NEXT:    fmov w8, s0
+; CHECK-NEXT:    mov x0, xzr
+; CHECK-NEXT:    ubfx w10, w8, #23, #8
+; CHECK-NEXT:    cmp w10, #127
+; CHECK-NEXT:    b.lo .LBB8_5
+; CHECK-NEXT:  // %bb.1: // %fp-to-i-entry
+; CHECK-NEXT:    fcmp s0, s0
+; CHECK-NEXT:    mov x1, x0
+; CHECK-NEXT:    mov x2, x0
+; CHECK-NEXT:    mov x3, x0
+; CHECK-NEXT:    b.vs .LBB8_7
+; CHECK-NEXT:  // %bb.2: // %fp-to-i-if-check.saturate
+; CHECK-NEXT:    cmp w10, #255
+; CHECK-NEXT:    b.hs .LBB8_8
+; CHECK-NEXT:  // %bb.3: // %fp-to-i-if-check.exp.size
+; CHECK-NEXT:    sbfx x9, x8, #31, #1
+; CHECK-NEXT:    mov w11, #8388608 // =0x800000
+; CHECK-NEXT:    cmp w10, #149
+; CHECK-NEXT:    bfxil w11, w8, #0, #23
+; CHECK-NEXT:    orr x8, x9, #0x1
+; CHECK-NEXT:    b.hi .LBB8_6
+; CHECK-NEXT:  // %bb.4: // %fp-to-i-if-exp.small
+; CHECK-NEXT:    mov w12, #150 // =0x96
+; CHECK-NEXT:    sub w10, w12, w10
+; CHECK-NEXT:    lsr w10, w11, w10
+; CHECK-NEXT:    umulh x13, x10, x8
+; CHECK-NEXT:    umulh x12, x10, x9
+; CHECK-NEXT:    umulh x11, x9, x10
+; CHECK-NEXT:    smull x14, w10, w9
+; CHECK-NEXT:    smull x15, w9, w10
+; CHECK-NEXT:    smull x9, w9, w10
+; CHECK-NEXT:    adds x1, x14, x13
+; CHECK-NEXT:    smull x0, w10, w8
+; CHECK-NEXT:    adcs x2, x15, x12
+; CHECK-NEXT:    adc x3, x11, x9
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB8_5:
+; CHECK-NEXT:    mov x1, x0
+; CHECK-NEXT:    mov x2, x0
+; CHECK-NEXT:    mov x3, x0
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB8_6: // %fp-to-i-if-exp.large
+; CHECK-NEXT:    sub sp, sp, #64
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-NEXT:    movi v0.2d, #0000000000000000
+; CHECK-NEXT:    sub w10, w10, #150
+; CHECK-NEXT:    str x11, [sp, #32]
+; CHECK-NEXT:    lsr x11, x10, #3
+; CHECK-NEXT:    mov x12, sp
+; CHECK-NEXT:    str xzr, [sp, #56]
+; CHECK-NEXT:    add x12, x12, #32
+; CHECK-NEXT:    and x16, x10, #0x3f
+; CHECK-NEXT:    mvn w2, w10
+; CHECK-NEXT:    and x11, x11, #0x18
+; CHECK-NEXT:    eor x16, x16, #0x3f
+; CHECK-NEXT:    stur q0, [sp, #40]
+; CHECK-NEXT:    sub x11, x12, x11
+; CHECK-NEXT:    stp q0, q0, [sp]
+; CHECK-NEXT:    ldp x12, x15, [x11]
+; CHECK-NEXT:    ldp x1, x11, [x11, #16]
+; CHECK-NEXT:    lsl x18, x15, x10
+; CHECK-NEXT:    lsr x15, x15, #1
+; CHECK-NEXT:    lsl x13, x12, x10
+; CHECK-NEXT:    lsr x12, x12, #1
+; CHECK-NEXT:    lsl x4, x1, x10
+; CHECK-NEXT:    lsr x1, x1, #1
+; CHECK-NEXT:    lsr x15, x15, x2
+; CHECK-NEXT:    lsl x10, x11, x10
+; CHECK-NEXT:    umulh x14, x13, x8
+; CHECK-NEXT:    lsr x12, x12, x16
+; CHECK-NEXT:    lsr x11, x1, x16
+; CHECK-NEXT:    orr x15, x4, x15
+; CHECK-NEXT:    mul x0, x13, x9
+; CHECK-NEXT:    orr x12, x18, x12
+; CHECK-NEXT:    orr x10, x10, x11
+; CHECK-NEXT:    umulh x4, x8, x15
+; CHECK-NEXT:    mul x3, x12, x8
+; CHECK-NEXT:    umulh x11, x9, x13
+; CHECK-NEXT:    umulh x18, x12, x8
+; CHECK-NEXT:    adds x14, x3, x14
+; CHECK-NEXT:    umulh x17, x13, x9
+; CHECK-NEXT:    madd x10, x8, x10, x4
+; CHECK-NEXT:    cinc x18, x18, hs
+; CHECK-NEXT:    adds x1, x0, x14
+; CHECK-NEXT:    madd x11, x9, x12, x11
+; CHECK-NEXT:    mul x16, x12, x9
+; CHECK-NEXT:    umulh x2, x12, x9
+; CHECK-NEXT:    madd x10, x9, x15, x10
+; CHECK-NEXT:    mul x12, x8, x15
+; CHECK-NEXT:    mul x15, x9, x13
+; CHECK-NEXT:    madd x9, x9, x13, x11
+; CHECK-NEXT:    cinc x11, x17, hs
+; CHECK-NEXT:    adds x11, x18, x11
+; CHECK-NEXT:    mul x0, x13, x8
+; CHECK-NEXT:    cset w8, hs
+; CHECK-NEXT:    adds x11, x16, x11
+; CHECK-NEXT:    adc x8, x2, x8
+; CHECK-NEXT:    adds x12, x15, x12
+; CHECK-NEXT:    adc x9, x9, x10
+; CHECK-NEXT:    adds x2, x11, x12
+; CHECK-NEXT:    adc x3, x8, x9
+; CHECK-NEXT:    add sp, sp, #64
+; CHECK-NEXT:  .LBB8_7: // %fp-to-i-cleanup
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB8_8: // %fp-to-i-if-saturate
+; CHECK-NEXT:    // kill: def $w8 killed $w8 killed $x8 def $x8
+; CHECK-NEXT:    sbfx x8, x8, #31, #1
+; CHECK-NEXT:    mvn x0, x8
+; CHECK-NEXT:    eor x3, x8, #0x7fffffffffffffff
+; CHECK-NEXT:    mov x1, x0
+; CHECK-NEXT:    mov x2, x0
+; CHECK-NEXT:    ret
   %result = call i256 @llvm.fptosi.sat(float %val)
   ret i256 %result
 }
 
 define i256 @f32_to_u256_sat(float %val) {
-; CHECK-SD-LABEL: f32_to_u256_sat:
-; CHECK-SD:       // %bb.0: // %fp-to-i-entry
-; CHECK-SD-NEXT:    fmov w10, s0
-; CHECK-SD-NEXT:    mov w9, #127 // =0x7f
-; CHECK-SD-NEXT:    cmp w10, #0
-; CHECK-SD-NEXT:    ubfx w8, w10, #23, #8
-; CHECK-SD-NEXT:    fccmp s0, s0, #1, pl
-; CHECK-SD-NEXT:    ccmp w8, w9, #0, vc
-; CHECK-SD-NEXT:    b.hs .LBB9_2
-; CHECK-SD-NEXT:  // %bb.1:
-; CHECK-SD-NEXT:    mov x0, xzr
-; CHECK-SD-NEXT:    mov x1, xzr
-; CHECK-SD-NEXT:    mov x2, xzr
-; CHECK-SD-NEXT:    mov x3, xzr
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB9_2: // %fp-to-i-if-check.saturate
-; CHECK-SD-NEXT:    cmp w8, #254
-; CHECK-SD-NEXT:    b.hi .LBB9_6
-; CHECK-SD-NEXT:  // %bb.3: // %fp-to-i-if-check.exp.size
-; CHECK-SD-NEXT:    mov w9, #8388608 // =0x800000
-; CHECK-SD-NEXT:    cmp w8, #149
-; CHECK-SD-NEXT:    bfxil w9, w10, #0, #23
-; CHECK-SD-NEXT:    b.hi .LBB9_5
-; CHECK-SD-NEXT:  // %bb.4: // %fp-to-i-if-exp.small
-; CHECK-SD-NEXT:    mov w10, #150 // =0x96
-; CHECK-SD-NEXT:    mov x1, xzr
-; CHECK-SD-NEXT:    mov x2, xzr
-; CHECK-SD-NEXT:    sub w8, w10, w8
-; CHECK-SD-NEXT:    mov x3, xzr
-; CHECK-SD-NEXT:    lsr w0, w9, w8
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB9_5: // %fp-to-i-if-exp.large
-; CHECK-SD-NEXT:    sub sp, sp, #64
-; CHECK-SD-NEXT:    .cfi_def_cfa_offset 64
-; CHECK-SD-NEXT:    movi v0.2d, #0000000000000000
-; CHECK-SD-NEXT:    sub w8, w8, #150
-; CHECK-SD-NEXT:    str x9, [sp, #32]
-; CHECK-SD-NEXT:    lsr x9, x8, #3
-; CHECK-SD-NEXT:    mov x10, sp
-; CHECK-SD-NEXT:    str xzr, [sp, #56]
-; CHECK-SD-NEXT:    add x10, x10, #32
-; CHECK-SD-NEXT:    and x13, x8, #0x3f
-; CHECK-SD-NEXT:    mvn w17, w8
-; CHECK-SD-NEXT:    and x9, x9, #0x18
-; CHECK-SD-NEXT:    eor x13, x13, #0x3f
-; CHECK-SD-NEXT:    stur q0, [sp, #40]
-; CHECK-SD-NEXT:    sub x9, x10, x9
-; CHECK-SD-NEXT:    stp q0, q0, [sp]
-; CHECK-SD-NEXT:    ldp x11, x10, [x9, #8]
-; CHECK-SD-NEXT:    ldr x12, [x9]
-; CHECK-SD-NEXT:    ldr x9, [x9, #24]
-; CHECK-SD-NEXT:    lsr x16, x12, #1
-; CHECK-SD-NEXT:    lsl x0, x12, x8
-; CHECK-SD-NEXT:    lsr x14, x10, #1
-; CHECK-SD-NEXT:    lsr x15, x11, #1
-; CHECK-SD-NEXT:    lsl x9, x9, x8
-; CHECK-SD-NEXT:    lsl x10, x10, x8
-; CHECK-SD-NEXT:    lsl x11, x11, x8
-; CHECK-SD-NEXT:    lsr x15, x15, x17
-; CHECK-SD-NEXT:    lsr x14, x14, x13
-; CHECK-SD-NEXT:    lsr x13, x16, x13
-; CHECK-SD-NEXT:    orr x3, x9, x14
-; CHECK-SD-NEXT:    orr x2, x10, x15
-; CHECK-SD-NEXT:    orr x1, x11, x13
-; CHECK-SD-NEXT:    add sp, sp, #64
-; CHECK-SD-NEXT:    ret
-; CHECK-SD-NEXT:  .LBB9_6:
-; CHECK-SD-NEXT:    mov x0, #-1 // =0xffffffffffffffff
-; CHECK-SD-NEXT:    mov x1, #-1 // =0xffffffffffffffff
-; CHECK-SD-NEXT:    mov x2, #-1 // =0xffffffffffffffff
-; CHECK-SD-NEXT:    mov x3, #-1 // =0xffffffffffffffff
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: f32_to_u256_sat:
-; CHECK-GI:       // %bb.0: // %fp-to-i-entry
-; CHECK-GI-NEXT:    fmov w8, s0
-; CHECK-GI-NEXT:    mov x0, xzr
-; CHECK-GI-NEXT:    ubfx w9, w8, #23, #8
-; CHECK-GI-NEXT:    cmp w9, #127
-; CHECK-GI-NEXT:    b.lo .LBB9_6
-; CHECK-GI-NEXT:  // %bb.1: // %fp-to-i-entry
-; CHECK-GI-NEXT:    fcmp s0, s0
-; CHECK-GI-NEXT:    b.vs .LBB9_6
-; CHECK-GI-NEXT:  // %bb.2: // %fp-to-i-entry
-; CHECK-GI-NEXT:    mov x1, x0
-; CHECK-GI-NEXT:    mov x2, x0
-; CHECK-GI-NEXT:    mov x3, x0
-; CHECK-GI-NEXT:    tbnz w8, #31, .LBB9_8
-; CHECK-GI-NEXT:  // %bb.3: // %fp-to-i-if-check.saturate
-; CHECK-GI-NEXT:    cmp w9, #255
-; CHECK-GI-NEXT:    b.hs .LBB9_9
-; CHECK-GI-NEXT:  // %bb.4: // %fp-to-i-if-check.exp.size
-; CHECK-GI-NEXT:    and w8, w8, #0x7fffff
-; CHECK-GI-NEXT:    cmp w9, #150
-; CHECK-GI-NEXT:    orr w8, w8, #0x800000
-; CHECK-GI-NEXT:    b.hs .LBB9_7
-; CHECK-GI-NEXT:  // %bb.5: // %fp-to-i-if-exp.small
-; CHECK-GI-NEXT:    mov w10, #150 // =0x96
-; CHECK-GI-NEXT:    mov x1, xzr
-; CHECK-GI-NEXT:    mov x2, xzr
-; CHECK-GI-NEXT:    sub w9, w10, w9
-; CHECK-GI-NEXT:    mov x3, xzr
-; CHECK-GI-NEXT:    lsr w0, w8, w9
-; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB9_6:
-; CHECK-GI-NEXT:    mov x1, x0
-; CHECK-GI-NEXT:    mov x2, x0
-; CHECK-GI-NEXT:    mov x3, x0
-; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB9_7: // %fp-to-i-if-exp.large
-; CHECK-GI-NEXT:    sub w9, w9, #150
-; CHECK-GI-NEXT:    mov w11, #64 // =0x40
-; CHECK-GI-NEXT:    mov w10, #128 // =0x80
-; CHECK-GI-NEXT:    sub x12, x9, #64
-; CHECK-GI-NEXT:    sub x13, x11, x9
-; CHECK-GI-NEXT:    lsl x14, x8, x9
-; CHECK-GI-NEXT:    lsr x13, x8, x13
-; CHECK-GI-NEXT:    lsl x12, x8, x12
-; CHECK-GI-NEXT:    sub x10, x10, x9
-; CHECK-GI-NEXT:    cmp x9, #64
-; CHECK-GI-NEXT:    sub x15, x9, #128
-; CHECK-GI-NEXT:    lsr x16, x8, x10
-; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
-; CHECK-GI-NEXT:    csel x12, x13, x12, lo
-; CHECK-GI-NEXT:    cmp x9, #0
-; CHECK-GI-NEXT:    sub x13, x15, #64
-; CHECK-GI-NEXT:    csel x12, xzr, x12, eq
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    sub x11, x11, x15
-; CHECK-GI-NEXT:    csel x16, x16, xzr, lo
-; CHECK-GI-NEXT:    cmp x10, #0
-; CHECK-GI-NEXT:    lsl x10, x8, x15
-; CHECK-GI-NEXT:    lsr x11, x8, x11
-; CHECK-GI-NEXT:    lsl x13, x8, x13
-; CHECK-GI-NEXT:    csel x8, x8, x16, eq
-; CHECK-GI-NEXT:    cmp x15, #64
-; CHECK-GI-NEXT:    csel x10, x10, xzr, lo
-; CHECK-GI-NEXT:    csel x11, x11, x13, lo
-; CHECK-GI-NEXT:    cmp x15, #0
-; CHECK-GI-NEXT:    csel x11, xzr, x11, eq
-; CHECK-GI-NEXT:    cmp x9, #128
-; CHECK-GI-NEXT:    csel x0, x14, xzr, lo
-; CHECK-GI-NEXT:    csel x1, x12, xzr, lo
-; CHECK-GI-NEXT:    csel x8, x8, x10, lo
-; CHECK-GI-NEXT:    csel x10, xzr, x11, lo
-; CHECK-GI-NEXT:    cmp x9, #0
-; CHECK-GI-NEXT:    csel x2, xzr, x8, eq
-; CHECK-GI-NEXT:    csel x3, xzr, x10, eq
-; CHECK-GI-NEXT:  .LBB9_8: // %fp-to-i-cleanup
-; CHECK-GI-NEXT:    ret
-; CHECK-GI-NEXT:  .LBB9_9:
-; CHECK-GI-NEXT:    mov x0, #-1 // =0xffffffffffffffff
-; CHECK-GI-NEXT:    mov x1, #-1 // =0xffffffffffffffff
-; CHECK-GI-NEXT:    mov x2, #-1 // =0xffffffffffffffff
-; CHECK-GI-NEXT:    mov x3, #-1 // =0xffffffffffffffff
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: f32_to_u256_sat:
+; CHECK:       // %bb.0: // %fp-to-i-entry
+; CHECK-NEXT:    fmov w10, s0
+; CHECK-NEXT:    mov w9, #127 // =0x7f
+; CHECK-NEXT:    cmp w10, #0
+; CHECK-NEXT:    ubfx w8, w10, #23, #8
+; CHECK-NEXT:    fccmp s0, s0, #1, pl
+; CHECK-NEXT:    ccmp w8, w9, #0, vc
+; CHECK-NEXT:    b.hs .LBB9_2
+; CHECK-NEXT:  // %bb.1:
+; CHECK-NEXT:    mov x0, xzr
+; CHECK-NEXT:    mov x1, xzr
+; CHECK-NEXT:    mov x2, xzr
+; CHECK-NEXT:    mov x3, xzr
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB9_2: // %fp-to-i-if-check.saturate
+; CHECK-NEXT:    cmp w8, #254
+; CHECK-NEXT:    b.hi .LBB9_6
+; CHECK-NEXT:  // %bb.3: // %fp-to-i-if-check.exp.size
+; CHECK-NEXT:    mov w9, #8388608 // =0x800000
+; CHECK-NEXT:    cmp w8, #149
+; CHECK-NEXT:    bfxil w9, w10, #0, #23
+; CHECK-NEXT:    b.hi .LBB9_5
+; CHECK-NEXT:  // %bb.4: // %fp-to-i-if-exp.small
+; CHECK-NEXT:    mov w10, #150 // =0x96
+; CHECK-NEXT:    mov x1, xzr
+; CHECK-NEXT:    mov x2, xzr
+; CHECK-NEXT:    sub w8, w10, w8
+; CHECK-NEXT:    mov x3, xzr
+; CHECK-NEXT:    lsr w0, w9, w8
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB9_5: // %fp-to-i-if-exp.large
+; CHECK-NEXT:    sub sp, sp, #64
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-NEXT:    movi v0.2d, #0000000000000000
+; CHECK-NEXT:    sub w8, w8, #150
+; CHECK-NEXT:    str x9, [sp, #32]
+; CHECK-NEXT:    lsr x9, x8, #3
+; CHECK-NEXT:    mov x10, sp
+; CHECK-NEXT:    str xzr, [sp, #56]
+; CHECK-NEXT:    add x10, x10, #32
+; CHECK-NEXT:    and x13, x8, #0x3f
+; CHECK-NEXT:    mvn w17, w8
+; CHECK-NEXT:    and x9, x9, #0x18
+; CHECK-NEXT:    eor x13, x13, #0x3f
+; CHECK-NEXT:    stur q0, [sp, #40]
+; CHECK-NEXT:    sub x9, x10, x9
+; CHECK-NEXT:    stp q0, q0, [sp]
+; CHECK-NEXT:    ldp x11, x10, [x9, #8]
+; CHECK-NEXT:    ldr x12, [x9]
+; CHECK-NEXT:    ldr x9, [x9, #24]
+; CHECK-NEXT:    lsr x16, x12, #1
+; CHECK-NEXT:    lsl x0, x12, x8
+; CHECK-NEXT:    lsr x14, x10, #1
+; CHECK-NEXT:    lsr x15, x11, #1
+; CHECK-NEXT:    lsl x9, x9, x8
+; CHECK-NEXT:    lsl x10, x10, x8
+; CHECK-NEXT:    lsl x11, x11, x8
+; CHECK-NEXT:    lsr x15, x15, x17
+; CHECK-NEXT:    lsr x14, x14, x13
+; CHECK-NEXT:    lsr x13, x16, x13
+; CHECK-NEXT:    orr x3, x9, x14
+; CHECK-NEXT:    orr x2, x10, x15
+; CHECK-NEXT:    orr x1, x11, x13
+; CHECK-NEXT:    add sp, sp, #64
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB9_6:
+; CHECK-NEXT:    mov x0, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    mov x1, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    mov x2, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    mov x3, #-1 // =0xffffffffffffffff
+; CHECK-NEXT:    ret
   %result = call i256 @llvm.fptoui.sat(float %val)
   ret i256 %result
 }
diff --git a/llvm/test/CodeGen/AArch64/frem-power2.ll b/llvm/test/CodeGen/AArch64/frem-power2.ll
index 548079dc5c4aa..7314ee72e8d20 100644
--- a/llvm/test/CodeGen/AArch64/frem-power2.ll
+++ b/llvm/test/CodeGen/AArch64/frem-power2.ll
@@ -665,9 +665,8 @@ define float @frem2_const_sitofp(float %x, i32 %sa) {
 ; CHECK-GI-LABEL: frem2_const_sitofp:
 ; CHECK-GI:       // %bb.0: // %entry
 ; CHECK-GI-NEXT:    mov w8, #1 // =0x1
-; CHECK-GI-NEXT:    and w9, w0, #0x1f
 ; CHECK-GI-NEXT:    fmov s0, #12.50000000
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w0
 ; CHECK-GI-NEXT:    scvtf s1, w8
 ; CHECK-GI-NEXT:    b fmodf
 entry:
@@ -695,9 +694,8 @@ define float @frem2_constneg_sitofp(float %x, i32 %sa) {
 ; CHECK-GI-LABEL: frem2_constneg_sitofp:
 ; CHECK-GI:       // %bb.0: // %entry
 ; CHECK-GI-NEXT:    mov w8, #1 // =0x1
-; CHECK-GI-NEXT:    and w9, w0, #0x1f
 ; CHECK-GI-NEXT:    fmov s0, #-12.50000000
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w0
 ; CHECK-GI-NEXT:    scvtf s1, w8
 ; CHECK-GI-NEXT:    b fmodf
 entry:
diff --git a/llvm/test/CodeGen/AArch64/fsh.ll b/llvm/test/CodeGen/AArch64/fsh.ll
index 312010904cf50..a3af83353692d 100644
--- a/llvm/test/CodeGen/AArch64/fsh.ll
+++ b/llvm/test/CodeGen/AArch64/fsh.ll
@@ -385,25 +385,14 @@ entry:
 }
 
 define i32 @fshl_i32(i32 %a, i32 %b, i32 %c) {
-; CHECK-SD-LABEL: fshl_i32:
-; CHECK-SD:       // %bb.0: // %entry
-; CHECK-SD-NEXT:    lsr w8, w1, #1
-; CHECK-SD-NEXT:    mvn w9, w2
-; CHECK-SD-NEXT:    lsl w10, w0, w2
-; CHECK-SD-NEXT:    lsr w8, w8, w9
-; CHECK-SD-NEXT:    orr w0, w10, w8
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: fshl_i32:
-; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    lsr w9, w1, #1
-; CHECK-GI-NEXT:    and w10, w2, #0x1f
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsl w10, w0, w10
-; CHECK-GI-NEXT:    lsr w8, w9, w8
-; CHECK-GI-NEXT:    orr w0, w10, w8
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: fshl_i32:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    lsr w8, w1, #1
+; CHECK-NEXT:    mvn w9, w2
+; CHECK-NEXT:    lsl w10, w0, w2
+; CHECK-NEXT:    lsr w8, w8, w9
+; CHECK-NEXT:    orr w0, w10, w8
+; CHECK-NEXT:    ret
 entry:
   %d = call i32 @llvm.fshl(i32 %a, i32 %b, i32 %c)
   ret i32 %d
@@ -421,12 +410,10 @@ define i32 @fshr_i32(i32 %a, i32 %b, i32 %c) {
 ;
 ; CHECK-GI-LABEL: fshr_i32:
 ; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    lsl w9, w0, #1
-; CHECK-GI-NEXT:    and w10, w2, #0x1f
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsl w8, w9, w8
-; CHECK-GI-NEXT:    lsr w9, w1, w10
+; CHECK-GI-NEXT:    lsl w8, w0, #1
+; CHECK-GI-NEXT:    mvn w9, w2
+; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsr w9, w1, w2
 ; CHECK-GI-NEXT:    orr w0, w8, w9
 ; CHECK-GI-NEXT:    ret
 entry:
diff --git a/llvm/test/CodeGen/AArch64/funnel-shift.ll b/llvm/test/CodeGen/AArch64/funnel-shift.ll
index c4e4d3c7dcd2b..8bc8fefc2aeb8 100644
--- a/llvm/test/CodeGen/AArch64/funnel-shift.ll
+++ b/llvm/test/CodeGen/AArch64/funnel-shift.ll
@@ -18,25 +18,14 @@ declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
 ; General case - all operands can be variables.
 
 define i32 @fshl_i32(i32 %x, i32 %y, i32 %z) {
-; CHECK-SD-LABEL: fshl_i32:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    lsr w8, w1, #1
-; CHECK-SD-NEXT:    mvn w9, w2
-; CHECK-SD-NEXT:    lsl w10, w0, w2
-; CHECK-SD-NEXT:    lsr w8, w8, w9
-; CHECK-SD-NEXT:    orr w0, w10, w8
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: fshl_i32:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    lsr w9, w1, #1
-; CHECK-GI-NEXT:    and w10, w2, #0x1f
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsl w10, w0, w10
-; CHECK-GI-NEXT:    lsr w8, w9, w8
-; CHECK-GI-NEXT:    orr w0, w10, w8
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: fshl_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsr w8, w1, #1
+; CHECK-NEXT:    mvn w9, w2
+; CHECK-NEXT:    lsl w10, w0, w2
+; CHECK-NEXT:    lsr w8, w8, w9
+; CHECK-NEXT:    orr w0, w10, w8
+; CHECK-NEXT:    ret
   %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %z)
   ret i32 %f
 }
@@ -300,12 +289,10 @@ define i32 @fshr_i32(i32 %x, i32 %y, i32 %z) {
 ;
 ; CHECK-GI-LABEL: fshr_i32:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    lsl w9, w0, #1
-; CHECK-GI-NEXT:    and w10, w2, #0x1f
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsl w8, w9, w8
-; CHECK-GI-NEXT:    lsr w9, w1, w10
+; CHECK-GI-NEXT:    lsl w8, w0, #1
+; CHECK-GI-NEXT:    mvn w9, w2
+; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsr w9, w1, w2
 ; CHECK-GI-NEXT:    orr w0, w8, w9
 ; CHECK-GI-NEXT:    ret
   %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %z)
@@ -551,14 +538,12 @@ define i32 @or_shl_fshl(i32 %x, i32 %y, i32 %s) {
 ;
 ; CHECK-GI-LABEL: or_shl_fshl:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    and w9, w2, #0x1f
-; CHECK-GI-NEXT:    lsr w10, w1, #1
-; CHECK-GI-NEXT:    lsl w11, w1, w2
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsl w9, w0, w9
-; CHECK-GI-NEXT:    lsr w8, w10, w8
-; CHECK-GI-NEXT:    orr w9, w9, w11
+; CHECK-GI-NEXT:    lsr w8, w1, #1
+; CHECK-GI-NEXT:    lsl w9, w1, w2
+; CHECK-GI-NEXT:    mvn w10, w2
+; CHECK-GI-NEXT:    lsl w11, w0, w2
+; CHECK-GI-NEXT:    lsr w8, w8, w10
+; CHECK-GI-NEXT:    orr w9, w11, w9
 ; CHECK-GI-NEXT:    orr w0, w9, w8
 ; CHECK-GI-NEXT:    ret
   %shy = shl i32 %y, %s
@@ -594,14 +579,12 @@ define i32 @or_shl_fshl_commute(i32 %x, i32 %y, i32 %s) {
 ;
 ; CHECK-GI-LABEL: or_shl_fshl_commute:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    and w9, w2, #0x1f
-; CHECK-GI-NEXT:    lsr w10, w1, #1
-; CHECK-GI-NEXT:    lsl w11, w1, w2
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsl w9, w0, w9
-; CHECK-GI-NEXT:    lsr w8, w10, w8
-; CHECK-GI-NEXT:    orr w9, w11, w9
+; CHECK-GI-NEXT:    lsr w8, w1, #1
+; CHECK-GI-NEXT:    lsl w9, w1, w2
+; CHECK-GI-NEXT:    mvn w10, w2
+; CHECK-GI-NEXT:    lsl w11, w0, w2
+; CHECK-GI-NEXT:    lsr w8, w8, w10
+; CHECK-GI-NEXT:    orr w9, w9, w11
 ; CHECK-GI-NEXT:    orr w0, w9, w8
 ; CHECK-GI-NEXT:    ret
   %shy = shl i32 %y, %s
@@ -637,14 +620,12 @@ define i32 @or_lshr_fshr(i32 %x, i32 %y, i32 %s) {
 ;
 ; CHECK-GI-LABEL: or_lshr_fshr:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    and w9, w2, #0x1f
-; CHECK-GI-NEXT:    lsl w10, w1, #1
-; CHECK-GI-NEXT:    lsr w11, w1, w2
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsr w9, w0, w9
-; CHECK-GI-NEXT:    lsl w8, w10, w8
-; CHECK-GI-NEXT:    orr w9, w9, w11
+; CHECK-GI-NEXT:    lsl w8, w1, #1
+; CHECK-GI-NEXT:    lsr w9, w1, w2
+; CHECK-GI-NEXT:    mvn w10, w2
+; CHECK-GI-NEXT:    lsr w11, w0, w2
+; CHECK-GI-NEXT:    lsl w8, w8, w10
+; CHECK-GI-NEXT:    orr w9, w11, w9
 ; CHECK-GI-NEXT:    orr w0, w8, w9
 ; CHECK-GI-NEXT:    ret
   %shy = lshr i32 %y, %s
@@ -679,14 +660,12 @@ define i32 @or_lshr_fshr_commute(i32 %x, i32 %y, i32 %s) {
 ;
 ; CHECK-GI-LABEL: or_lshr_fshr_commute:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    and w9, w2, #0x1f
-; CHECK-GI-NEXT:    lsl w10, w1, #1
-; CHECK-GI-NEXT:    lsr w11, w1, w2
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsr w9, w0, w9
-; CHECK-GI-NEXT:    lsl w8, w10, w8
-; CHECK-GI-NEXT:    orr w9, w11, w9
+; CHECK-GI-NEXT:    lsl w8, w1, #1
+; CHECK-GI-NEXT:    lsr w9, w1, w2
+; CHECK-GI-NEXT:    mvn w10, w2
+; CHECK-GI-NEXT:    lsr w11, w0, w2
+; CHECK-GI-NEXT:    lsl w8, w8, w10
+; CHECK-GI-NEXT:    orr w9, w9, w11
 ; CHECK-GI-NEXT:    orr w0, w9, w8
 ; CHECK-GI-NEXT:    ret
   %shy = lshr i32 %y, %s
@@ -709,25 +688,14 @@ define i32 @or_lshr_rotr_commute(i32 %x, i32 %y, i32 %s) {
 }
 
 define i32 @or_shl_fshl_simplify(i32 %x, i32 %y, i32 %s) {
-; CHECK-SD-LABEL: or_shl_fshl_simplify:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    lsr w8, w0, #1
-; CHECK-SD-NEXT:    mvn w9, w2
-; CHECK-SD-NEXT:    lsl w10, w1, w2
-; CHECK-SD-NEXT:    lsr w8, w8, w9
-; CHECK-SD-NEXT:    orr w0, w10, w8
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: or_shl_fshl_simplify:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    lsr w9, w0, #1
-; CHECK-GI-NEXT:    and w10, w2, #0x1f
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsl w10, w1, w10
-; CHECK-GI-NEXT:    lsr w8, w9, w8
-; CHECK-GI-NEXT:    orr w0, w10, w8
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: or_shl_fshl_simplify:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsr w8, w0, #1
+; CHECK-NEXT:    mvn w9, w2
+; CHECK-NEXT:    lsl w10, w1, w2
+; CHECK-NEXT:    lsr w8, w8, w9
+; CHECK-NEXT:    orr w0, w10, w8
+; CHECK-NEXT:    ret
   %shy = shl i32 %y, %s
   %fun = call i32 @llvm.fshl.i32(i32 %y, i32 %x, i32 %s)
   %or = or i32 %fun, %shy
@@ -746,12 +714,10 @@ define i32 @or_lshr_fshr_simplify(i32 %x, i32 %y, i32 %s) {
 ;
 ; CHECK-GI-LABEL: or_lshr_fshr_simplify:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #31 // =0x1f
-; CHECK-GI-NEXT:    lsl w9, w0, #1
-; CHECK-GI-NEXT:    and w10, w2, #0x1f
-; CHECK-GI-NEXT:    bic w8, w8, w2
-; CHECK-GI-NEXT:    lsl w8, w9, w8
-; CHECK-GI-NEXT:    lsr w9, w1, w10
+; CHECK-GI-NEXT:    lsl w8, w0, #1
+; CHECK-GI-NEXT:    mvn w9, w2
+; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsr w9, w1, w2
 ; CHECK-GI-NEXT:    orr w0, w8, w9
 ; CHECK-GI-NEXT:    ret
   %shy = lshr i32 %y, %s
diff --git a/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll b/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll
index 7d8ff9ac11e30..78efedb0c9317 100644
--- a/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll
+++ b/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-lshr-in-eqcmp-zero.ll
@@ -24,8 +24,7 @@ define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_signbit_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #128 // =0x80
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsr w8, w8, w9
+; CHECK-GI-NEXT:    lsr w8, w8, w1
 ; CHECK-GI-NEXT:    tst w8, w0
 ; CHECK-GI-NEXT:    cset w0, eq
 ; CHECK-GI-NEXT:    ret
@@ -46,8 +45,7 @@ define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_lowestbit_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #1 // =0x1
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsr w8, w8, w9
+; CHECK-GI-NEXT:    lsr w8, w8, w1
 ; CHECK-GI-NEXT:    tst w8, w0
 ; CHECK-GI-NEXT:    cset w0, eq
 ; CHECK-GI-NEXT:    ret
@@ -68,8 +66,7 @@ define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_bitsinmiddle_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #24 // =0x18
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsr w8, w8, w9
+; CHECK-GI-NEXT:    lsr w8, w8, w1
 ; CHECK-GI-NEXT:    tst w8, w0
 ; CHECK-GI-NEXT:    cset w0, eq
 ; CHECK-GI-NEXT:    ret
@@ -92,8 +89,7 @@ define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i16_signbit_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #32768 // =0x8000
-; CHECK-GI-NEXT:    and w9, w1, #0xffff
-; CHECK-GI-NEXT:    lsr w8, w8, w9
+; CHECK-GI-NEXT:    lsr w8, w8, w1
 ; CHECK-GI-NEXT:    tst w8, w0
 ; CHECK-GI-NEXT:    cset w0, eq
 ; CHECK-GI-NEXT:    ret
@@ -114,8 +110,7 @@ define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i16_lowestbit_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #1 // =0x1
-; CHECK-GI-NEXT:    and w9, w1, #0xffff
-; CHECK-GI-NEXT:    lsr w8, w8, w9
+; CHECK-GI-NEXT:    lsr w8, w8, w1
 ; CHECK-GI-NEXT:    tst w8, w0
 ; CHECK-GI-NEXT:    cset w0, eq
 ; CHECK-GI-NEXT:    ret
@@ -136,8 +131,7 @@ define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i16_bitsinmiddle_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #4080 // =0xff0
-; CHECK-GI-NEXT:    and w9, w1, #0xffff
-; CHECK-GI-NEXT:    lsr w8, w8, w9
+; CHECK-GI-NEXT:    lsr w8, w8, w1
 ; CHECK-GI-NEXT:    tst w8, w0
 ; CHECK-GI-NEXT:    cset w0, eq
 ; CHECK-GI-NEXT:    ret
@@ -425,8 +419,7 @@ define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_signbit_ne:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #128 // =0x80
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsr w8, w8, w9
+; CHECK-GI-NEXT:    lsr w8, w8, w1
 ; CHECK-GI-NEXT:    tst w8, w0
 ; CHECK-GI-NEXT:    cset w0, ne
 ; CHECK-GI-NEXT:    ret
@@ -480,24 +473,14 @@ define i1 @scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
 }
 
 define i1 @scalar_i8_signbit_eq_with_nonzero(i8 %x, i8 %y) nounwind {
-; CHECK-SD-LABEL: scalar_i8_signbit_eq_with_nonzero:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    mov w8, #128 // =0x80
-; CHECK-SD-NEXT:    lsr w8, w8, w1
-; CHECK-SD-NEXT:    and w8, w8, w0
-; CHECK-SD-NEXT:    cmp w8, #1
-; CHECK-SD-NEXT:    cset w0, eq
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: scalar_i8_signbit_eq_with_nonzero:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #128 // =0x80
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsr w8, w8, w9
-; CHECK-GI-NEXT:    and w8, w8, w0
-; CHECK-GI-NEXT:    cmp w8, #1
-; CHECK-GI-NEXT:    cset w0, eq
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: scalar_i8_signbit_eq_with_nonzero:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov w8, #128 // =0x80
+; CHECK-NEXT:    lsr w8, w8, w1
+; CHECK-NEXT:    and w8, w8, w0
+; CHECK-NEXT:    cmp w8, #1
+; CHECK-NEXT:    cset w0, eq
+; CHECK-NEXT:    ret
   %t0 = lshr i8 128, %y
   %t1 = and i8 %t0, %x
   %res = icmp eq i8 %t1, 1 ; should be comparing with 0
diff --git a/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-shl-in-eqcmp-zero.ll b/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-shl-in-eqcmp-zero.ll
index f61e4303ca2be..b55efeb580ee7 100644
--- a/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-shl-in-eqcmp-zero.ll
+++ b/llvm/test/CodeGen/AArch64/hoist-and-by-const-from-shl-in-eqcmp-zero.ll
@@ -25,8 +25,7 @@ define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_signbit_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #-128 // =0xffffff80
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w1
 ; CHECK-GI-NEXT:    and w8, w8, w0
 ; CHECK-GI-NEXT:    tst w8, #0xff
 ; CHECK-GI-NEXT:    cset w0, eq
@@ -49,8 +48,7 @@ define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_lowestbit_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #1 // =0x1
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w1
 ; CHECK-GI-NEXT:    and w8, w8, w0
 ; CHECK-GI-NEXT:    tst w8, #0xff
 ; CHECK-GI-NEXT:    cset w0, eq
@@ -73,8 +71,7 @@ define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_bitsinmiddle_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #24 // =0x18
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w1
 ; CHECK-GI-NEXT:    and w8, w8, w0
 ; CHECK-GI-NEXT:    tst w8, #0xff
 ; CHECK-GI-NEXT:    cset w0, eq
@@ -99,8 +96,7 @@ define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i16_signbit_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #-32768 // =0xffff8000
-; CHECK-GI-NEXT:    and w9, w1, #0xffff
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w1
 ; CHECK-GI-NEXT:    and w8, w8, w0
 ; CHECK-GI-NEXT:    tst w8, #0xffff
 ; CHECK-GI-NEXT:    cset w0, eq
@@ -123,8 +119,7 @@ define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i16_lowestbit_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #1 // =0x1
-; CHECK-GI-NEXT:    and w9, w1, #0xffff
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w1
 ; CHECK-GI-NEXT:    and w8, w8, w0
 ; CHECK-GI-NEXT:    tst w8, #0xffff
 ; CHECK-GI-NEXT:    cset w0, eq
@@ -147,8 +142,7 @@ define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i16_bitsinmiddle_eq:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #4080 // =0xff0
-; CHECK-GI-NEXT:    and w9, w1, #0xffff
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w1
 ; CHECK-GI-NEXT:    and w8, w8, w0
 ; CHECK-GI-NEXT:    tst w8, #0xffff
 ; CHECK-GI-NEXT:    cset w0, eq
@@ -430,8 +424,7 @@ define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_signbit_ne:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #-128 // =0xffffff80
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w1
 ; CHECK-GI-NEXT:    and w8, w8, w0
 ; CHECK-GI-NEXT:    tst w8, #0xff
 ; CHECK-GI-NEXT:    cset w0, ne
@@ -488,8 +481,7 @@ define i1 @scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
 ; CHECK-GI-LABEL: scalar_i8_bitsinmiddle_slt:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #24 // =0x18
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    lsl w8, w8, w9
+; CHECK-GI-NEXT:    lsl w8, w8, w1
 ; CHECK-GI-NEXT:    and w8, w8, w0
 ; CHECK-GI-NEXT:    sxtb w8, w8
 ; CHECK-GI-NEXT:    cmp w8, #0
diff --git a/llvm/test/CodeGen/AArch64/select_const.ll b/llvm/test/CodeGen/AArch64/select_const.ll
index daa9971dbcd58..c67d527dbfed1 100644
--- a/llvm/test/CodeGen/AArch64/select_const.ll
+++ b/llvm/test/CodeGen/AArch64/select_const.ll
@@ -672,7 +672,6 @@ define i8 @shl_constant_sel_constants(i1 %cond) {
 ; CHECK-GI-NEXT:    sbfx w9, w0, #0, #1
 ; CHECK-GI-NEXT:    mov w8, #1 // =0x1
 ; CHECK-GI-NEXT:    add w9, w9, #3
-; CHECK-GI-NEXT:    and w9, w9, #0xff
 ; CHECK-GI-NEXT:    lsl w0, w8, w9
 ; CHECK-GI-NEXT:    ret
   %sel = select i1 %cond, i8 2, i8 3
@@ -714,7 +713,6 @@ define i8 @lshr_constant_sel_constants(i1 %cond) {
 ; CHECK-GI-NEXT:    sbfx w9, w0, #0, #1
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
 ; CHECK-GI-NEXT:    add w9, w9, #3
-; CHECK-GI-NEXT:    and w9, w9, #0xff
 ; CHECK-GI-NEXT:    lsr w0, w8, w9
 ; CHECK-GI-NEXT:    ret
   %sel = select i1 %cond, i8 2, i8 3
@@ -747,7 +745,6 @@ define i8 @ashr_constant_sel_constants(i1 %cond) {
 ; CHECK-GI-NEXT:    sbfx w9, w0, #0, #1
 ; CHECK-GI-NEXT:    mov w8, #-128 // =0xffffff80
 ; CHECK-GI-NEXT:    add w9, w9, #3
-; CHECK-GI-NEXT:    and w9, w9, #0xff
 ; CHECK-GI-NEXT:    asr w0, w8, w9
 ; CHECK-GI-NEXT:    ret
   %sel = select i1 %cond, i8 2, i8 3
diff --git a/llvm/test/CodeGen/AArch64/shift-mod.ll b/llvm/test/CodeGen/AArch64/shift-mod.ll
index a235b3628ded5..5b74f9b7f9b50 100644
--- a/llvm/test/CodeGen/AArch64/shift-mod.ll
+++ b/llvm/test/CodeGen/AArch64/shift-mod.ll
@@ -54,8 +54,8 @@ define i64 @test3(i64 %x, i64 %y) {
 define i64 @test4(i64 %y, i32 %s) {
 ; CHECK-LABEL: test4:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    asr x0, x0, x1
+; CHECK-NEXT:    mov w8, w1
+; CHECK-NEXT:    asr x0, x0, x8
 ; CHECK-NEXT:    ret
 entry:
   %sh_prom = zext i32 %s to i64
@@ -67,7 +67,8 @@ define i64 @test5(i64 %y, i32 %s) {
 ; CHECK-LABEL: test5:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    asr x0, x0, x1
+; CHECK-NEXT:    sxtw x8, w1
+; CHECK-NEXT:    asr x0, x0, x8
 ; CHECK-NEXT:    ret
 entry:
   %sh_prom = sext i32 %s to i64
@@ -79,7 +80,8 @@ define i64 @test6(i64 %y, i32 %s) {
 ; CHECK-LABEL: test6:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
-; CHECK-NEXT:    lsl x0, x0, x1
+; CHECK-NEXT:    sxtw x8, w1
+; CHECK-NEXT:    lsl x0, x0, x8
 ; CHECK-NEXT:    ret
 entry:
   %sh_prom = sext i32 %s to i64
diff --git a/llvm/test/CodeGen/AArch64/shift.ll b/llvm/test/CodeGen/AArch64/shift.ll
index 5d7935474c903..eb5f56f771a0f 100644
--- a/llvm/test/CodeGen/AArch64/shift.ll
+++ b/llvm/test/CodeGen/AArch64/shift.ll
@@ -19,31 +19,19 @@ define i1 @shl_i1(i1 %0, i1 %1){
 }
 
 define i8 @shl_i8(i8 %0, i8 %1){
-; CHECK-SD-LABEL: shl_i8:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    lsl w0, w0, w1
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: shl_i8:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    and w8, w1, #0xff
-; CHECK-GI-NEXT:    lsl w0, w0, w8
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: shl_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsl w0, w0, w1
+; CHECK-NEXT:    ret
     %3 = shl i8 %0, %1
     ret i8 %3
 }
 
 define i16 @shl_i16(i16 %0, i16 %1){
-; CHECK-SD-LABEL: shl_i16:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    lsl w0, w0, w1
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: shl_i16:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    and w8, w1, #0xffff
-; CHECK-GI-NEXT:    lsl w0, w0, w8
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: shl_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsl w0, w0, w1
+; CHECK-NEXT:    ret
     %3 = shl i16 %0, %1
     ret i16 %3
 }
@@ -118,35 +106,21 @@ define i1 @ashr_i1(i1 %0, i1 %1){
 }
 
 define i8 @ashr_i8(i8 %0, i8 %1){
-; CHECK-SD-LABEL: ashr_i8:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    sxtb w8, w0
-; CHECK-SD-NEXT:    asr w0, w8, w1
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: ashr_i8:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    sxtb w8, w0
-; CHECK-GI-NEXT:    and w9, w1, #0xff
-; CHECK-GI-NEXT:    asr w0, w8, w9
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: ashr_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    sxtb w8, w0
+; CHECK-NEXT:    asr w0, w8, w1
+; CHECK-NEXT:    ret
     %3 = ashr i8 %0, %1
     ret i8 %3
 }
 
 define i16 @ashr_i16(i16 %0, i16 %1){
-; CHECK-SD-LABEL: ashr_i16:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    sxth w8, w0
-; CHECK-SD-NEXT:    asr w0, w8, w1
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: ashr_i16:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    sxth w8, w0
-; CHECK-GI-NEXT:    and w9, w1, #0xffff
-; CHECK-GI-NEXT:    asr w0, w8, w9
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: ashr_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    sxth w8, w0
+; CHECK-NEXT:    asr w0, w8, w1
+; CHECK-NEXT:    ret
     %3 = ashr i16 %0, %1
     ret i16 %3
 }
@@ -223,35 +197,21 @@ define i1 @lshr_i1(i1 %0, i1 %1){
 }
 
 define i8 @lshr_i8(i8 %0, i8 %1){
-; CHECK-SD-LABEL: lshr_i8:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    and w8, w0, #0xff
-; CHECK-SD-NEXT:    lsr w0, w8, w1
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: lshr_i8:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    and w8, w1, #0xff
-; CHECK-GI-NEXT:    and w9, w0, #0xff
-; CHECK-GI-NEXT:    lsr w0, w9, w8
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: lshr_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w0, #0xff
+; CHECK-NEXT:    lsr w0, w8, w1
+; CHECK-NEXT:    ret
     %3 = lshr i8 %0, %1
     ret i8 %3
 }
 
 define i16 @lshr_i16(i16 %0, i16 %1){
-; CHECK-SD-LABEL: lshr_i16:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    and w8, w0, #0xffff
-; CHECK-SD-NEXT:    lsr w0, w8, w1
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: lshr_i16:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    and w8, w1, #0xffff
-; CHECK-GI-NEXT:    and w9, w0, #0xffff
-; CHECK-GI-NEXT:    lsr w0, w9, w8
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: lshr_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w0, #0xffff
+; CHECK-NEXT:    lsr w0, w8, w1
+; CHECK-NEXT:    ret
     %3 = lshr i16 %0, %1
     ret i16 %3
 }



More information about the llvm-commits mailing list