[llvm] [GlobalISel] [AArch64] Extend SelectShiftMask to handle ADD/SUB mod patterns (PR #225842)

Deepak Shirke via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 07:18:48 PDT 2026


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

>From 4046e2db2338825994022ee0af924effe126ce50 Mon Sep 17 00:00:00 2001
From: deepakshirkem <deepakshirke509 at gmail.com>
Date: Wed, 23 Sep 2026 22:09:29 +0530
Subject: [PATCH] AArch64: Skip ADD/SUB by multiple of shift size in
 SelectShiftMask

Extend SelectShiftMask ComplexPattern to also handle ADD/SUB where the
immediate operand is a multiple of the shift width. AArch64 shift
instructions only use the low log2(ShiftWidth) bits of the shift amount,
so shifting by X+N where N == 0 mod ShiftWidth is equivalent to shifting
by X alone.
---
 .../Target/AArch64/AArch64ISelDAGToDAG.cpp    |  14 +
 .../GISel/AArch64InstructionSelector.cpp      |  15 +
 .../test/CodeGen/AArch64/and-mask-variable.ll |  14 +-
 llvm/test/CodeGen/AArch64/fcvt-i256.ll        | 608 +++++++++---------
 llvm/test/CodeGen/AArch64/fsh.ll              | 584 ++++++++---------
 llvm/test/CodeGen/AArch64/funnel-shift.ll     |  54 +-
 llvm/test/CodeGen/AArch64/shift-mod.ll        |  45 +-
 llvm/test/CodeGen/AArch64/shift.ll            | 116 ++--
 8 files changed, 715 insertions(+), 735 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 81aa12190d8751..b3c8ca0532cc6a 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -789,6 +789,20 @@ bool AArch64DAGToDAGISel::SelectShiftMask(SDValue N, SDValue &ShAmt) {
       return true;
     }
   }
+  // If shifting by X+/-N where N == 0 mod ShiftWidth, then just shift by X
+  // to avoid the ADD/SUB. Only do this if the ADD/SUB has a single use, so
+  // we don't leave the ADD/SUB behind for other users.
+  if ((N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) &&
+      N.hasOneUse() &&
+      N.getValueType() == (ShiftWidth == 32 ? MVT::i32 : MVT::i64)) {
+    uint64_t Imm;
+    if (isIntImmediate(N.getOperand(1).getNode(), Imm) &&
+        (Imm % ShiftWidth == 0)) {
+      ShAmt = N.getOperand(0);
+      return true;
+    }
+  }
+
   return false;
 }
 
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 42f13bd114b26f..c794080a5ddb4d 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -7336,6 +7336,21 @@ AArch64InstructionSelector::selectShiftMask(MachineOperand &Root) const {
       ShAmtReg = AndSrcReg;
   }
 
+  // If shifting by X+/-N where N == 0 mod ShiftWidth, then just shift by X
+  // to avoid the ADD/SUB. Only do this if the ADD/SUB has a single use, so
+  // we don't leave the ADD/SUB behind for other users.
+  Register AddSrcReg;
+  int64_t AddImm;
+  if (MRI.hasOneUse(ShAmtReg) &&
+      (mi_match(ShAmtReg, MRI,
+                m_GAdd(m_Reg(AddSrcReg), m_ICstOrSplat(AddImm))) ||
+       mi_match(ShAmtReg, MRI,
+                m_GSub(m_Reg(AddSrcReg), m_ICstOrSplat(AddImm)))) &&
+      (AddImm % ShiftWidth == 0)) {
+    ShAmtReg = AddSrcReg;
+    return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}};
+  }
+
   // Only succeed if we changed the shift amount; otherwise let other
   // patterns (e.g. zext GPR32 -> SUBREG_TO_REG) match instead.
   if (ShAmtReg == Root.getReg())
diff --git a/llvm/test/CodeGen/AArch64/and-mask-variable.ll b/llvm/test/CodeGen/AArch64/and-mask-variable.ll
index f41cdc6dd241b2..ea5079770b2435 100644
--- a/llvm/test/CodeGen/AArch64/and-mask-variable.ll
+++ b/llvm/test/CodeGen/AArch64/and-mask-variable.ll
@@ -58,16 +58,14 @@ define i128 @mask_pair_128(i128 %x, i128 %y) {
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
 ; CHECK-GI-NEXT:    mov x9, #-1 // =0xffffffffffffffff
-; CHECK-GI-NEXT:    sub x10, x2, #64
-; CHECK-GI-NEXT:    sub x8, x8, x2
-; CHECK-GI-NEXT:    lsl x11, x9, x2
 ; CHECK-GI-NEXT:    cmp x2, #64
+; CHECK-GI-NEXT:    sub x8, x8, x2
+; CHECK-GI-NEXT:    lsl x10, x9, x2
 ; CHECK-GI-NEXT:    lsr x8, x9, x8
-; CHECK-GI-NEXT:    lsl x9, x9, x10
-; CHECK-GI-NEXT:    csel x10, x11, xzr, lo
-; CHECK-GI-NEXT:    orr x8, x8, x11
-; CHECK-GI-NEXT:    and x0, x10, x0
-; CHECK-GI-NEXT:    csel x8, x8, x9, lo
+; CHECK-GI-NEXT:    csel x9, x10, xzr, lo
+; CHECK-GI-NEXT:    orr x8, x8, x10
+; CHECK-GI-NEXT:    and x0, x9, x0
+; CHECK-GI-NEXT:    csel x8, x8, x10, lo
 ; CHECK-GI-NEXT:    cmp x2, #0
 ; CHECK-GI-NEXT:    csinv x8, x8, xzr, ne
 ; CHECK-GI-NEXT:    and x1, x8, x1
diff --git a/llvm/test/CodeGen/AArch64/fcvt-i256.ll b/llvm/test/CodeGen/AArch64/fcvt-i256.ll
index d7d9d041875064..accd667d0ee8cf 100644
--- a/llvm/test/CodeGen/AArch64/fcvt-i256.ll
+++ b/llvm/test/CodeGen/AArch64/fcvt-i256.ll
@@ -700,78 +700,75 @@ define i256 @f32_to_s256(float %val) {
 ; 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:    lsl x17, 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:    sub x14, 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:    csel x15, x15, x17, 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:    sub x13, x13, x14
+; CHECK-GI-NEXT:    csel x15, xzr, x15, eq
 ; CHECK-GI-NEXT:    cmp x12, #64
-; CHECK-GI-NEXT:    sub x13, x13, x17
+; CHECK-GI-NEXT:    lsl x17, x10, x14
+; CHECK-GI-NEXT:    lsr x13, x10, x13
 ; 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 x12, x10, x18, eq
+; CHECK-GI-NEXT:    cmp x14, #64
+; CHECK-GI-NEXT:    csel x18, x17, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x13, x17, lo
+; CHECK-GI-NEXT:    cmp x14, #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 x15, x15, xzr, lo
+; CHECK-GI-NEXT:    csel x12, x12, x18, 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:    umulh x17, 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:    umulh x11, x15, x9
+; CHECK-GI-NEXT:    umulh x18, x12, x8
+; CHECK-GI-NEXT:    umulh x14, x10, x8
+; CHECK-GI-NEXT:    add x11, x11, x17
 ; 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:    add x11, x18, x11
+; CHECK-GI-NEXT:    mul x0, x15, x8
+; CHECK-GI-NEXT:    umulh x2, x15, x8
+; CHECK-GI-NEXT:    adds x14, x14, x16
+; CHECK-GI-NEXT:    madd x11, x10, x9, x11
 ; 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:    adds x1, x14, x0
+; CHECK-GI-NEXT:    mul x18, x15, x9
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    adds x17, x2, x17
+; CHECK-GI-NEXT:    madd x11, x15, x9, x11
 ; 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:    adds x16, x17, x16
+; CHECK-GI-NEXT:    and x17, x0, #0x1
+; CHECK-GI-NEXT:    mul x15, x12, x8
+; CHECK-GI-NEXT:    madd x9, x12, x9, x11
+; CHECK-GI-NEXT:    and x11, x3, #0x1
+; CHECK-GI-NEXT:    and x12, x14, #0x1
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    and x14, x14, #0x1
 ; CHECK-GI-NEXT:    mul x0, x10, x8
-; CHECK-GI-NEXT:    add x10, x12, x14
+; CHECK-GI-NEXT:    add x10, x11, x12
+; CHECK-GI-NEXT:    adds x12, x16, x18
+; CHECK-GI-NEXT:    add x11, x17, x14
 ; CHECK-GI-NEXT:    cset w14, hs
-; CHECK-GI-NEXT:    adds x11, x11, x17
-; CHECK-GI-NEXT:    add x12, x16, x15
+; CHECK-GI-NEXT:    adds x12, x12, 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:    adds x2, x12, x10
+; CHECK-GI-NEXT:    add x9, x11, x9
 ; CHECK-GI-NEXT:    and x10, x13, #0x1
 ; CHECK-GI-NEXT:    cset w11, hs
 ; CHECK-GI-NEXT:    add x9, x9, x10
@@ -873,38 +870,35 @@ define i256 @f32_to_u256(float %val) {
 ; 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:    sub x12, x11, x9
+; CHECK-GI-NEXT:    lsl x13, x8, 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:    lsr 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:    lsr x15, x8, x10
+; CHECK-GI-NEXT:    csel x13, x13, xzr, lo
+; CHECK-GI-NEXT:    csel x12, x12, x14, lo
 ; CHECK-GI-NEXT:    cmp x9, #0
-; CHECK-GI-NEXT:    sub x13, x15, #64
+; CHECK-GI-NEXT:    sub x14, x9, #128
 ; 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:    sub x11, x11, x14
+; CHECK-GI-NEXT:    csel x15, x15, xzr, lo
 ; CHECK-GI-NEXT:    cmp x10, #0
-; CHECK-GI-NEXT:    lsl x10, x8, x15
+; CHECK-GI-NEXT:    lsl x10, x8, x14
 ; 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:    csel x8, x8, x15, eq
+; CHECK-GI-NEXT:    cmp x14, #64
+; CHECK-GI-NEXT:    csel x15, x10, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x11, x10, lo
+; CHECK-GI-NEXT:    cmp x14, #0
+; CHECK-GI-NEXT:    csel x10, xzr, x10, eq
 ; CHECK-GI-NEXT:    cmp x9, #128
-; CHECK-GI-NEXT:    csel x0, x14, xzr, lo
+; CHECK-GI-NEXT:    csel x0, x13, 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:    csel x8, x8, x15, lo
+; CHECK-GI-NEXT:    csel x10, xzr, x10, lo
 ; CHECK-GI-NEXT:    cmp x9, #0
 ; CHECK-GI-NEXT:    csel x2, xzr, x8, eq
 ; CHECK-GI-NEXT:    csel x3, xzr, x10, eq
@@ -1059,81 +1053,77 @@ define i256 @f64_to_s256(double %val) {
 ; 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:    mov w12, #64 // =0x40
+; CHECK-GI-NEXT:    mov w13, #128 // =0x80
+; CHECK-GI-NEXT:    sub x15, x12, x11
 ; CHECK-GI-NEXT:    lsl x16, x10, x11
+; CHECK-GI-NEXT:    sub x13, x13, 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:    sub x14, x11, #128
+; CHECK-GI-NEXT:    lsr x17, x10, x13
+; CHECK-GI-NEXT:    csel x18, x16, xzr, lo
+; CHECK-GI-NEXT:    sub x12, x12, x14
+; CHECK-GI-NEXT:    csel x15, x15, x16, 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:    lsl x16, x10, x14
+; CHECK-GI-NEXT:    csel x15, xzr, x15, eq
+; CHECK-GI-NEXT:    cmp x13, #64
+; CHECK-GI-NEXT:    lsr x12, x10, x12
+; CHECK-GI-NEXT:    csel x17, x17, xzr, lo
+; CHECK-GI-NEXT:    cmp x13, #0
+; CHECK-GI-NEXT:    csel x13, x10, x17, eq
+; CHECK-GI-NEXT:    cmp x14, #64
+; CHECK-GI-NEXT:    csel x17, x16, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x12, x16, lo
+; CHECK-GI-NEXT:    cmp x14, #0
+; CHECK-GI-NEXT:    csel x12, 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:    csel x10, x18, xzr, lo
+; CHECK-GI-NEXT:    csel x15, x15, xzr, lo
+; CHECK-GI-NEXT:    csel x13, x13, x17, lo
+; CHECK-GI-NEXT:    csel x12, xzr, x12, 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:    umulh x18, x10, x9
 ; 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:    csel x12, xzr, x12, eq
+; CHECK-GI-NEXT:    umulh x11, x15, x9
+; CHECK-GI-NEXT:    umulh x17, x13, x8
+; CHECK-GI-NEXT:    umulh x14, x10, x8
+; CHECK-GI-NEXT:    add x11, x11, x18
 ; 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:    add x11, x17, x11
+; CHECK-GI-NEXT:    mul x0, x15, x8
+; CHECK-GI-NEXT:    umulh x2, x15, x8
+; CHECK-GI-NEXT:    adds x14, x14, x16
+; CHECK-GI-NEXT:    madd x11, x10, x9, x11
 ; 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:    adds x1, x14, x0
+; CHECK-GI-NEXT:    mul x17, x15, x9
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    adds x18, x2, x18
+; CHECK-GI-NEXT:    madd x11, x15, x9, x11
 ; 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:    adds x16, x18, x16
+; CHECK-GI-NEXT:    and x18, x0, #0x1
+; CHECK-GI-NEXT:    mul x15, x13, x8
+; CHECK-GI-NEXT:    madd x9, x13, x9, x11
+; CHECK-GI-NEXT:    and x11, x3, #0x1
+; CHECK-GI-NEXT:    and x13, x14, #0x1
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    and x14, x14, #0x1
 ; CHECK-GI-NEXT:    mul x0, x10, x8
-; CHECK-GI-NEXT:    add x10, x12, x14
+; CHECK-GI-NEXT:    add x10, x11, x13
+; CHECK-GI-NEXT:    adds x13, x16, x17
+; CHECK-GI-NEXT:    add x11, x18, 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:    adds x13, x13, x15
+; CHECK-GI-NEXT:    madd x8, x12, 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 w12, hs
+; CHECK-GI-NEXT:    adds x2, x13, x10
+; CHECK-GI-NEXT:    add x9, x11, x9
+; CHECK-GI-NEXT:    and x10, x12, #0x1
 ; CHECK-GI-NEXT:    cset w11, hs
 ; CHECK-GI-NEXT:    add x9, x9, x10
 ; CHECK-GI-NEXT:    and x10, x11, #0x1
@@ -1232,40 +1222,36 @@ define i256 @f64_to_u256(double %val) {
 ; 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:    mov w10, #64 // =0x40
+; CHECK-GI-NEXT:    mov w11, #128 // =0x80
+; CHECK-GI-NEXT:    sub x12, x10, x9
+; CHECK-GI-NEXT:    lsl x13, x8, x9
+; CHECK-GI-NEXT:    sub x11, x11, x9
+; CHECK-GI-NEXT:    lsr x12, x8, x12
 ; 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:    lsr x14, x8, x11
+; CHECK-GI-NEXT:    csel x15, x13, xzr, lo
+; CHECK-GI-NEXT:    csel x12, x12, x13, lo
 ; CHECK-GI-NEXT:    cmp x9, #0
-; CHECK-GI-NEXT:    sub x13, x15, #64
+; CHECK-GI-NEXT:    sub x13, x9, #128
 ; 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 x11, #64
+; CHECK-GI-NEXT:    sub x10, x10, x13
+; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
+; CHECK-GI-NEXT:    cmp x11, #0
+; CHECK-GI-NEXT:    lsl x11, x8, x13
+; CHECK-GI-NEXT:    lsr x10, x8, x10
+; CHECK-GI-NEXT:    csel x8, x8, x14, eq
+; CHECK-GI-NEXT:    cmp x13, #64
+; CHECK-GI-NEXT:    csel x14, x11, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x10, x11, lo
+; CHECK-GI-NEXT:    cmp x13, #0
+; CHECK-GI-NEXT:    csel x10, xzr, x10, eq
 ; CHECK-GI-NEXT:    cmp x9, #128
-; CHECK-GI-NEXT:    csel x0, x14, xzr, lo
+; CHECK-GI-NEXT:    csel x0, x15, 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:    csel x8, x8, x14, lo
+; CHECK-GI-NEXT:    csel x10, xzr, x10, lo
 ; CHECK-GI-NEXT:    cmp x9, #0
 ; CHECK-GI-NEXT:    csel x2, xzr, x8, eq
 ; CHECK-GI-NEXT:    csel x3, xzr, x10, eq
@@ -1450,78 +1436,75 @@ define i256 @f32_to_s256_sat(float %val) {
 ; 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:    lsl x17, 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:    sub x14, 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:    csel x15, x15, x17, 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:    sub x13, x13, x14
+; CHECK-GI-NEXT:    csel x15, xzr, x15, eq
 ; CHECK-GI-NEXT:    cmp x12, #64
-; CHECK-GI-NEXT:    sub x13, x13, x17
+; CHECK-GI-NEXT:    lsl x17, x10, x14
+; CHECK-GI-NEXT:    lsr x13, x10, x13
 ; 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 x12, x10, x18, eq
+; CHECK-GI-NEXT:    cmp x14, #64
+; CHECK-GI-NEXT:    csel x18, x17, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x13, x17, lo
+; CHECK-GI-NEXT:    cmp x14, #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 x15, x15, xzr, lo
+; CHECK-GI-NEXT:    csel x12, x12, x18, 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:    umulh x17, 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:    umulh x11, x15, x9
+; CHECK-GI-NEXT:    umulh x18, x12, x8
+; CHECK-GI-NEXT:    umulh x14, x10, x8
+; CHECK-GI-NEXT:    add x11, x11, x17
 ; 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:    add x11, x18, x11
+; CHECK-GI-NEXT:    mul x0, x15, x8
+; CHECK-GI-NEXT:    umulh x2, x15, x8
+; CHECK-GI-NEXT:    adds x14, x14, x16
+; CHECK-GI-NEXT:    madd x11, x10, x9, x11
 ; 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:    adds x1, x14, x0
+; CHECK-GI-NEXT:    mul x18, x15, x9
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    adds x17, x2, x17
+; CHECK-GI-NEXT:    madd x11, x15, x9, x11
 ; 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:    adds x16, x17, x16
+; CHECK-GI-NEXT:    and x17, x0, #0x1
+; CHECK-GI-NEXT:    mul x15, x12, x8
+; CHECK-GI-NEXT:    madd x9, x12, x9, x11
+; CHECK-GI-NEXT:    and x11, x3, #0x1
+; CHECK-GI-NEXT:    and x12, x14, #0x1
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    and x14, x14, #0x1
 ; CHECK-GI-NEXT:    mul x0, x10, x8
-; CHECK-GI-NEXT:    add x10, x12, x14
+; CHECK-GI-NEXT:    add x10, x11, x12
+; CHECK-GI-NEXT:    adds x12, x16, x18
+; CHECK-GI-NEXT:    add x11, x17, x14
 ; CHECK-GI-NEXT:    cset w14, hs
-; CHECK-GI-NEXT:    adds x11, x11, x17
-; CHECK-GI-NEXT:    add x12, x16, x15
+; CHECK-GI-NEXT:    adds x12, x12, 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:    adds x2, x12, x10
+; CHECK-GI-NEXT:    add x9, x11, x9
 ; CHECK-GI-NEXT:    and x10, x13, #0x1
 ; CHECK-GI-NEXT:    cset w11, hs
 ; CHECK-GI-NEXT:    add x9, x9, x10
@@ -1659,38 +1642,35 @@ define i256 @f32_to_u256_sat(float %val) {
 ; 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:    sub x12, x11, x9
+; CHECK-GI-NEXT:    lsl x13, x8, 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:    lsr 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:    lsr x15, x8, x10
+; CHECK-GI-NEXT:    csel x13, x13, xzr, lo
+; CHECK-GI-NEXT:    csel x12, x12, x14, lo
 ; CHECK-GI-NEXT:    cmp x9, #0
-; CHECK-GI-NEXT:    sub x13, x15, #64
+; CHECK-GI-NEXT:    sub x14, x9, #128
 ; 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:    sub x11, x11, x14
+; CHECK-GI-NEXT:    csel x15, x15, xzr, lo
 ; CHECK-GI-NEXT:    cmp x10, #0
-; CHECK-GI-NEXT:    lsl x10, x8, x15
+; CHECK-GI-NEXT:    lsl x10, x8, x14
 ; 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:    csel x8, x8, x15, eq
+; CHECK-GI-NEXT:    cmp x14, #64
+; CHECK-GI-NEXT:    csel x15, x10, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x11, x10, lo
+; CHECK-GI-NEXT:    cmp x14, #0
+; CHECK-GI-NEXT:    csel x10, xzr, x10, eq
 ; CHECK-GI-NEXT:    cmp x9, #128
-; CHECK-GI-NEXT:    csel x0, x14, xzr, lo
+; CHECK-GI-NEXT:    csel x0, x13, 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:    csel x8, x8, x15, lo
+; CHECK-GI-NEXT:    csel x10, xzr, x10, lo
 ; CHECK-GI-NEXT:    cmp x9, #0
 ; CHECK-GI-NEXT:    csel x2, xzr, x8, eq
 ; CHECK-GI-NEXT:    csel x3, xzr, x10, eq
@@ -1875,81 +1855,77 @@ define i256 @f64_to_s256_sat(double %val) {
 ; CHECK-GI-NEXT:    ret
 ; CHECK-GI-NEXT:  .LBB10_6: // %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:    mov w12, #64 // =0x40
+; CHECK-GI-NEXT:    mov w13, #128 // =0x80
+; CHECK-GI-NEXT:    sub x15, x12, x11
 ; CHECK-GI-NEXT:    lsl x16, x10, x11
+; CHECK-GI-NEXT:    sub x13, x13, 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:    sub x14, x11, #128
+; CHECK-GI-NEXT:    lsr x17, x10, x13
+; CHECK-GI-NEXT:    csel x18, x16, xzr, lo
+; CHECK-GI-NEXT:    sub x12, x12, x14
+; CHECK-GI-NEXT:    csel x15, x15, x16, 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:    lsl x16, x10, x14
+; CHECK-GI-NEXT:    csel x15, xzr, x15, eq
+; CHECK-GI-NEXT:    cmp x13, #64
+; CHECK-GI-NEXT:    lsr x12, x10, x12
+; CHECK-GI-NEXT:    csel x17, x17, xzr, lo
+; CHECK-GI-NEXT:    cmp x13, #0
+; CHECK-GI-NEXT:    csel x13, x10, x17, eq
+; CHECK-GI-NEXT:    cmp x14, #64
+; CHECK-GI-NEXT:    csel x17, x16, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x12, x16, lo
+; CHECK-GI-NEXT:    cmp x14, #0
+; CHECK-GI-NEXT:    csel x12, 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:    csel x10, x18, xzr, lo
+; CHECK-GI-NEXT:    csel x15, x15, xzr, lo
+; CHECK-GI-NEXT:    csel x13, x13, x17, lo
+; CHECK-GI-NEXT:    csel x12, xzr, x12, 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:    umulh x18, x10, x9
 ; 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:    csel x12, xzr, x12, eq
+; CHECK-GI-NEXT:    umulh x11, x15, x9
+; CHECK-GI-NEXT:    umulh x17, x13, x8
+; CHECK-GI-NEXT:    umulh x14, x10, x8
+; CHECK-GI-NEXT:    add x11, x11, x18
 ; 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:    add x11, x17, x11
+; CHECK-GI-NEXT:    mul x0, x15, x8
+; CHECK-GI-NEXT:    umulh x2, x15, x8
+; CHECK-GI-NEXT:    adds x14, x14, x16
+; CHECK-GI-NEXT:    madd x11, x10, x9, x11
 ; 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:    adds x1, x14, x0
+; CHECK-GI-NEXT:    mul x17, x15, x9
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    adds x18, x2, x18
+; CHECK-GI-NEXT:    madd x11, x15, x9, x11
 ; 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:    adds x16, x18, x16
+; CHECK-GI-NEXT:    and x18, x0, #0x1
+; CHECK-GI-NEXT:    mul x15, x13, x8
+; CHECK-GI-NEXT:    madd x9, x13, x9, x11
+; CHECK-GI-NEXT:    and x11, x3, #0x1
+; CHECK-GI-NEXT:    and x13, x14, #0x1
+; CHECK-GI-NEXT:    cset w14, hs
+; CHECK-GI-NEXT:    and x14, x14, #0x1
 ; CHECK-GI-NEXT:    mul x0, x10, x8
-; CHECK-GI-NEXT:    add x10, x12, x14
+; CHECK-GI-NEXT:    add x10, x11, x13
+; CHECK-GI-NEXT:    adds x13, x16, x17
+; CHECK-GI-NEXT:    add x11, x18, 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:    adds x13, x13, x15
+; CHECK-GI-NEXT:    madd x8, x12, 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 w12, hs
+; CHECK-GI-NEXT:    adds x2, x13, x10
+; CHECK-GI-NEXT:    add x9, x11, x9
+; CHECK-GI-NEXT:    and x10, x12, #0x1
 ; CHECK-GI-NEXT:    cset w11, hs
 ; CHECK-GI-NEXT:    add x9, x9, x10
 ; CHECK-GI-NEXT:    and x10, x11, #0x1
@@ -2084,40 +2060,36 @@ define i256 @f64_to_u256_sat(double %val) {
 ; CHECK-GI-NEXT:    ret
 ; CHECK-GI-NEXT:  .LBB11_7: // %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:    mov w10, #64 // =0x40
+; CHECK-GI-NEXT:    mov w11, #128 // =0x80
+; CHECK-GI-NEXT:    sub x12, x10, x9
+; CHECK-GI-NEXT:    lsl x13, x8, x9
+; CHECK-GI-NEXT:    sub x11, x11, x9
+; CHECK-GI-NEXT:    lsr x12, x8, x12
 ; 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:    lsr x14, x8, x11
+; CHECK-GI-NEXT:    csel x15, x13, xzr, lo
+; CHECK-GI-NEXT:    csel x12, x12, x13, lo
 ; CHECK-GI-NEXT:    cmp x9, #0
-; CHECK-GI-NEXT:    sub x13, x15, #64
+; CHECK-GI-NEXT:    sub x13, x9, #128
 ; 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 x11, #64
+; CHECK-GI-NEXT:    sub x10, x10, x13
+; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
+; CHECK-GI-NEXT:    cmp x11, #0
+; CHECK-GI-NEXT:    lsl x11, x8, x13
+; CHECK-GI-NEXT:    lsr x10, x8, x10
+; CHECK-GI-NEXT:    csel x8, x8, x14, eq
+; CHECK-GI-NEXT:    cmp x13, #64
+; CHECK-GI-NEXT:    csel x14, x11, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x10, x11, lo
+; CHECK-GI-NEXT:    cmp x13, #0
+; CHECK-GI-NEXT:    csel x10, xzr, x10, eq
 ; CHECK-GI-NEXT:    cmp x9, #128
-; CHECK-GI-NEXT:    csel x0, x14, xzr, lo
+; CHECK-GI-NEXT:    csel x0, x15, 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:    csel x8, x8, x14, lo
+; CHECK-GI-NEXT:    csel x10, xzr, x10, lo
 ; CHECK-GI-NEXT:    cmp x9, #0
 ; CHECK-GI-NEXT:    csel x2, xzr, x8, eq
 ; CHECK-GI-NEXT:    csel x3, xzr, x10, eq
diff --git a/llvm/test/CodeGen/AArch64/fsh.ll b/llvm/test/CodeGen/AArch64/fsh.ll
index 81b21db4b8aeb0..d174817c7139f6 100644
--- a/llvm/test/CodeGen/AArch64/fsh.ll
+++ b/llvm/test/CodeGen/AArch64/fsh.ll
@@ -181,35 +181,33 @@ define i128 @rotl_i128(i128 %a, i128 %c) {
 ; CHECK-GI:       // %bb.0: // %entry
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
 ; CHECK-GI-NEXT:    and x9, x2, #0x7f
-; CHECK-GI-NEXT:    neg x10, x2
-; CHECK-GI-NEXT:    sub x12, x8, x9
-; CHECK-GI-NEXT:    lsl x13, x1, x2
-; CHECK-GI-NEXT:    sub x14, x9, #64
-; CHECK-GI-NEXT:    lsr x12, x0, x12
+; CHECK-GI-NEXT:    neg x11, x2
+; CHECK-GI-NEXT:    sub x10, x8, x9
+; CHECK-GI-NEXT:    lsl x12, x1, x2
+; CHECK-GI-NEXT:    lsl x13, x0, x9
+; CHECK-GI-NEXT:    lsr x10, x0, x10
 ; CHECK-GI-NEXT:    cmp x9, #64
-; CHECK-GI-NEXT:    and x9, x10, #0x7f
-; CHECK-GI-NEXT:    lsl x14, x0, x14
-; CHECK-GI-NEXT:    lsl x11, x0, x2
+; CHECK-GI-NEXT:    and x9, x11, #0x7f
 ; CHECK-GI-NEXT:    sub x8, x8, x9
-; CHECK-GI-NEXT:    orr x12, x12, x13
-; CHECK-GI-NEXT:    lsr x13, x0, x10
+; CHECK-GI-NEXT:    lsr x14, x1, x9
+; CHECK-GI-NEXT:    orr x10, x10, x12
+; CHECK-GI-NEXT:    lsl x12, x0, x2
 ; CHECK-GI-NEXT:    lsl x8, x1, x8
-; CHECK-GI-NEXT:    csel x12, x12, x14, lo
-; CHECK-GI-NEXT:    sub x14, x9, #64
-; CHECK-GI-NEXT:    csel x11, x11, xzr, lo
+; CHECK-GI-NEXT:    csel x10, x10, x13, lo
+; CHECK-GI-NEXT:    lsr x13, x0, x11
+; CHECK-GI-NEXT:    csel x12, x12, xzr, lo
 ; CHECK-GI-NEXT:    tst x2, #0x7f
-; CHECK-GI-NEXT:    lsr x14, x1, x14
+; CHECK-GI-NEXT:    csel x10, x1, x10, eq
 ; CHECK-GI-NEXT:    orr x8, x13, x8
-; CHECK-GI-NEXT:    csel x12, x1, x12, eq
 ; CHECK-GI-NEXT:    cmp x9, #64
-; CHECK-GI-NEXT:    lsr x13, x1, x10
+; CHECK-GI-NEXT:    lsr x13, x1, x11
 ; CHECK-GI-NEXT:    csel x8, x8, x14, lo
-; CHECK-GI-NEXT:    tst x10, #0x7f
+; CHECK-GI-NEXT:    tst x11, #0x7f
 ; CHECK-GI-NEXT:    csel x8, x0, x8, eq
 ; CHECK-GI-NEXT:    cmp x9, #64
 ; CHECK-GI-NEXT:    csel x9, x13, xzr, lo
-; CHECK-GI-NEXT:    orr x0, x11, x8
-; CHECK-GI-NEXT:    orr x1, x12, x9
+; CHECK-GI-NEXT:    orr x0, x12, x8
+; CHECK-GI-NEXT:    orr x1, x10, x9
 ; CHECK-GI-NEXT:    ret
 entry:
   %d = call i128 @llvm.fshl(i128 %a, i128 %a, i128 %c)
@@ -239,33 +237,31 @@ define i128 @rotr_i128(i128 %a, i128 %c) {
 ; CHECK-GI-NEXT:    and x9, x2, #0x7f
 ; CHECK-GI-NEXT:    lsr x11, x0, x2
 ; CHECK-GI-NEXT:    sub x10, x8, x9
-; CHECK-GI-NEXT:    sub x12, x9, #64
 ; CHECK-GI-NEXT:    neg x13, x2
+; CHECK-GI-NEXT:    lsr x12, x1, x9
 ; CHECK-GI-NEXT:    lsl x10, x1, x10
-; CHECK-GI-NEXT:    lsr x12, x1, x12
-; CHECK-GI-NEXT:    and x14, x13, #0x7f
 ; CHECK-GI-NEXT:    cmp x9, #64
-; CHECK-GI-NEXT:    sub x8, x8, x14
-; CHECK-GI-NEXT:    sub x15, x14, #64
+; CHECK-GI-NEXT:    lsl x14, x1, x13
 ; CHECK-GI-NEXT:    orr x10, x11, x10
-; CHECK-GI-NEXT:    lsr x11, x1, x2
-; CHECK-GI-NEXT:    lsr x8, x0, x8
+; CHECK-GI-NEXT:    and x11, x13, #0x7f
+; CHECK-GI-NEXT:    sub x8, x8, x11
 ; CHECK-GI-NEXT:    csel x10, x10, x12, lo
-; CHECK-GI-NEXT:    lsl x12, x1, x13
+; CHECK-GI-NEXT:    lsr x12, x1, x2
 ; CHECK-GI-NEXT:    tst x2, #0x7f
+; CHECK-GI-NEXT:    lsr x8, x0, x8
+; CHECK-GI-NEXT:    lsl x15, x0, x11
 ; CHECK-GI-NEXT:    csel x10, x0, x10, eq
 ; CHECK-GI-NEXT:    cmp x9, #64
 ; CHECK-GI-NEXT:    lsl x9, x0, x13
-; CHECK-GI-NEXT:    lsl x15, x0, x15
-; CHECK-GI-NEXT:    csel x11, x11, xzr, lo
-; CHECK-GI-NEXT:    orr x8, x8, x12
-; CHECK-GI-NEXT:    cmp x14, #64
+; CHECK-GI-NEXT:    csel x12, x12, xzr, lo
+; CHECK-GI-NEXT:    orr x8, x8, x14
+; CHECK-GI-NEXT:    cmp x11, #64
 ; CHECK-GI-NEXT:    csel x9, x9, xzr, lo
 ; CHECK-GI-NEXT:    csel x8, x8, x15, lo
 ; CHECK-GI-NEXT:    tst x13, #0x7f
 ; CHECK-GI-NEXT:    csel x8, x1, x8, eq
 ; CHECK-GI-NEXT:    orr x0, x10, x9
-; CHECK-GI-NEXT:    orr x1, x11, x8
+; CHECK-GI-NEXT:    orr x1, x12, x8
 ; CHECK-GI-NEXT:    ret
 entry:
   %d = call i128 @llvm.fshr(i128 %a, i128 %a, i128 %c)
@@ -487,40 +483,38 @@ define i128 @fshl_i128(i128 %a, i128 %b, i128 %c) {
 ;
 ; CHECK-GI-LABEL: fshl_i128:
 ; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    mov w8, #64 // =0x40
 ; CHECK-GI-NEXT:    and x9, x4, #0x7f
-; CHECK-GI-NEXT:    lsl x13, x1, x4
-; CHECK-GI-NEXT:    sub x12, x8, x9
-; CHECK-GI-NEXT:    mov w10, #127 // =0x7f
-; CHECK-GI-NEXT:    sub x15, x9, #64
+; CHECK-GI-NEXT:    mov w10, #64 // =0x40
+; CHECK-GI-NEXT:    mov w8, #127 // =0x7f
+; CHECK-GI-NEXT:    sub x12, x10, x9
+; CHECK-GI-NEXT:    bic x8, x8, x4
+; CHECK-GI-NEXT:    lsl x13, x0, x4
 ; CHECK-GI-NEXT:    lsr x12, x0, x12
-; CHECK-GI-NEXT:    bic x10, x10, x4
+; CHECK-GI-NEXT:    lsl x14, x1, x4
 ; CHECK-GI-NEXT:    extr x16, x3, x2, #1
-; CHECK-GI-NEXT:    cmp x9, #64
+; CHECK-GI-NEXT:    lsr x17, x3, #1
 ; CHECK-GI-NEXT:    mvn x11, x4
-; CHECK-GI-NEXT:    lsl x14, x0, x4
-; CHECK-GI-NEXT:    orr x9, x12, x13
-; CHECK-GI-NEXT:    lsr x12, x3, #1
-; CHECK-GI-NEXT:    lsl x13, x0, x15
-; CHECK-GI-NEXT:    sub x8, x8, x10
-; CHECK-GI-NEXT:    sub x15, x10, #64
-; CHECK-GI-NEXT:    lsr x17, x16, x11
-; CHECK-GI-NEXT:    lsl x8, x12, x8
-; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
-; CHECK-GI-NEXT:    csel x9, x9, x13, lo
+; CHECK-GI-NEXT:    lsl x15, x0, x9
+; CHECK-GI-NEXT:    cmp x9, #64
+; CHECK-GI-NEXT:    sub x9, x10, x8
+; CHECK-GI-NEXT:    orr x12, x12, x14
+; CHECK-GI-NEXT:    csel x10, x13, xzr, lo
+; CHECK-GI-NEXT:    lsr x13, x16, x11
+; CHECK-GI-NEXT:    lsl x9, x17, x9
+; CHECK-GI-NEXT:    csel x12, x12, x15, lo
 ; CHECK-GI-NEXT:    tst x4, #0x7f
-; CHECK-GI-NEXT:    lsr x13, x12, x15
-; CHECK-GI-NEXT:    lsr x12, x12, x11
-; CHECK-GI-NEXT:    csel x9, x1, x9, eq
-; CHECK-GI-NEXT:    orr x8, x17, x8
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    csel x8, x8, x13, lo
+; CHECK-GI-NEXT:    lsr x14, x17, x8
+; CHECK-GI-NEXT:    csel x12, x1, x12, eq
+; CHECK-GI-NEXT:    orr x9, x13, x9
+; CHECK-GI-NEXT:    cmp x8, #64
+; CHECK-GI-NEXT:    lsr x13, x17, x11
+; CHECK-GI-NEXT:    csel x9, x9, x14, lo
 ; CHECK-GI-NEXT:    tst x11, #0x7f
-; CHECK-GI-NEXT:    csel x8, x16, x8, eq
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    csel x10, x12, xzr, lo
-; CHECK-GI-NEXT:    orr x0, x14, x8
-; CHECK-GI-NEXT:    orr x1, x9, x10
+; CHECK-GI-NEXT:    csel x9, x16, x9, eq
+; CHECK-GI-NEXT:    cmp x8, #64
+; CHECK-GI-NEXT:    csel x8, x13, xzr, lo
+; CHECK-GI-NEXT:    orr x0, x10, x9
+; CHECK-GI-NEXT:    orr x1, x12, x8
 ; CHECK-GI-NEXT:    ret
 entry:
   %d = call i128 @llvm.fshl(i128 %a, i128 %b, i128 %c)
@@ -558,29 +552,27 @@ define i128 @fshr_i128(i128 %a, i128 %b, i128 %c) {
 ; CHECK-GI-NEXT:    and x15, x4, #0x7f
 ; CHECK-GI-NEXT:    lsr x13, x9, x13
 ; CHECK-GI-NEXT:    lsl x16, x9, x12
-; CHECK-GI-NEXT:    sub x17, x8, #64
+; CHECK-GI-NEXT:    lsl x9, x9, x8
 ; CHECK-GI-NEXT:    cmp x8, #64
-; CHECK-GI-NEXT:    lsl x8, x9, x17
-; CHECK-GI-NEXT:    sub x11, x11, x15
+; CHECK-GI-NEXT:    sub x8, x11, x15
 ; CHECK-GI-NEXT:    orr x13, x13, x14
-; CHECK-GI-NEXT:    csel x9, x16, xzr, lo
-; CHECK-GI-NEXT:    sub x14, x15, #64
-; CHECK-GI-NEXT:    lsr x16, x2, x4
-; CHECK-GI-NEXT:    lsl x11, x3, x11
-; CHECK-GI-NEXT:    csel x8, x13, x8, lo
+; CHECK-GI-NEXT:    lsr x14, x2, x4
+; CHECK-GI-NEXT:    lsl x8, x3, x8
+; CHECK-GI-NEXT:    csel x11, x16, xzr, lo
+; CHECK-GI-NEXT:    csel x9, x13, x9, lo
 ; CHECK-GI-NEXT:    tst x12, #0x7f
-; CHECK-GI-NEXT:    lsr x12, x3, x14
-; CHECK-GI-NEXT:    csel x8, x10, x8, eq
-; CHECK-GI-NEXT:    orr x10, x16, x11
+; CHECK-GI-NEXT:    lsr x12, x3, x15
+; CHECK-GI-NEXT:    csel x9, x10, x9, eq
+; CHECK-GI-NEXT:    orr x8, x14, x8
 ; CHECK-GI-NEXT:    cmp x15, #64
-; CHECK-GI-NEXT:    lsr x11, x3, x4
-; CHECK-GI-NEXT:    csel x10, x10, x12, lo
+; CHECK-GI-NEXT:    lsr x10, x3, x4
+; CHECK-GI-NEXT:    csel x8, x8, x12, lo
 ; CHECK-GI-NEXT:    tst x4, #0x7f
-; CHECK-GI-NEXT:    csel x10, x2, x10, eq
+; CHECK-GI-NEXT:    csel x8, x2, x8, eq
 ; CHECK-GI-NEXT:    cmp x15, #64
-; CHECK-GI-NEXT:    csel x11, x11, xzr, lo
-; CHECK-GI-NEXT:    orr x0, x9, x10
-; CHECK-GI-NEXT:    orr x1, x8, x11
+; CHECK-GI-NEXT:    csel x10, x10, xzr, lo
+; CHECK-GI-NEXT:    orr x0, x11, x8
+; CHECK-GI-NEXT:    orr x1, x9, x10
 ; CHECK-GI-NEXT:    ret
 entry:
   %d = call i128 @llvm.fshr(i128 %a, i128 %b, i128 %c)
@@ -1747,63 +1739,59 @@ define <2 x i128> @rotl_v2i128(<2 x i128> %a, <2 x i128> %c) {
 ; CHECK-GI-NEXT:    mov w9, #64 // =0x40
 ; CHECK-GI-NEXT:    lsl x11, x1, x4
 ; CHECK-GI-NEXT:    sub x10, x9, x8
-; CHECK-GI-NEXT:    sub x12, x8, #64
-; CHECK-GI-NEXT:    lsl x14, x0, x4
+; CHECK-GI-NEXT:    lsl x13, x0, x4
+; CHECK-GI-NEXT:    and x15, x6, #0x7f
 ; CHECK-GI-NEXT:    lsr x10, x0, x10
-; CHECK-GI-NEXT:    lsl x12, x0, x12
+; CHECK-GI-NEXT:    lsl x14, x0, x8
 ; CHECK-GI-NEXT:    cmp x8, #64
-; CHECK-GI-NEXT:    lsl x16, x2, x6
-; CHECK-GI-NEXT:    lsl x17, x3, x6
-; CHECK-GI-NEXT:    neg x13, x4
+; CHECK-GI-NEXT:    neg x12, x4
+; CHECK-GI-NEXT:    lsl x16, x2, x15
+; CHECK-GI-NEXT:    neg x17, x6
 ; CHECK-GI-NEXT:    orr x8, x10, x11
-; CHECK-GI-NEXT:    and x10, x6, #0x7f
-; CHECK-GI-NEXT:    csel x11, x14, xzr, lo
-; CHECK-GI-NEXT:    sub x14, x9, x10
-; CHECK-GI-NEXT:    csel x8, x8, x12, lo
+; CHECK-GI-NEXT:    sub x10, x9, x15
+; CHECK-GI-NEXT:    csel x11, x13, xzr, lo
+; CHECK-GI-NEXT:    lsr x10, x2, x10
+; CHECK-GI-NEXT:    lsl x13, x3, x6
+; CHECK-GI-NEXT:    csel x8, x8, x14, lo
 ; CHECK-GI-NEXT:    tst x4, #0x7f
-; CHECK-GI-NEXT:    sub x12, x10, #64
-; CHECK-GI-NEXT:    lsr x14, x2, x14
+; CHECK-GI-NEXT:    lsl x14, x2, x6
+; CHECK-GI-NEXT:    and x4, x17, #0x7f
+; CHECK-GI-NEXT:    orr x10, x10, x13
+; CHECK-GI-NEXT:    and x13, x12, #0x7f
 ; CHECK-GI-NEXT:    csel x8, x1, x8, eq
-; CHECK-GI-NEXT:    lsl x12, x2, x12
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    neg x15, x6
-; CHECK-GI-NEXT:    orr x10, x14, x17
-; CHECK-GI-NEXT:    csel x14, x16, xzr, lo
-; CHECK-GI-NEXT:    and x16, x13, #0x7f
-; CHECK-GI-NEXT:    csel x10, x10, x12, lo
-; CHECK-GI-NEXT:    sub x12, x9, x16
-; CHECK-GI-NEXT:    sub x17, x16, #64
-; CHECK-GI-NEXT:    lsr x18, x0, x13
-; CHECK-GI-NEXT:    lsl x12, x1, x12
+; CHECK-GI-NEXT:    cmp x15, #64
+; CHECK-GI-NEXT:    sub x15, x9, x13
+; CHECK-GI-NEXT:    lsr x18, x1, x13
+; CHECK-GI-NEXT:    csel x10, x10, x16, lo
+; CHECK-GI-NEXT:    lsr x16, x0, x12
+; CHECK-GI-NEXT:    lsl x15, x1, x15
+; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
 ; CHECK-GI-NEXT:    tst x6, #0x7f
-; CHECK-GI-NEXT:    and x4, x15, #0x7f
-; CHECK-GI-NEXT:    lsr x17, x1, x17
-; CHECK-GI-NEXT:    csel x10, x3, x10, eq
-; CHECK-GI-NEXT:    orr x12, x18, x12
-; CHECK-GI-NEXT:    cmp x16, #64
 ; CHECK-GI-NEXT:    sub x9, x9, x4
-; CHECK-GI-NEXT:    lsr x1, x1, x13
-; CHECK-GI-NEXT:    csel x12, x12, x17, lo
-; CHECK-GI-NEXT:    tst x13, #0x7f
-; CHECK-GI-NEXT:    sub x13, x4, #64
-; CHECK-GI-NEXT:    lsr x17, x2, x15
+; CHECK-GI-NEXT:    csel x10, x3, x10, eq
+; CHECK-GI-NEXT:    orr x15, x16, x15
+; CHECK-GI-NEXT:    cmp x13, #64
+; CHECK-GI-NEXT:    lsr x16, x1, x12
+; CHECK-GI-NEXT:    csel x15, x15, x18, lo
+; CHECK-GI-NEXT:    tst x12, #0x7f
+; CHECK-GI-NEXT:    lsr x12, x2, x17
 ; CHECK-GI-NEXT:    lsl x9, x3, x9
-; CHECK-GI-NEXT:    csel x12, x0, x12, eq
-; CHECK-GI-NEXT:    cmp x16, #64
-; CHECK-GI-NEXT:    lsr x13, x3, x13
-; CHECK-GI-NEXT:    csel x16, x1, xzr, lo
-; CHECK-GI-NEXT:    orr x9, x17, x9
+; CHECK-GI-NEXT:    csel x15, x0, x15, eq
+; CHECK-GI-NEXT:    cmp x13, #64
+; CHECK-GI-NEXT:    lsr x13, x3, x4
+; CHECK-GI-NEXT:    orr x0, x11, x15
+; CHECK-GI-NEXT:    csel x16, x16, xzr, lo
+; CHECK-GI-NEXT:    orr x9, x12, x9
 ; CHECK-GI-NEXT:    cmp x4, #64
-; CHECK-GI-NEXT:    lsr x17, x3, x15
+; CHECK-GI-NEXT:    lsr x12, x3, x17
 ; CHECK-GI-NEXT:    csel x9, x9, x13, lo
-; CHECK-GI-NEXT:    tst x15, #0x7f
+; CHECK-GI-NEXT:    tst x17, #0x7f
 ; CHECK-GI-NEXT:    csel x9, x2, x9, eq
 ; CHECK-GI-NEXT:    cmp x4, #64
-; CHECK-GI-NEXT:    orr x0, x11, x12
-; CHECK-GI-NEXT:    csel x13, x17, xzr, lo
 ; CHECK-GI-NEXT:    orr x1, x8, x16
+; CHECK-GI-NEXT:    csel x12, x12, xzr, lo
 ; CHECK-GI-NEXT:    orr x2, x14, x9
-; CHECK-GI-NEXT:    orr x3, x10, x13
+; CHECK-GI-NEXT:    orr x3, x10, x12
 ; CHECK-GI-NEXT:    ret
 entry:
   %d = call <2 x i128> @llvm.fshl(<2 x i128> %a, <2 x i128> %a, <2 x i128> %c)
@@ -1843,65 +1831,61 @@ define <2 x i128> @rotr_v2i128(<2 x i128> %a, <2 x i128> %c) {
 ; CHECK-GI:       // %bb.0: // %entry
 ; CHECK-GI-NEXT:    and x8, x4, #0x7f
 ; CHECK-GI-NEXT:    mov w9, #64 // =0x40
-; CHECK-GI-NEXT:    lsr x11, x0, x4
-; CHECK-GI-NEXT:    sub x10, x9, x8
-; CHECK-GI-NEXT:    sub x12, x8, #64
-; CHECK-GI-NEXT:    and x14, x6, #0x7f
-; CHECK-GI-NEXT:    lsl x10, x1, x10
-; CHECK-GI-NEXT:    lsr x12, x1, x12
+; CHECK-GI-NEXT:    lsr x13, x0, x4
+; CHECK-GI-NEXT:    sub x11, x9, x8
+; CHECK-GI-NEXT:    and x12, x6, #0x7f
+; CHECK-GI-NEXT:    lsr x15, x1, x8
+; CHECK-GI-NEXT:    lsl x11, x1, x11
 ; CHECK-GI-NEXT:    cmp x8, #64
-; CHECK-GI-NEXT:    sub x15, x9, x14
-; CHECK-GI-NEXT:    neg x13, x4
-; CHECK-GI-NEXT:    neg x16, x6
-; CHECK-GI-NEXT:    orr x10, x11, x10
-; CHECK-GI-NEXT:    lsr x11, x1, x4
-; CHECK-GI-NEXT:    lsl x15, x3, x15
-; CHECK-GI-NEXT:    csel x10, x10, x12, lo
+; CHECK-GI-NEXT:    sub x16, x9, x12
+; CHECK-GI-NEXT:    lsr x14, x1, x4
+; CHECK-GI-NEXT:    neg x10, x4
+; CHECK-GI-NEXT:    orr x11, x13, x11
+; CHECK-GI-NEXT:    lsr x13, x2, x6
+; CHECK-GI-NEXT:    lsl x17, x0, x10
+; CHECK-GI-NEXT:    csel x11, x11, x15, lo
 ; CHECK-GI-NEXT:    tst x4, #0x7f
-; CHECK-GI-NEXT:    sub x12, x14, #64
-; CHECK-GI-NEXT:    csel x10, x0, x10, eq
+; CHECK-GI-NEXT:    lsl x15, x3, x16
+; CHECK-GI-NEXT:    csel x11, x0, x11, eq
 ; CHECK-GI-NEXT:    cmp x8, #64
-; CHECK-GI-NEXT:    lsr x8, x2, x6
-; CHECK-GI-NEXT:    lsr x12, x3, x12
-; CHECK-GI-NEXT:    csel x11, x11, xzr, lo
-; CHECK-GI-NEXT:    cmp x14, #64
-; CHECK-GI-NEXT:    orr x8, x8, x15
-; CHECK-GI-NEXT:    lsr x17, x3, x6
-; CHECK-GI-NEXT:    lsl x18, x1, x13
-; CHECK-GI-NEXT:    csel x8, x8, x12, lo
+; CHECK-GI-NEXT:    lsr x8, x3, x12
+; CHECK-GI-NEXT:    orr x13, x13, x15
+; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
+; CHECK-GI-NEXT:    cmp x12, #64
+; CHECK-GI-NEXT:    csel x8, x13, x8, lo
 ; CHECK-GI-NEXT:    tst x6, #0x7f
-; CHECK-GI-NEXT:    and x12, x13, #0x7f
+; CHECK-GI-NEXT:    lsr x15, x3, x6
 ; CHECK-GI-NEXT:    csel x8, x2, x8, eq
-; CHECK-GI-NEXT:    cmp x14, #64
-; CHECK-GI-NEXT:    sub x14, x9, x12
-; CHECK-GI-NEXT:    sub x15, x12, #64
-; CHECK-GI-NEXT:    lsr x14, x0, x14
-; CHECK-GI-NEXT:    lsl x4, x0, x13
-; CHECK-GI-NEXT:    lsl x15, x0, x15
-; CHECK-GI-NEXT:    and x0, x16, #0x7f
-; CHECK-GI-NEXT:    csel x17, x17, xzr, lo
-; CHECK-GI-NEXT:    orr x14, x14, x18
 ; CHECK-GI-NEXT:    cmp x12, #64
-; CHECK-GI-NEXT:    sub x9, x9, x0
-; CHECK-GI-NEXT:    csel x14, x14, x15, lo
-; CHECK-GI-NEXT:    sub x15, x0, #64
+; CHECK-GI-NEXT:    and x12, x10, #0x7f
+; CHECK-GI-NEXT:    neg x13, x6
+; CHECK-GI-NEXT:    sub x16, x9, x12
+; CHECK-GI-NEXT:    lsl x18, x1, x10
+; CHECK-GI-NEXT:    lsr x16, x0, x16
+; CHECK-GI-NEXT:    and x4, x13, #0x7f
+; CHECK-GI-NEXT:    csel x15, x15, xzr, lo
+; CHECK-GI-NEXT:    lsl x0, x0, x12
+; CHECK-GI-NEXT:    cmp x12, #64
+; CHECK-GI-NEXT:    sub x9, x9, x4
+; CHECK-GI-NEXT:    orr x12, x16, x18
+; CHECK-GI-NEXT:    csel x16, x17, xzr, lo
 ; CHECK-GI-NEXT:    lsr x9, x2, x9
-; CHECK-GI-NEXT:    lsl x18, x3, x16
-; CHECK-GI-NEXT:    csel x12, x4, xzr, lo
+; CHECK-GI-NEXT:    lsl x17, x3, x13
+; CHECK-GI-NEXT:    csel x12, x12, x0, lo
+; CHECK-GI-NEXT:    tst x10, #0x7f
+; CHECK-GI-NEXT:    lsl x10, x2, x13
+; CHECK-GI-NEXT:    lsl x18, x2, x4
+; CHECK-GI-NEXT:    csel x12, x1, x12, eq
+; CHECK-GI-NEXT:    orr x9, x9, x17
+; CHECK-GI-NEXT:    cmp x4, #64
+; CHECK-GI-NEXT:    orr x0, x11, x16
+; CHECK-GI-NEXT:    csel x10, x10, xzr, lo
+; CHECK-GI-NEXT:    csel x9, x9, x18, lo
 ; CHECK-GI-NEXT:    tst x13, #0x7f
-; CHECK-GI-NEXT:    lsl x13, x2, x16
-; CHECK-GI-NEXT:    lsl x15, x2, x15
-; CHECK-GI-NEXT:    csel x14, x1, x14, eq
-; CHECK-GI-NEXT:    orr x9, x9, x18
-; CHECK-GI-NEXT:    cmp x0, #64
-; CHECK-GI-NEXT:    orr x0, x10, x12
-; CHECK-GI-NEXT:    csel x13, x13, xzr, lo
-; CHECK-GI-NEXT:    csel x9, x9, x15, lo
-; CHECK-GI-NEXT:    tst x16, #0x7f
 ; CHECK-GI-NEXT:    csel x9, x3, x9, eq
-; CHECK-GI-NEXT:    orr x1, x11, x14
-; CHECK-GI-NEXT:    orr x2, x8, x13
-; CHECK-GI-NEXT:    orr x3, x17, x9
+; CHECK-GI-NEXT:    orr x1, x14, x12
+; CHECK-GI-NEXT:    orr x2, x8, x10
+; CHECK-GI-NEXT:    orr x3, x15, x9
 ; CHECK-GI-NEXT:    ret
 entry:
   %d = call <2 x i128> @llvm.fshr(<2 x i128> %a, <2 x i128> %a, <2 x i128> %c)
@@ -2845,78 +2829,70 @@ define <2 x i128> @fshl_v2i128(<2 x i128> %a, <2 x i128> %b, <2 x i128> %c) {
 ;
 ; CHECK-GI-LABEL: fshl_v2i128:
 ; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    str x19, [sp, #-16]! // 8-byte Folded Spill
-; CHECK-GI-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-GI-NEXT:    .cfi_offset w19, -16
-; CHECK-GI-NEXT:    ldr x11, [sp, #16]
-; CHECK-GI-NEXT:    mov w9, #64 // =0x40
-; CHECK-GI-NEXT:    ldr x12, [sp, #32]
-; CHECK-GI-NEXT:    mov w13, #127 // =0x7f
-; CHECK-GI-NEXT:    and x8, x11, #0x7f
-; CHECK-GI-NEXT:    lsl x17, x1, x11
-; CHECK-GI-NEXT:    and x14, x12, #0x7f
-; CHECK-GI-NEXT:    sub x10, x9, x8
-; CHECK-GI-NEXT:    sub x15, x8, #64
-; CHECK-GI-NEXT:    cmp x8, #64
-; CHECK-GI-NEXT:    lsr x16, x0, x10
-; CHECK-GI-NEXT:    lsl x15, x0, x15
-; CHECK-GI-NEXT:    lsl x19, x0, x11
-; CHECK-GI-NEXT:    lsl x0, x3, x12
-; CHECK-GI-NEXT:    mvn x18, x11
-; CHECK-GI-NEXT:    mvn x10, x12
-; CHECK-GI-NEXT:    orr x16, x16, x17
-; CHECK-GI-NEXT:    sub x17, x14, #64
-; CHECK-GI-NEXT:    csel x8, x19, xzr, lo
-; CHECK-GI-NEXT:    csel x15, x16, x15, lo
-; CHECK-GI-NEXT:    sub x16, x9, x14
-; CHECK-GI-NEXT:    tst x11, #0x7f
-; CHECK-GI-NEXT:    lsr x16, x2, x16
-; CHECK-GI-NEXT:    lsl x19, x2, x12
-; CHECK-GI-NEXT:    lsl x17, x2, x17
-; CHECK-GI-NEXT:    csel x15, x1, x15, eq
+; CHECK-GI-NEXT:    ldr x8, [sp]
+; CHECK-GI-NEXT:    mov w11, #64 // =0x40
+; CHECK-GI-NEXT:    ldr x9, [sp, #16]
+; CHECK-GI-NEXT:    mov w12, #127 // =0x7f
+; CHECK-GI-NEXT:    and x10, x8, #0x7f
+; CHECK-GI-NEXT:    lsl x15, x1, x8
+; CHECK-GI-NEXT:    and x14, x9, #0x7f
+; CHECK-GI-NEXT:    sub x13, x11, x10
+; CHECK-GI-NEXT:    lsl x17, x0, x8
+; CHECK-GI-NEXT:    cmp x10, #64
+; CHECK-GI-NEXT:    lsr x13, x0, x13
+; CHECK-GI-NEXT:    lsl x18, x0, x10
+; CHECK-GI-NEXT:    mvn x16, x8
+; CHECK-GI-NEXT:    csel x10, x17, xzr, lo
+; CHECK-GI-NEXT:    lsl x17, x3, x9
+; CHECK-GI-NEXT:    mvn x0, x9
+; CHECK-GI-NEXT:    orr x13, x13, x15
+; CHECK-GI-NEXT:    sub x15, x11, x14
+; CHECK-GI-NEXT:    lsr x15, x2, x15
+; CHECK-GI-NEXT:    csel x13, x13, x18, lo
+; CHECK-GI-NEXT:    tst x8, #0x7f
+; CHECK-GI-NEXT:    bic x8, x12, x8
+; CHECK-GI-NEXT:    csel x13, x1, x13, eq
+; CHECK-GI-NEXT:    lsl x18, x2, x9
+; CHECK-GI-NEXT:    orr x15, x15, x17
+; CHECK-GI-NEXT:    lsl x17, x2, x14
 ; CHECK-GI-NEXT:    cmp x14, #64
-; CHECK-GI-NEXT:    bic x11, x13, x11
-; CHECK-GI-NEXT:    orr x16, x16, x0
-; CHECK-GI-NEXT:    csel x14, x19, xzr, lo
-; CHECK-GI-NEXT:    extr x0, x5, x4, #1
-; CHECK-GI-NEXT:    csel x16, x16, x17, lo
-; CHECK-GI-NEXT:    tst x12, #0x7f
-; CHECK-GI-NEXT:    lsr x17, x5, #1
-; CHECK-GI-NEXT:    bic x12, x13, x12
-; CHECK-GI-NEXT:    csel x13, x3, x16, eq
-; CHECK-GI-NEXT:    sub x16, x9, x11
-; CHECK-GI-NEXT:    sub x1, x11, #64
-; CHECK-GI-NEXT:    lsr x2, x0, x18
-; CHECK-GI-NEXT:    lsl x16, x17, x16
-; CHECK-GI-NEXT:    lsr x3, x7, #1
+; CHECK-GI-NEXT:    lsr x14, x5, #1
+; CHECK-GI-NEXT:    extr x1, x5, x4, #1
+; CHECK-GI-NEXT:    bic x12, x12, x9
+; CHECK-GI-NEXT:    csel x15, x15, x17, lo
+; CHECK-GI-NEXT:    sub x17, x11, x8
+; CHECK-GI-NEXT:    csel x18, x18, xzr, lo
+; CHECK-GI-NEXT:    tst x9, #0x7f
+; CHECK-GI-NEXT:    lsr x9, x1, x16
+; CHECK-GI-NEXT:    lsl x17, x14, x17
+; CHECK-GI-NEXT:    csel x15, x3, x15, eq
+; CHECK-GI-NEXT:    lsr x2, x7, #1
+; CHECK-GI-NEXT:    lsr x3, x14, x8
 ; CHECK-GI-NEXT:    extr x4, x7, x6, #1
-; CHECK-GI-NEXT:    lsr x1, x17, x1
-; CHECK-GI-NEXT:    orr x16, x2, x16
-; CHECK-GI-NEXT:    cmp x11, #64
-; CHECK-GI-NEXT:    sub x9, x9, x12
-; CHECK-GI-NEXT:    lsr x17, x17, x18
-; CHECK-GI-NEXT:    csel x16, x16, x1, lo
-; CHECK-GI-NEXT:    tst x18, #0x7f
-; CHECK-GI-NEXT:    sub x18, x12, #64
-; CHECK-GI-NEXT:    lsr x1, x4, x10
-; CHECK-GI-NEXT:    lsl x9, x3, x9
-; CHECK-GI-NEXT:    csel x16, x0, x16, eq
-; CHECK-GI-NEXT:    cmp x11, #64
-; CHECK-GI-NEXT:    lsr x11, x3, x18
-; CHECK-GI-NEXT:    csel x17, x17, xzr, lo
-; CHECK-GI-NEXT:    orr x9, x1, x9
+; CHECK-GI-NEXT:    orr x9, x9, x17
+; CHECK-GI-NEXT:    cmp x8, #64
+; CHECK-GI-NEXT:    sub x11, x11, x12
+; CHECK-GI-NEXT:    lsr x14, x14, x16
+; CHECK-GI-NEXT:    csel x9, x9, x3, lo
+; CHECK-GI-NEXT:    tst x16, #0x7f
+; CHECK-GI-NEXT:    lsr x16, x4, x0
+; CHECK-GI-NEXT:    lsl x11, x2, x11
+; CHECK-GI-NEXT:    csel x9, x1, x9, eq
+; CHECK-GI-NEXT:    cmp x8, #64
+; CHECK-GI-NEXT:    lsr x8, x2, x12
+; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
+; CHECK-GI-NEXT:    orr x11, x16, x11
 ; CHECK-GI-NEXT:    cmp x12, #64
-; CHECK-GI-NEXT:    lsr x18, x3, x10
-; CHECK-GI-NEXT:    csel x9, x9, x11, lo
-; CHECK-GI-NEXT:    tst x10, #0x7f
-; CHECK-GI-NEXT:    csel x9, x4, x9, eq
+; CHECK-GI-NEXT:    lsr x16, x2, x0
+; CHECK-GI-NEXT:    csel x8, x11, x8, lo
+; CHECK-GI-NEXT:    tst x0, #0x7f
+; CHECK-GI-NEXT:    csel x8, x4, x8, eq
 ; CHECK-GI-NEXT:    cmp x12, #64
-; CHECK-GI-NEXT:    orr x0, x8, x16
-; CHECK-GI-NEXT:    csel x10, x18, xzr, lo
-; CHECK-GI-NEXT:    orr x1, x15, x17
-; CHECK-GI-NEXT:    orr x2, x14, x9
-; CHECK-GI-NEXT:    orr x3, x13, x10
-; CHECK-GI-NEXT:    ldr x19, [sp], #16 // 8-byte Folded Reload
+; CHECK-GI-NEXT:    orr x0, x10, x9
+; CHECK-GI-NEXT:    csel x11, x16, xzr, lo
+; CHECK-GI-NEXT:    orr x1, x13, x14
+; CHECK-GI-NEXT:    orr x2, x18, x8
+; CHECK-GI-NEXT:    orr x3, x15, x11
 ; CHECK-GI-NEXT:    ret
 entry:
   %d = call <2 x i128> @llvm.fshl(<2 x i128> %a, <2 x i128> %b, <2 x i128> %c)
@@ -2958,74 +2934,74 @@ define <2 x i128> @fshr_v2i128(<2 x i128> %a, <2 x i128> %b, <2 x i128> %c) {
 ;
 ; CHECK-GI-LABEL: fshr_v2i128:
 ; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    ldr x9, [sp]
-; CHECK-GI-NEXT:    mov w10, #127 // =0x7f
-; CHECK-GI-NEXT:    mov w12, #64 // =0x40
-; CHECK-GI-NEXT:    lsl x13, x0, #1
-; CHECK-GI-NEXT:    extr x14, x1, x0, #63
-; CHECK-GI-NEXT:    ldr x8, [sp, #16]
-; CHECK-GI-NEXT:    bic x11, x10, x9
-; CHECK-GI-NEXT:    mvn x15, x9
-; CHECK-GI-NEXT:    sub x17, x12, x11
-; CHECK-GI-NEXT:    sub x18, x11, #64
-; CHECK-GI-NEXT:    lsl x0, x14, x15
-; CHECK-GI-NEXT:    lsr x17, x13, x17
-; CHECK-GI-NEXT:    lsl x1, x13, x15
-; CHECK-GI-NEXT:    lsl x13, x13, x18
-; CHECK-GI-NEXT:    bic x10, x10, x8
-; CHECK-GI-NEXT:    lsl x18, x2, #1
+; CHECK-GI-NEXT:    str x19, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-GI-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-GI-NEXT:    .cfi_offset w19, -16
+; CHECK-GI-NEXT:    ldr x10, [sp, #16]
+; CHECK-GI-NEXT:    mov w12, #127 // =0x7f
+; CHECK-GI-NEXT:    mov w14, #64 // =0x40
+; CHECK-GI-NEXT:    lsl x15, x0, #1
+; CHECK-GI-NEXT:    extr x16, x1, x0, #63
+; CHECK-GI-NEXT:    ldr x8, [sp, #32]
+; CHECK-GI-NEXT:    bic x13, x12, x10
+; CHECK-GI-NEXT:    mvn x17, x10
+; CHECK-GI-NEXT:    lsl x19, x2, #1
+; CHECK-GI-NEXT:    sub x0, x14, x13
+; CHECK-GI-NEXT:    lsl x1, x16, x17
+; CHECK-GI-NEXT:    bic x12, x12, x8
+; CHECK-GI-NEXT:    lsr x0, x15, x0
+; CHECK-GI-NEXT:    extr x2, x3, x2, #63
+; CHECK-GI-NEXT:    lsl x3, x15, x17
+; CHECK-GI-NEXT:    lsl x15, x15, x13
+; CHECK-GI-NEXT:    mvn x18, x8
+; CHECK-GI-NEXT:    cmp x13, #64
+; CHECK-GI-NEXT:    orr x0, x0, x1
+; CHECK-GI-NEXT:    sub x1, x14, x12
+; CHECK-GI-NEXT:    and x11, x10, #0x7f
+; CHECK-GI-NEXT:    lsr x13, x19, x1
+; CHECK-GI-NEXT:    lsl x1, x2, x18
+; CHECK-GI-NEXT:    csel x3, x3, xzr, lo
+; CHECK-GI-NEXT:    csel x15, x0, x15, lo
+; CHECK-GI-NEXT:    tst x17, #0x7f
+; CHECK-GI-NEXT:    lsl x17, x19, x12
+; CHECK-GI-NEXT:    csel x15, x16, x15, eq
+; CHECK-GI-NEXT:    lsl x16, x19, x18
+; CHECK-GI-NEXT:    cmp x12, #64
+; CHECK-GI-NEXT:    sub x12, x14, x11
+; CHECK-GI-NEXT:    orr x13, x13, x1
+; CHECK-GI-NEXT:    lsr x0, x4, x10
+; CHECK-GI-NEXT:    lsl x12, x5, x12
+; CHECK-GI-NEXT:    and x9, x8, #0x7f
+; CHECK-GI-NEXT:    csel x16, x16, xzr, lo
+; CHECK-GI-NEXT:    csel x13, x13, x17, lo
+; CHECK-GI-NEXT:    tst x18, #0x7f
+; CHECK-GI-NEXT:    lsr x17, x5, x11
+; CHECK-GI-NEXT:    csel x13, x2, x13, eq
+; CHECK-GI-NEXT:    orr x12, x0, x12
 ; CHECK-GI-NEXT:    cmp x11, #64
-; CHECK-GI-NEXT:    orr x17, x17, x0
-; CHECK-GI-NEXT:    extr x11, x3, x2, #63
-; CHECK-GI-NEXT:    mvn x16, x8
-; CHECK-GI-NEXT:    csel x13, x17, x13, lo
-; CHECK-GI-NEXT:    sub x17, x12, x10
-; CHECK-GI-NEXT:    csel x0, x1, xzr, lo
-; CHECK-GI-NEXT:    tst x15, #0x7f
-; CHECK-GI-NEXT:    sub x15, x10, #64
-; CHECK-GI-NEXT:    lsr x17, x18, x17
-; CHECK-GI-NEXT:    lsl x2, x11, x16
-; CHECK-GI-NEXT:    csel x13, x14, x13, eq
-; CHECK-GI-NEXT:    lsl x14, x18, x15
-; CHECK-GI-NEXT:    lsl x1, x18, x16
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    and x10, x9, #0x7f
-; CHECK-GI-NEXT:    orr x15, x17, x2
-; CHECK-GI-NEXT:    lsr x18, x4, x9
-; CHECK-GI-NEXT:    csel x14, x15, x14, lo
-; CHECK-GI-NEXT:    sub x15, x12, x10
-; CHECK-GI-NEXT:    csel x17, x1, xzr, lo
-; CHECK-GI-NEXT:    tst x16, #0x7f
-; CHECK-GI-NEXT:    sub x16, x10, #64
-; CHECK-GI-NEXT:    lsl x15, x5, x15
-; CHECK-GI-NEXT:    csel x11, x11, x14, eq
-; CHECK-GI-NEXT:    lsr x14, x5, x16
-; CHECK-GI-NEXT:    and x1, x8, #0x7f
-; CHECK-GI-NEXT:    orr x15, x18, x15
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    lsr x16, x5, x9
-; CHECK-GI-NEXT:    csel x14, x15, x14, lo
-; CHECK-GI-NEXT:    tst x9, #0x7f
-; CHECK-GI-NEXT:    sub x9, x12, x1
-; CHECK-GI-NEXT:    sub x12, x1, #64
-; CHECK-GI-NEXT:    lsr x15, x6, x8
-; CHECK-GI-NEXT:    lsl x9, x7, x9
-; CHECK-GI-NEXT:    csel x14, x4, x14, eq
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    lsr x10, x7, x12
-; CHECK-GI-NEXT:    csel x12, x16, xzr, lo
-; CHECK-GI-NEXT:    orr x9, x15, x9
-; CHECK-GI-NEXT:    cmp x1, #64
-; CHECK-GI-NEXT:    lsr x15, x7, x8
-; CHECK-GI-NEXT:    csel x9, x9, x10, lo
+; CHECK-GI-NEXT:    sub x14, x14, x9
+; CHECK-GI-NEXT:    lsr x18, x5, x10
+; CHECK-GI-NEXT:    csel x12, x12, x17, lo
+; CHECK-GI-NEXT:    tst x10, #0x7f
+; CHECK-GI-NEXT:    lsr x10, x6, x8
+; CHECK-GI-NEXT:    lsl x14, x7, x14
+; CHECK-GI-NEXT:    csel x12, x4, x12, eq
+; CHECK-GI-NEXT:    cmp x11, #64
+; CHECK-GI-NEXT:    lsr x11, x7, x9
+; CHECK-GI-NEXT:    csel x17, x18, xzr, lo
+; CHECK-GI-NEXT:    orr x10, x10, x14
+; CHECK-GI-NEXT:    cmp x9, #64
+; CHECK-GI-NEXT:    lsr x14, x7, x8
+; CHECK-GI-NEXT:    csel x10, x10, x11, lo
 ; CHECK-GI-NEXT:    tst x8, #0x7f
-; CHECK-GI-NEXT:    csel x8, x6, x9, eq
-; CHECK-GI-NEXT:    cmp x1, #64
-; CHECK-GI-NEXT:    orr x0, x0, x14
-; CHECK-GI-NEXT:    csel x9, x15, xzr, lo
-; CHECK-GI-NEXT:    orr x1, x13, x12
-; CHECK-GI-NEXT:    orr x2, x17, x8
-; CHECK-GI-NEXT:    orr x3, x11, x9
+; CHECK-GI-NEXT:    csel x8, x6, x10, eq
+; CHECK-GI-NEXT:    cmp x9, #64
+; CHECK-GI-NEXT:    orr x0, x3, x12
+; CHECK-GI-NEXT:    csel x9, x14, xzr, lo
+; CHECK-GI-NEXT:    orr x1, x15, x17
+; CHECK-GI-NEXT:    orr x2, x16, x8
+; CHECK-GI-NEXT:    orr x3, x13, x9
+; CHECK-GI-NEXT:    ldr x19, [sp], #16 // 8-byte Folded Reload
 ; CHECK-GI-NEXT:    ret
 entry:
   %d = call <2 x i128> @llvm.fshr(<2 x i128> %a, <2 x i128> %b, <2 x i128> %c)
diff --git a/llvm/test/CodeGen/AArch64/funnel-shift.ll b/llvm/test/CodeGen/AArch64/funnel-shift.ll
index f92d9af5ce6c16..d750e9521096da 100644
--- a/llvm/test/CodeGen/AArch64/funnel-shift.ll
+++ b/llvm/test/CodeGen/AArch64/funnel-shift.ll
@@ -72,40 +72,38 @@ define i128 @fshl_i128(i128 %x, i128 %y, i128 %z) nounwind {
 ;
 ; CHECK-GI-LABEL: fshl_i128:
 ; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    mov w8, #64 // =0x40
 ; CHECK-GI-NEXT:    and x9, x4, #0x7f
-; CHECK-GI-NEXT:    lsl x13, x1, x4
-; CHECK-GI-NEXT:    sub x12, x8, x9
-; CHECK-GI-NEXT:    mov w10, #127 // =0x7f
-; CHECK-GI-NEXT:    sub x15, x9, #64
+; CHECK-GI-NEXT:    mov w10, #64 // =0x40
+; CHECK-GI-NEXT:    mov w8, #127 // =0x7f
+; CHECK-GI-NEXT:    sub x12, x10, x9
+; CHECK-GI-NEXT:    bic x8, x8, x4
+; CHECK-GI-NEXT:    lsl x13, x0, x4
 ; CHECK-GI-NEXT:    lsr x12, x0, x12
-; CHECK-GI-NEXT:    bic x10, x10, x4
+; CHECK-GI-NEXT:    lsl x14, x1, x4
 ; CHECK-GI-NEXT:    extr x16, x3, x2, #1
-; CHECK-GI-NEXT:    cmp x9, #64
+; CHECK-GI-NEXT:    lsr x17, x3, #1
 ; CHECK-GI-NEXT:    mvn x11, x4
-; CHECK-GI-NEXT:    lsl x14, x0, x4
-; CHECK-GI-NEXT:    orr x9, x12, x13
-; CHECK-GI-NEXT:    lsr x12, x3, #1
-; CHECK-GI-NEXT:    lsl x13, x0, x15
-; CHECK-GI-NEXT:    sub x8, x8, x10
-; CHECK-GI-NEXT:    sub x15, x10, #64
-; CHECK-GI-NEXT:    lsr x17, x16, x11
-; CHECK-GI-NEXT:    lsl x8, x12, x8
-; CHECK-GI-NEXT:    csel x14, x14, xzr, lo
-; CHECK-GI-NEXT:    csel x9, x9, x13, lo
+; CHECK-GI-NEXT:    lsl x15, x0, x9
+; CHECK-GI-NEXT:    cmp x9, #64
+; CHECK-GI-NEXT:    sub x9, x10, x8
+; CHECK-GI-NEXT:    orr x12, x12, x14
+; CHECK-GI-NEXT:    csel x10, x13, xzr, lo
+; CHECK-GI-NEXT:    lsr x13, x16, x11
+; CHECK-GI-NEXT:    lsl x9, x17, x9
+; CHECK-GI-NEXT:    csel x12, x12, x15, lo
 ; CHECK-GI-NEXT:    tst x4, #0x7f
-; CHECK-GI-NEXT:    lsr x13, x12, x15
-; CHECK-GI-NEXT:    lsr x12, x12, x11
-; CHECK-GI-NEXT:    csel x9, x1, x9, eq
-; CHECK-GI-NEXT:    orr x8, x17, x8
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    csel x8, x8, x13, lo
+; CHECK-GI-NEXT:    lsr x14, x17, x8
+; CHECK-GI-NEXT:    csel x12, x1, x12, eq
+; CHECK-GI-NEXT:    orr x9, x13, x9
+; CHECK-GI-NEXT:    cmp x8, #64
+; CHECK-GI-NEXT:    lsr x13, x17, x11
+; CHECK-GI-NEXT:    csel x9, x9, x14, lo
 ; CHECK-GI-NEXT:    tst x11, #0x7f
-; CHECK-GI-NEXT:    csel x8, x16, x8, eq
-; CHECK-GI-NEXT:    cmp x10, #64
-; CHECK-GI-NEXT:    csel x10, x12, xzr, lo
-; CHECK-GI-NEXT:    orr x0, x14, x8
-; CHECK-GI-NEXT:    orr x1, x9, x10
+; CHECK-GI-NEXT:    csel x9, x16, x9, eq
+; CHECK-GI-NEXT:    cmp x8, #64
+; CHECK-GI-NEXT:    csel x8, x13, xzr, lo
+; CHECK-GI-NEXT:    orr x0, x10, x9
+; CHECK-GI-NEXT:    orr x1, x12, x8
 ; CHECK-GI-NEXT:    ret
   %f = call i128 @llvm.fshl.i128(i128 %x, i128 %y, i128 %z)
   ret i128 %f
diff --git a/llvm/test/CodeGen/AArch64/shift-mod.ll b/llvm/test/CodeGen/AArch64/shift-mod.ll
index 8ba17c73e20933..e53ba2554ac776 100644
--- a/llvm/test/CodeGen/AArch64/shift-mod.ll
+++ b/llvm/test/CodeGen/AArch64/shift-mod.ll
@@ -36,16 +36,10 @@ define i64 @test2(i32 %x, i64 %y) {
 }
 
 define i64 @test3(i64 %x, i64 %y) {
-; CHECK-SD-LABEL: test3:
-; CHECK-SD:       // %bb.0:
-; CHECK-SD-NEXT:    lsl x0, x1, x0
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: test3:
-; CHECK-GI:       // %bb.0:
-; CHECK-GI-NEXT:    add x8, x0, #64
-; CHECK-GI-NEXT:    lsl x0, x1, x8
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: test3:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsl x0, x1, x0
+; CHECK-NEXT:    ret
   %add = add nsw i64 64, %x
   %shl = shl i64 %y, %add
   ret i64 %shl
@@ -265,3 +259,34 @@ define i64 @ashr_i64_i16(i64 %x, i16 %amt) {
   %r = ashr i64 %x, %ext
   ret i64 %r
 }
+
+; Test ADD/SUB by multiple of shift size is optimized away.
+define i32 @shl_i32_add64(i32 %x, i32 %amt) {
+; CHECK-LABEL: shl_i32_add64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsl w0, w0, w1
+; CHECK-NEXT:    ret
+  %add = add i32 %amt, 64
+  %r = shl i32 %x, %add
+  ret i32 %r
+}
+
+define i32 @lshr_i32_add32(i32 %x, i32 %amt) {
+; CHECK-LABEL: lshr_i32_add32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsr w0, w0, w1
+; CHECK-NEXT:    ret
+  %add = add i32 %amt, 32
+  %r = lshr i32 %x, %add
+  ret i32 %r
+}
+
+define i64 @shl_i64_add64(i64 %x, i64 %amt) {
+; CHECK-LABEL: shl_i64_add64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsl x0, x0, x1
+; CHECK-NEXT:    ret
+  %add = add i64 %amt, 64
+  %r = shl i64 %x, %add
+  ret i64 %r
+}
diff --git a/llvm/test/CodeGen/AArch64/shift.ll b/llvm/test/CodeGen/AArch64/shift.ll
index eb5f56f771a0f2..2fcdf4df419310 100644
--- a/llvm/test/CodeGen/AArch64/shift.ll
+++ b/llvm/test/CodeGen/AArch64/shift.ll
@@ -71,16 +71,14 @@ define i128 @shl_i128(i128 %0, i128 %1){
 ; CHECK-GI-LABEL: shl_i128:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
-; CHECK-GI-NEXT:    sub x9, x2, #64
-; CHECK-GI-NEXT:    lsl x10, x1, x2
+; CHECK-GI-NEXT:    lsl x9, x1, x2
+; CHECK-GI-NEXT:    lsl x10, x0, x2
 ; CHECK-GI-NEXT:    sub x8, x8, x2
-; CHECK-GI-NEXT:    lsl x11, x0, x2
-; CHECK-GI-NEXT:    lsl x9, x0, x9
-; CHECK-GI-NEXT:    lsr x8, x0, x8
 ; CHECK-GI-NEXT:    cmp x2, #64
-; CHECK-GI-NEXT:    csel x0, x11, xzr, lo
-; CHECK-GI-NEXT:    orr x8, x8, x10
-; CHECK-GI-NEXT:    csel x8, x8, x9, lo
+; CHECK-GI-NEXT:    lsr x8, x0, x8
+; CHECK-GI-NEXT:    csel x0, x10, xzr, lo
+; CHECK-GI-NEXT:    orr x8, x8, x9
+; CHECK-GI-NEXT:    csel x8, x8, x10, lo
 ; CHECK-GI-NEXT:    cmp x2, #0
 ; CHECK-GI-NEXT:    csel x1, x1, x8, eq
 ; CHECK-GI-NEXT:    ret
@@ -161,20 +159,18 @@ define i128 @ashr_i128(i128 %0, i128 %1){
 ; CHECK-GI-LABEL: ashr_i128:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
-; CHECK-GI-NEXT:    sub x9, x2, #64
-; CHECK-GI-NEXT:    lsr x10, x0, x2
+; CHECK-GI-NEXT:    lsr x9, x0, x2
+; CHECK-GI-NEXT:    asr x10, x1, x2
 ; CHECK-GI-NEXT:    sub x8, x8, x2
-; CHECK-GI-NEXT:    asr x9, x1, x9
 ; CHECK-GI-NEXT:    cmp x2, #64
 ; CHECK-GI-NEXT:    lsl x8, x1, x8
-; CHECK-GI-NEXT:    asr x11, x1, x2
-; CHECK-GI-NEXT:    orr x8, x10, x8
-; CHECK-GI-NEXT:    asr x10, x1, #63
-; CHECK-GI-NEXT:    csel x8, x8, x9, lo
+; CHECK-GI-NEXT:    orr x8, x9, x8
+; CHECK-GI-NEXT:    asr x9, x1, #63
+; CHECK-GI-NEXT:    csel x8, x8, x10, lo
 ; CHECK-GI-NEXT:    cmp x2, #0
 ; CHECK-GI-NEXT:    csel x0, x0, x8, eq
 ; CHECK-GI-NEXT:    cmp x2, #64
-; CHECK-GI-NEXT:    csel x1, x11, x10, lo
+; CHECK-GI-NEXT:    csel x1, x10, x9, lo
 ; CHECK-GI-NEXT:    ret
     %3 = ashr i128 %0, %1
     ret i128 %3
@@ -251,15 +247,13 @@ define i128 @lshr_i128(i128 %0, i128 %1){
 ; CHECK-GI-LABEL: lshr_i128:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
-; CHECK-GI-NEXT:    sub x9, x2, #64
-; CHECK-GI-NEXT:    lsr x10, x0, x2
+; CHECK-GI-NEXT:    lsr x9, x0, x2
+; CHECK-GI-NEXT:    lsr x10, x1, x2
 ; CHECK-GI-NEXT:    sub x8, x8, x2
-; CHECK-GI-NEXT:    lsr x9, x1, x9
 ; CHECK-GI-NEXT:    cmp x2, #64
 ; CHECK-GI-NEXT:    lsl x8, x1, x8
-; CHECK-GI-NEXT:    orr x8, x10, x8
-; CHECK-GI-NEXT:    lsr x10, x1, x2
-; CHECK-GI-NEXT:    csel x8, x8, x9, lo
+; CHECK-GI-NEXT:    orr x8, x9, x8
+; CHECK-GI-NEXT:    csel x8, x8, x10, lo
 ; CHECK-GI-NEXT:    cmp x2, #0
 ; CHECK-GI-NEXT:    csel x0, x0, x8, eq
 ; CHECK-GI-NEXT:    cmp x2, #64
@@ -620,28 +614,24 @@ define <2 x i128> @shl_v2i128(<2 x i128> %0, <2 x i128> %1){
 ; CHECK-GI-LABEL: shl_v2i128:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
-; CHECK-GI-NEXT:    sub x10, x4, #64
-; CHECK-GI-NEXT:    lsl x11, x1, x4
+; CHECK-GI-NEXT:    lsl x10, x1, x4
+; CHECK-GI-NEXT:    lsl x11, x0, x4
 ; CHECK-GI-NEXT:    sub x9, x8, x4
-; CHECK-GI-NEXT:    lsl x10, x0, x10
-; CHECK-GI-NEXT:    lsl x12, x0, x4
-; CHECK-GI-NEXT:    lsr x9, x0, x9
-; CHECK-GI-NEXT:    cmp x4, #64
 ; CHECK-GI-NEXT:    sub x8, x8, x6
+; CHECK-GI-NEXT:    cmp x4, #64
+; CHECK-GI-NEXT:    lsr x9, x0, x9
 ; CHECK-GI-NEXT:    lsr x8, x2, x8
-; CHECK-GI-NEXT:    csel x0, x12, xzr, lo
-; CHECK-GI-NEXT:    lsl x12, x2, x6
-; CHECK-GI-NEXT:    orr x9, x9, x11
-; CHECK-GI-NEXT:    lsl x11, x3, x6
-; CHECK-GI-NEXT:    csel x9, x9, x10, lo
-; CHECK-GI-NEXT:    sub x10, x6, #64
+; CHECK-GI-NEXT:    csel x0, x11, xzr, lo
+; CHECK-GI-NEXT:    orr x9, x9, x10
+; CHECK-GI-NEXT:    lsl x10, x3, x6
+; CHECK-GI-NEXT:    csel x9, x9, x11, lo
 ; CHECK-GI-NEXT:    cmp x4, #0
-; CHECK-GI-NEXT:    lsl x10, x2, x10
+; CHECK-GI-NEXT:    lsl x11, x2, x6
 ; CHECK-GI-NEXT:    csel x1, x1, x9, eq
-; CHECK-GI-NEXT:    orr x8, x8, x11
+; CHECK-GI-NEXT:    orr x8, x8, x10
 ; CHECK-GI-NEXT:    cmp x6, #64
-; CHECK-GI-NEXT:    csel x2, x12, xzr, lo
-; CHECK-GI-NEXT:    csel x8, x8, x10, lo
+; CHECK-GI-NEXT:    csel x2, x11, xzr, lo
+; CHECK-GI-NEXT:    csel x8, x8, x11, lo
 ; CHECK-GI-NEXT:    cmp x6, #0
 ; CHECK-GI-NEXT:    csel x3, x3, x8, eq
 ; CHECK-GI-NEXT:    ret
@@ -788,34 +778,30 @@ define <2 x i128> @ashr_v2i128(<2 x i128> %0, <2 x i128> %1){
 ; CHECK-GI-LABEL: ashr_v2i128:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
-; CHECK-GI-NEXT:    sub x10, x4, #64
-; CHECK-GI-NEXT:    lsr x11, x0, x4
+; CHECK-GI-NEXT:    lsr x10, x0, x4
+; CHECK-GI-NEXT:    asr x11, x1, x4
 ; CHECK-GI-NEXT:    sub x9, x8, x4
-; CHECK-GI-NEXT:    asr x10, x1, x10
 ; CHECK-GI-NEXT:    cmp x4, #64
-; CHECK-GI-NEXT:    lsl x9, x1, x9
 ; CHECK-GI-NEXT:    sub x8, x8, x6
-; CHECK-GI-NEXT:    asr x12, x1, x4
+; CHECK-GI-NEXT:    lsl x9, x1, x9
+; CHECK-GI-NEXT:    lsr x12, x2, x6
 ; CHECK-GI-NEXT:    lsl x8, x3, x8
-; CHECK-GI-NEXT:    orr x9, x11, x9
-; CHECK-GI-NEXT:    asr x11, x1, #63
-; CHECK-GI-NEXT:    csel x9, x9, x10, lo
+; CHECK-GI-NEXT:    orr x9, x10, x9
+; CHECK-GI-NEXT:    asr x10, x1, #63
+; CHECK-GI-NEXT:    orr x8, x12, x8
+; CHECK-GI-NEXT:    csel x9, x9, x11, lo
 ; CHECK-GI-NEXT:    cmp x4, #0
-; CHECK-GI-NEXT:    lsr x10, x2, x6
 ; CHECK-GI-NEXT:    csel x0, x0, x9, eq
-; CHECK-GI-NEXT:    sub x9, x6, #64
 ; CHECK-GI-NEXT:    cmp x4, #64
-; CHECK-GI-NEXT:    asr x9, x3, x9
-; CHECK-GI-NEXT:    csel x1, x12, x11, lo
-; CHECK-GI-NEXT:    orr x8, x10, x8
+; CHECK-GI-NEXT:    asr x9, x3, x6
+; CHECK-GI-NEXT:    csel x1, x11, x10, lo
 ; CHECK-GI-NEXT:    cmp x6, #64
-; CHECK-GI-NEXT:    asr x11, x3, x6
 ; CHECK-GI-NEXT:    asr x10, x3, #63
 ; CHECK-GI-NEXT:    csel x8, x8, x9, lo
 ; CHECK-GI-NEXT:    cmp x6, #0
 ; CHECK-GI-NEXT:    csel x2, x2, x8, eq
 ; CHECK-GI-NEXT:    cmp x6, #64
-; CHECK-GI-NEXT:    csel x3, x11, x10, lo
+; CHECK-GI-NEXT:    csel x3, x9, x10, lo
 ; CHECK-GI-NEXT:    ret
     %3 = ashr <2 x i128> %0, %1
     ret <2 x i128> %3
@@ -956,32 +942,28 @@ define <2 x i128> @lshr_v2i128(<2 x i128> %0, <2 x i128> %1){
 ; CHECK-GI-LABEL: lshr_v2i128:
 ; CHECK-GI:       // %bb.0:
 ; CHECK-GI-NEXT:    mov w8, #64 // =0x40
-; CHECK-GI-NEXT:    sub x10, x4, #64
-; CHECK-GI-NEXT:    lsr x11, x0, x4
+; CHECK-GI-NEXT:    lsr x10, x0, x4
+; CHECK-GI-NEXT:    lsr x11, x1, x4
 ; CHECK-GI-NEXT:    sub x9, x8, x4
-; CHECK-GI-NEXT:    lsr x10, x1, x10
 ; CHECK-GI-NEXT:    cmp x4, #64
-; CHECK-GI-NEXT:    lsl x9, x1, x9
 ; CHECK-GI-NEXT:    sub x8, x8, x6
-; CHECK-GI-NEXT:    lsr x12, x1, x4
+; CHECK-GI-NEXT:    lsl x9, x1, x9
 ; CHECK-GI-NEXT:    lsl x8, x3, x8
-; CHECK-GI-NEXT:    orr x9, x11, x9
-; CHECK-GI-NEXT:    lsr x11, x2, x6
-; CHECK-GI-NEXT:    csel x9, x9, x10, lo
+; CHECK-GI-NEXT:    orr x9, x10, x9
+; CHECK-GI-NEXT:    lsr x10, x2, x6
+; CHECK-GI-NEXT:    csel x9, x9, x11, lo
 ; CHECK-GI-NEXT:    cmp x4, #0
-; CHECK-GI-NEXT:    sub x10, x6, #64
 ; CHECK-GI-NEXT:    csel x0, x0, x9, eq
 ; CHECK-GI-NEXT:    cmp x4, #64
-; CHECK-GI-NEXT:    lsr x9, x3, x10
-; CHECK-GI-NEXT:    csel x1, x12, xzr, lo
-; CHECK-GI-NEXT:    orr x8, x11, x8
+; CHECK-GI-NEXT:    lsr x9, x3, x6
+; CHECK-GI-NEXT:    csel x1, x11, xzr, lo
+; CHECK-GI-NEXT:    orr x8, x10, x8
 ; CHECK-GI-NEXT:    cmp x6, #64
-; CHECK-GI-NEXT:    lsr x10, x3, x6
 ; CHECK-GI-NEXT:    csel x8, x8, x9, lo
 ; CHECK-GI-NEXT:    cmp x6, #0
 ; CHECK-GI-NEXT:    csel x2, x2, x8, eq
 ; CHECK-GI-NEXT:    cmp x6, #64
-; CHECK-GI-NEXT:    csel x3, x10, xzr, lo
+; CHECK-GI-NEXT:    csel x3, x9, xzr, lo
 ; CHECK-GI-NEXT:    ret
     %3 = lshr <2 x i128> %0, %1
     ret <2 x i128> %3



More information about the llvm-commits mailing list