[llvm-branch-commits] [llvm] [LoongArch] Fold selects sharing operands with binary operations (PR #215520)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Aug 11 04:04:50 PDT 2026


https://github.com/heiher created https://github.com/llvm/llvm-project/pull/215520

Fold selects of the form
  select C, (binop X, Y), X
into
  binop X, (select C, Y, 0)

Support ADD, OR, XOR, and eligible SUB patterns while preserving the operand-order restrictions of SUB.

>From 92e692e2b56c25feac4976e26138c9e681ed5a08 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Tue, 11 Aug 2026 15:49:18 +0800
Subject: [PATCH] [LoongArch] Fold selects sharing operands with binary
 operations

Fold selects of the form
  select C, (binop X, Y), X
into
  binop X, (select C, Y, 0)

Support ADD, OR, XOR, and eligible SUB patterns while preserving the
operand-order restrictions of SUB.
---
 .../LoongArch/LoongArchISelLowering.cpp       | 137 +++++++++
 .../LoongArch/atomicrmw-cond-sub-clamp.ll     |  24 +-
 .../CodeGen/LoongArch/select-binop-combine.ll | 268 +++++++-----------
 llvm/test/CodeGen/LoongArch/sextw-removal.ll  |  42 ++-
 4 files changed, 258 insertions(+), 213 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index e4a369c096545..612ec12a2ef54 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -512,6 +512,17 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
   setTargetDAGCombine(ISD::SRL);
   setTargetDAGCombine(ISD::SETCC);
 
+  // On targets with the 32S feature, `select` is expanded into
+  // maskeqz + masknez + or (3 instructions), which is more expensive than
+  // on most other architectures where a single cmov-like instruction
+  // suffices. Enable a combine that can turn
+  //   select cond, binop(X, Y), X   ->  binop X, (select cond, Y, 0)
+  //   select cond, X, binop(X, Y)   ->  binop X, (select cond, 0, Y)
+  // for binop in {add, or, xor, sub}, replacing the 3-insn select (plus
+  // the original binop) with a single mask instruction plus the binop.
+  if (Subtarget.has32S())
+    setTargetDAGCombine(ISD::SELECT);
+
   // Set DAG combine for 'LSX' feature.
 
   if (Subtarget.hasExtLSX()) {
@@ -7212,6 +7223,130 @@ static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG,
   return SDValue(N, 0);
 }
 
+// Strip a single outer ISD::SIGN_EXTEND_INREG from \p V, if present, and
+// return the inner value together with the narrow VT it was extending
+// from. If no such node is present, returns \p V unchanged and an invalid
+// EVT.
+//
+// i32 (and other sub-GRLen) arithmetic is legalized to operate on the full
+// GRLen-width register, with a `sign_extend_inreg` re-normalizing the
+// result back into the narrow type's range afterwards (see e.g. the
+// `add i32` -> `add` + `sign_extend_inreg ..., i32` legalization). Any
+// combine that reassociates such a binop must track and reapply this
+// extension, otherwise the transformed code can produce a value whose
+// high bits no longer match the narrow-type semantics.
+static std::pair<SDValue, EVT> stripSignExtendInReg(SDValue V) {
+  if (V.getOpcode() == ISD::SIGN_EXTEND_INREG)
+    return {V.getOperand(0), cast<VTSDNode>(V.getOperand(1))->getVT()};
+  return {V, EVT()};
+}
+
+// Try to match \p BinV (after optionally stripping an outer
+// sign_extend_inreg) as a supported binary operation that has \p X as one
+// of its operands, returning the matched opcode, the other operand (the
+// "delta"), and the narrow VT of the sign_extend_inreg that was stripped
+// (invalid EVT if none was present).
+//
+// For commutative ops (add/or/xor), \p X may be either operand, since
+// `binop(X, Y) == binop(Y, X)` and the identity element (0) works on
+// either side.
+//
+// For `sub`, the operation is NOT commutative: `sub(X, Y) != sub(Y, X)`.
+// Only `sub(X, Y)` (i.e. \p X is the *minuend*, the first operand) can be
+// rewritten using the identity `X - 0 == X`. If \p X were the *subtrahend*
+// (second operand, i.e. the pattern is actually `sub(Y, X)`), there is no
+// way to express `cond ? (Y - X) : X` (or the symmetric case) as
+// `X op (select ...)` without introducing an extra negation, so that case
+// must be rejected instead of "optimized" into worse code.
+static std::tuple<unsigned, SDValue, EVT>
+matchBinOpWithSharedOperand(SDValue BinV, SDValue X) {
+  auto [Inner, ExtVT] = stripSignExtendInReg(BinV);
+
+  unsigned Opc = Inner.getOpcode();
+  switch (Opc) {
+  case ISD::ADD:
+  case ISD::OR:
+  case ISD::XOR:
+    if (Inner.getOperand(0) == X)
+      return {Opc, Inner.getOperand(1), ExtVT};
+    if (Inner.getOperand(1) == X)
+      return {Opc, Inner.getOperand(0), ExtVT};
+    return {0, SDValue(), EVT()};
+  case ISD::SUB:
+    // Only accept X as the minuend (first operand); see comment above.
+    if (Inner.getOperand(0) == X)
+      return {Opc, Inner.getOperand(1), ExtVT};
+    return {0, SDValue(), EVT()};
+  default:
+    return {0, SDValue(), EVT()};
+  }
+}
+
+// Try to combine:
+//   select cond, binop(X, Y), X  -> binop X, (select cond, Y, 0)
+//   select cond, X, binop(X, Y)  -> binop X, (select cond, 0, Y)
+// for binop in {add, or, xor, sub}, where 0 is the identity element of the
+// respective operation, additionally handling the common legalized form
+// where the binop result is wrapped in a `sign_extend_inreg` (as happens
+// for sub-GRLen types such as i32 on a 64-bit GRLen target). See
+// matchBinOpWithSharedOperand() for the restrictions applied to
+// non-commutative operations (currently only `sub`).
+static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
+                                    TargetLowering::DAGCombinerInfo &DCI,
+                                    const LoongArchSubtarget &Subtarget) {
+  if (DCI.isBeforeLegalizeOps())
+    return SDValue();
+
+  EVT VT = N->getValueType(0);
+  // Restrict to the scalar GRLen integer type that maskeqz/masknez operate
+  // on; this also naturally excludes float and vector selects.
+  if (VT != Subtarget.getGRLenVT())
+    return SDValue();
+
+  SDValue Cond = N->getOperand(0);
+  SDValue TrueV = N->getOperand(1);
+  SDValue FalseV = N->getOperand(2);
+  SDLoc DL(N);
+
+  auto TryFold = [&](SDValue BinV, SDValue SharedV,
+                     bool BinIsTrueArm) -> SDValue {
+    auto [Opc, Delta, ExtVT] = matchBinOpWithSharedOperand(BinV, SharedV);
+    if (!Opc)
+      return SDValue();
+
+    // Avoid infinite combine loops: bail out if Delta is trivially the
+    // same node we would otherwise be selecting on (shouldn't normally
+    // happen, but guards against degenerate/self-referential IR).
+    if (Delta.getNode() == N)
+      return SDValue();
+
+    SDValue Zero = DAG.getConstant(0, DL, VT);
+    SDValue NewSel = BinIsTrueArm ? DAG.getSelect(DL, VT, Cond, Delta, Zero)
+                                  : DAG.getSelect(DL, VT, Cond, Zero, Delta);
+    SDValue NewBin = DAG.getNode(Opc, DL, VT, SharedV, NewSel);
+
+    // If the original binop result was normalized back into a narrower
+    // type via sign_extend_inreg (e.g. i32 arithmetic on a 64-bit GRLen
+    // target), the new binop must be re-normalized the same way: SharedV
+    // is already known-sign-extended for that narrow type, but NewSel
+    // (Delta or 0, selected) combined with SharedV via Opc can still
+    // produce a 64-bit result whose high bits don't match the narrow
+    // type's sign-extended representation.
+    if (ExtVT != EVT())
+      NewBin = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, NewBin,
+                           DAG.getValueType(ExtVT));
+
+    return NewBin;
+  };
+
+  if (SDValue R = TryFold(TrueV, FalseV, /*BinIsTrueArm=*/true))
+    return R;
+  if (SDValue R = TryFold(FalseV, TrueV, /*BinIsTrueArm=*/false))
+    return R;
+
+  return SDValue();
+}
+
 // Combine (loongarch_bitrev_w (loongarch_revb_2w X)) to loongarch_bitrev_4b.
 static SDValue performBITREV_WCombine(SDNode *N, SelectionDAG &DAG,
                                       TargetLowering::DAGCombinerInfo &DCI,
@@ -8677,6 +8812,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
     return performORCombine(N, DAG, DCI, Subtarget);
   case ISD::SETCC:
     return performSETCCCombine(N, DAG, DCI, Subtarget);
+  case ISD::SELECT:
+    return performSELECTCombine(N, DAG, DCI, Subtarget);
   case ISD::SHL:
     return performSHLCombine(N, DAG, DCI, Subtarget);
   case ISD::SRL:
diff --git a/llvm/test/CodeGen/LoongArch/atomicrmw-cond-sub-clamp.ll b/llvm/test/CodeGen/LoongArch/atomicrmw-cond-sub-clamp.ll
index ab09cc9ed50a0..ca54e89e26299 100644
--- a/llvm/test/CodeGen/LoongArch/atomicrmw-cond-sub-clamp.ll
+++ b/llvm/test/CodeGen/LoongArch/atomicrmw-cond-sub-clamp.ll
@@ -21,10 +21,8 @@ define i8 @atomicrmw_usub_cond_i8(ptr %ptr, i8 %val) {
 ; LA64-NEXT:    andi $a7, $a5, 255
 ; LA64-NEXT:    sltu $a7, $a7, $a4
 ; LA64-NEXT:    xori $a7, $a7, 1
-; LA64-NEXT:    sub.d $t0, $a5, $a1
-; LA64-NEXT:    masknez $a5, $a5, $a7
-; LA64-NEXT:    maskeqz $a7, $t0, $a7
-; LA64-NEXT:    or $a5, $a7, $a5
+; LA64-NEXT:    maskeqz $a7, $a1, $a7
+; LA64-NEXT:    sub.d $a5, $a5, $a7
 ; LA64-NEXT:    andi $a5, $a5, 255
 ; LA64-NEXT:    sll.w $a5, $a5, $a2
 ; LA64-NEXT:    and $a7, $a6, $a3
@@ -74,10 +72,8 @@ define i16 @atomicrmw_usub_cond_i16(ptr %ptr, i16 %val) {
 ; LA64-NEXT:    bstrpick.d $a7, $a5, 15, 0
 ; LA64-NEXT:    sltu $a7, $a7, $a4
 ; LA64-NEXT:    xori $a7, $a7, 1
-; LA64-NEXT:    sub.d $t0, $a5, $a1
-; LA64-NEXT:    masknez $a5, $a5, $a7
-; LA64-NEXT:    maskeqz $a7, $t0, $a7
-; LA64-NEXT:    or $a5, $a7, $a5
+; LA64-NEXT:    maskeqz $a7, $a1, $a7
+; LA64-NEXT:    sub.d $a5, $a5, $a7
 ; LA64-NEXT:    bstrpick.d $a5, $a5, 15, 0
 ; LA64-NEXT:    sll.w $a5, $a5, $a2
 ; LA64-NEXT:    and $a7, $a6, $a3
@@ -118,10 +114,8 @@ define i32 @atomicrmw_usub_cond_i32(ptr %ptr, i32 %val) {
 ; LA64-NEXT:    move $a4, $a2
 ; LA64-NEXT:    sltu $a2, $a2, $a3
 ; LA64-NEXT:    xori $a2, $a2, 1
-; LA64-NEXT:    sub.w $a5, $a4, $a1
-; LA64-NEXT:    maskeqz $a5, $a5, $a2
-; LA64-NEXT:    masknez $a2, $a4, $a2
-; LA64-NEXT:    or $a5, $a5, $a2
+; LA64-NEXT:    maskeqz $a2, $a1, $a2
+; LA64-NEXT:    sub.w $a5, $a4, $a2
 ; LA64-NEXT:  .LBB2_3: # %atomicrmw.start
 ; LA64-NEXT:    # Parent Loop BB2_1 Depth=1
 ; LA64-NEXT:    # => This Inner Loop Header: Depth=2
@@ -157,10 +151,8 @@ define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) {
 ; LA64-NEXT:    move $a3, $a2
 ; LA64-NEXT:    sltu $a2, $a2, $a1
 ; LA64-NEXT:    xori $a2, $a2, 1
-; LA64-NEXT:    sub.d $a4, $a3, $a1
-; LA64-NEXT:    maskeqz $a4, $a4, $a2
-; LA64-NEXT:    masknez $a2, $a3, $a2
-; LA64-NEXT:    or $a4, $a4, $a2
+; LA64-NEXT:    maskeqz $a2, $a1, $a2
+; LA64-NEXT:    sub.d $a4, $a3, $a2
 ; LA64-NEXT:  .LBB3_3: # %atomicrmw.start
 ; LA64-NEXT:    # Parent Loop BB3_1 Depth=1
 ; LA64-NEXT:    # => This Inner Loop Header: Depth=2
diff --git a/llvm/test/CodeGen/LoongArch/select-binop-combine.ll b/llvm/test/CodeGen/LoongArch/select-binop-combine.ll
index 14631056f8948..b85ec309e6029 100644
--- a/llvm/test/CodeGen/LoongArch/select-binop-combine.ll
+++ b/llvm/test/CodeGen/LoongArch/select-binop-combine.ll
@@ -9,25 +9,22 @@ define i64 @add_lhs_true(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwin
 ; LA32-LABEL: add_lhs_true:
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    add.w $a3, $a1, $a3
-; LA32-NEXT:    add.w $a2, $a0, $a2
-; LA32-NEXT:    sltu $a6, $a2, $a0
+; LA32-NEXT:    add.w $a6, $a0, $a2
+; LA32-NEXT:    sltu $a6, $a6, $a0
 ; LA32-NEXT:    add.w $a3, $a3, $a6
 ; LA32-NEXT:    slt $a4, $a4, $a5
-; LA32-NEXT:    maskeqz $a2, $a2, $a4
-; LA32-NEXT:    masknez $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a2, $a0
-; LA32-NEXT:    maskeqz $a2, $a3, $a4
+; LA32-NEXT:    maskeqz $a3, $a3, $a4
 ; LA32-NEXT:    masknez $a1, $a1, $a4
-; LA32-NEXT:    or $a1, $a2, $a1
+; LA32-NEXT:    or $a1, $a3, $a1
+; LA32-NEXT:    maskeqz $a2, $a2, $a4
+; LA32-NEXT:    add.w $a0, $a0, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: add_lhs_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    add.d $a1, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    maskeqz $a1, $a1, $a2
-; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a1, $a0
+; LA64-NEXT:    add.d $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = add i64 %a, %b
@@ -41,24 +38,21 @@ define i64 @add_rhs_true(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwin
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    add.w $a1, $a1, $a3
 ; LA32-NEXT:    add.w $a6, $a0, $a2
-; LA32-NEXT:    sltu $a0, $a6, $a0
-; LA32-NEXT:    add.w $a1, $a1, $a0
+; LA32-NEXT:    sltu $a6, $a6, $a0
+; LA32-NEXT:    add.w $a1, $a1, $a6
 ; LA32-NEXT:    slt $a4, $a4, $a5
-; LA32-NEXT:    maskeqz $a0, $a6, $a4
-; LA32-NEXT:    masknez $a2, $a2, $a4
-; LA32-NEXT:    or $a0, $a0, $a2
 ; LA32-NEXT:    maskeqz $a1, $a1, $a4
-; LA32-NEXT:    masknez $a2, $a3, $a4
-; LA32-NEXT:    or $a1, $a1, $a2
+; LA32-NEXT:    masknez $a3, $a3, $a4
+; LA32-NEXT:    or $a1, $a1, $a3
+; LA32-NEXT:    maskeqz $a0, $a0, $a4
+; LA32-NEXT:    add.w $a0, $a2, $a0
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: add_rhs_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    add.d $a0, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    maskeqz $a0, $a0, $a2
-; LA64-NEXT:    masknez $a1, $a1, $a2
-; LA64-NEXT:    or $a0, $a0, $a1
+; LA64-NEXT:    add.d $a0, $a1, $a0
 ; LA64-NEXT:    ret
 entry:
   %0 = add i64 %a, %b
@@ -71,25 +65,22 @@ define i64 @add_lhs_false(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwi
 ; LA32-LABEL: add_lhs_false:
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    add.w $a3, $a1, $a3
-; LA32-NEXT:    add.w $a2, $a0, $a2
-; LA32-NEXT:    sltu $a6, $a2, $a0
+; LA32-NEXT:    add.w $a6, $a0, $a2
+; LA32-NEXT:    sltu $a6, $a6, $a0
 ; LA32-NEXT:    add.w $a3, $a3, $a6
 ; LA32-NEXT:    slt $a4, $a4, $a5
-; LA32-NEXT:    masknez $a2, $a2, $a4
-; LA32-NEXT:    maskeqz $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a0, $a2
-; LA32-NEXT:    masknez $a2, $a3, $a4
+; LA32-NEXT:    masknez $a3, $a3, $a4
 ; LA32-NEXT:    maskeqz $a1, $a1, $a4
-; LA32-NEXT:    or $a1, $a1, $a2
+; LA32-NEXT:    or $a1, $a1, $a3
+; LA32-NEXT:    masknez $a2, $a2, $a4
+; LA32-NEXT:    add.w $a0, $a0, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: add_lhs_false:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    add.d $a1, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    masknez $a1, $a1, $a2
-; LA64-NEXT:    maskeqz $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a0, $a1
+; LA64-NEXT:    add.d $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = add i64 %a, %b
@@ -103,24 +94,21 @@ define i64 @add_rhs_false(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwi
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    add.w $a1, $a1, $a3
 ; LA32-NEXT:    add.w $a6, $a0, $a2
-; LA32-NEXT:    sltu $a0, $a6, $a0
-; LA32-NEXT:    add.w $a1, $a1, $a0
+; LA32-NEXT:    sltu $a6, $a6, $a0
+; LA32-NEXT:    add.w $a1, $a1, $a6
 ; LA32-NEXT:    slt $a4, $a4, $a5
-; LA32-NEXT:    masknez $a0, $a6, $a4
-; LA32-NEXT:    maskeqz $a2, $a2, $a4
-; LA32-NEXT:    or $a0, $a2, $a0
 ; LA32-NEXT:    masknez $a1, $a1, $a4
-; LA32-NEXT:    maskeqz $a2, $a3, $a4
-; LA32-NEXT:    or $a1, $a2, $a1
+; LA32-NEXT:    maskeqz $a3, $a3, $a4
+; LA32-NEXT:    or $a1, $a3, $a1
+; LA32-NEXT:    masknez $a0, $a0, $a4
+; LA32-NEXT:    add.w $a0, $a2, $a0
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: add_rhs_false:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    add.d $a0, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    maskeqz $a1, $a1, $a2
-; LA64-NEXT:    or $a0, $a1, $a0
+; LA64-NEXT:    add.d $a0, $a1, $a0
 ; LA64-NEXT:    ret
 entry:
   %0 = add i64 %a, %b
@@ -134,24 +122,18 @@ entry:
 define i64 @or_lhs_true(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: or_lhs_true:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    or $a3, $a1, $a3
-; LA32-NEXT:    or $a2, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
 ; LA32-NEXT:    maskeqz $a2, $a2, $a4
-; LA32-NEXT:    masknez $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a2, $a0
+; LA32-NEXT:    or $a0, $a0, $a2
 ; LA32-NEXT:    maskeqz $a2, $a3, $a4
-; LA32-NEXT:    masknez $a1, $a1, $a4
-; LA32-NEXT:    or $a1, $a2, $a1
+; LA32-NEXT:    or $a1, $a1, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: or_lhs_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    or $a1, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    maskeqz $a1, $a1, $a2
-; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a1, $a0
+; LA64-NEXT:    or $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = or i64 %a, %b
@@ -163,24 +145,18 @@ entry:
 define i64 @or_rhs_true(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: or_rhs_true:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    or $a1, $a1, $a3
-; LA32-NEXT:    or $a0, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
 ; LA32-NEXT:    maskeqz $a0, $a0, $a4
-; LA32-NEXT:    masknez $a2, $a2, $a4
-; LA32-NEXT:    or $a0, $a0, $a2
+; LA32-NEXT:    or $a0, $a2, $a0
 ; LA32-NEXT:    maskeqz $a1, $a1, $a4
-; LA32-NEXT:    masknez $a2, $a3, $a4
-; LA32-NEXT:    or $a1, $a1, $a2
+; LA32-NEXT:    or $a1, $a3, $a1
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: or_rhs_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    or $a0, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    maskeqz $a0, $a0, $a2
-; LA64-NEXT:    masknez $a1, $a1, $a2
-; LA64-NEXT:    or $a0, $a0, $a1
+; LA64-NEXT:    or $a0, $a1, $a0
 ; LA64-NEXT:    ret
 entry:
   %0 = or i64 %a, %b
@@ -192,23 +168,17 @@ entry:
 define i64 @or_lhs_false(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: or_lhs_false:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    or $a3, $a1, $a3
-; LA32-NEXT:    or $a2, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
 ; LA32-NEXT:    masknez $a2, $a2, $a4
-; LA32-NEXT:    maskeqz $a0, $a0, $a4
 ; LA32-NEXT:    or $a0, $a0, $a2
 ; LA32-NEXT:    masknez $a2, $a3, $a4
-; LA32-NEXT:    maskeqz $a1, $a1, $a4
 ; LA32-NEXT:    or $a1, $a1, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: or_lhs_false:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    or $a1, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    masknez $a1, $a1, $a2
-; LA64-NEXT:    maskeqz $a0, $a0, $a2
 ; LA64-NEXT:    or $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
@@ -221,23 +191,17 @@ entry:
 define i64 @or_rhs_false(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: or_rhs_false:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    or $a1, $a1, $a3
-; LA32-NEXT:    or $a0, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
 ; LA32-NEXT:    masknez $a0, $a0, $a4
-; LA32-NEXT:    maskeqz $a2, $a2, $a4
 ; LA32-NEXT:    or $a0, $a2, $a0
 ; LA32-NEXT:    masknez $a1, $a1, $a4
-; LA32-NEXT:    maskeqz $a2, $a3, $a4
-; LA32-NEXT:    or $a1, $a2, $a1
+; LA32-NEXT:    or $a1, $a3, $a1
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: or_rhs_false:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    or $a0, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    maskeqz $a1, $a1, $a2
 ; LA64-NEXT:    or $a0, $a1, $a0
 ; LA64-NEXT:    ret
 entry:
@@ -250,24 +214,18 @@ entry:
 define i64 @xor_lhs_true(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: xor_lhs_true:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    xor $a3, $a1, $a3
-; LA32-NEXT:    xor $a2, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
 ; LA32-NEXT:    maskeqz $a2, $a2, $a4
-; LA32-NEXT:    masknez $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a2, $a0
+; LA32-NEXT:    xor $a0, $a0, $a2
 ; LA32-NEXT:    maskeqz $a2, $a3, $a4
-; LA32-NEXT:    masknez $a1, $a1, $a4
-; LA32-NEXT:    or $a1, $a2, $a1
+; LA32-NEXT:    xor $a1, $a1, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: xor_lhs_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    xor $a1, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    maskeqz $a1, $a1, $a2
-; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a1, $a0
+; LA64-NEXT:    xor $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = xor i64 %a, %b
@@ -279,24 +237,18 @@ entry:
 define i64 @xor_rhs_true(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: xor_rhs_true:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    xor $a1, $a1, $a3
-; LA32-NEXT:    xor $a0, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
 ; LA32-NEXT:    maskeqz $a0, $a0, $a4
-; LA32-NEXT:    masknez $a2, $a2, $a4
-; LA32-NEXT:    or $a0, $a0, $a2
+; LA32-NEXT:    xor $a0, $a2, $a0
 ; LA32-NEXT:    maskeqz $a1, $a1, $a4
-; LA32-NEXT:    masknez $a2, $a3, $a4
-; LA32-NEXT:    or $a1, $a1, $a2
+; LA32-NEXT:    xor $a1, $a3, $a1
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: xor_rhs_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    xor $a0, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    maskeqz $a0, $a0, $a2
-; LA64-NEXT:    masknez $a1, $a1, $a2
-; LA64-NEXT:    or $a0, $a0, $a1
+; LA64-NEXT:    xor $a0, $a1, $a0
 ; LA64-NEXT:    ret
 entry:
   %0 = xor i64 %a, %b
@@ -308,24 +260,18 @@ entry:
 define i64 @xor_lhs_false(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: xor_lhs_false:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    xor $a3, $a1, $a3
-; LA32-NEXT:    xor $a2, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
 ; LA32-NEXT:    masknez $a2, $a2, $a4
-; LA32-NEXT:    maskeqz $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a0, $a2
+; LA32-NEXT:    xor $a0, $a0, $a2
 ; LA32-NEXT:    masknez $a2, $a3, $a4
-; LA32-NEXT:    maskeqz $a1, $a1, $a4
-; LA32-NEXT:    or $a1, $a1, $a2
+; LA32-NEXT:    xor $a1, $a1, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: xor_lhs_false:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    xor $a1, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    masknez $a1, $a1, $a2
-; LA64-NEXT:    maskeqz $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a0, $a1
+; LA64-NEXT:    xor $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = xor i64 %a, %b
@@ -337,24 +283,18 @@ entry:
 define i64 @xor_rhs_false(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: xor_rhs_false:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    xor $a1, $a1, $a3
-; LA32-NEXT:    xor $a0, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
 ; LA32-NEXT:    masknez $a0, $a0, $a4
-; LA32-NEXT:    maskeqz $a2, $a2, $a4
-; LA32-NEXT:    or $a0, $a2, $a0
+; LA32-NEXT:    xor $a0, $a2, $a0
 ; LA32-NEXT:    masknez $a1, $a1, $a4
-; LA32-NEXT:    maskeqz $a2, $a3, $a4
-; LA32-NEXT:    or $a1, $a2, $a1
+; LA32-NEXT:    xor $a1, $a3, $a1
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: xor_rhs_false:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    xor $a0, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    maskeqz $a1, $a1, $a2
-; LA64-NEXT:    or $a0, $a1, $a0
+; LA64-NEXT:    xor $a0, $a1, $a0
 ; LA64-NEXT:    ret
 entry:
   %0 = xor i64 %a, %b
@@ -375,23 +315,19 @@ define i64 @sub_minuend_true(i64 %a, i64 %b, i32 signext %c, i32 signext %d) nou
 ; LA32-NEXT:    sltu $a6, $a0, $a2
 ; LA32-NEXT:    sub.w $a3, $a1, $a3
 ; LA32-NEXT:    sub.w $a3, $a3, $a6
-; LA32-NEXT:    sub.w $a2, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
-; LA32-NEXT:    maskeqz $a2, $a2, $a4
-; LA32-NEXT:    masknez $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a2, $a0
-; LA32-NEXT:    maskeqz $a2, $a3, $a4
+; LA32-NEXT:    maskeqz $a3, $a3, $a4
 ; LA32-NEXT:    masknez $a1, $a1, $a4
-; LA32-NEXT:    or $a1, $a2, $a1
+; LA32-NEXT:    or $a1, $a3, $a1
+; LA32-NEXT:    maskeqz $a2, $a2, $a4
+; LA32-NEXT:    sub.w $a0, $a0, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: sub_minuend_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    sub.d $a1, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    maskeqz $a1, $a1, $a2
-; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a1, $a0
+; LA64-NEXT:    sub.d $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = sub i64 %a, %b
@@ -406,23 +342,19 @@ define i64 @sub_minuend_false(i64 %a, i64 %b, i32 signext %c, i32 signext %d) no
 ; LA32-NEXT:    sltu $a6, $a0, $a2
 ; LA32-NEXT:    sub.w $a3, $a1, $a3
 ; LA32-NEXT:    sub.w $a3, $a3, $a6
-; LA32-NEXT:    sub.w $a2, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
-; LA32-NEXT:    masknez $a2, $a2, $a4
-; LA32-NEXT:    maskeqz $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a0, $a2
-; LA32-NEXT:    masknez $a2, $a3, $a4
+; LA32-NEXT:    masknez $a3, $a3, $a4
 ; LA32-NEXT:    maskeqz $a1, $a1, $a4
-; LA32-NEXT:    or $a1, $a1, $a2
+; LA32-NEXT:    or $a1, $a1, $a3
+; LA32-NEXT:    masknez $a2, $a2, $a4
+; LA32-NEXT:    sub.w $a0, $a0, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: sub_minuend_false:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    sub.d $a1, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
 ; LA64-NEXT:    masknez $a1, $a1, $a2
-; LA64-NEXT:    maskeqz $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a0, $a1
+; LA64-NEXT:    sub.d $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = sub i64 %a, %b
@@ -573,30 +505,28 @@ define i64 @add_lhs_true_multi_use(i64 %a, i64 %b, i32 signext %c, i32 signext %
 ; LA32-LABEL: add_lhs_true_multi_use:
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    add.w $a3, $a1, $a3
-; LA32-NEXT:    add.w $a2, $a0, $a2
-; LA32-NEXT:    sltu $a6, $a2, $a0
-; LA32-NEXT:    add.w $a3, $a3, $a6
+; LA32-NEXT:    add.w $a6, $a0, $a2
+; LA32-NEXT:    sltu $a7, $a6, $a0
+; LA32-NEXT:    add.w $a3, $a3, $a7
 ; LA32-NEXT:    slt $a4, $a4, $a5
-; LA32-NEXT:    maskeqz $a5, $a2, $a4
-; LA32-NEXT:    masknez $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a5, $a0
 ; LA32-NEXT:    maskeqz $a5, $a3, $a4
 ; LA32-NEXT:    masknez $a1, $a1, $a4
 ; LA32-NEXT:    or $a1, $a5, $a1
+; LA32-NEXT:    maskeqz $a2, $a2, $a4
+; LA32-NEXT:    add.w $a0, $a0, $a2
 ; LA32-NEXT:    add.w $a1, $a3, $a1
-; LA32-NEXT:    add.w $a0, $a2, $a0
-; LA32-NEXT:    sltu $a2, $a0, $a2
+; LA32-NEXT:    add.w $a0, $a6, $a0
+; LA32-NEXT:    sltu $a2, $a0, $a6
 ; LA32-NEXT:    add.w $a1, $a1, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: add_lhs_true_multi_use:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    add.d $a1, $a0, $a1
+; LA64-NEXT:    add.d $a4, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
-; LA64-NEXT:    maskeqz $a3, $a1, $a2
-; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a3, $a0
-; LA64-NEXT:    add.d $a0, $a1, $a0
+; LA64-NEXT:    maskeqz $a1, $a1, $a2
+; LA64-NEXT:    add.d $a0, $a0, $a1
+; LA64-NEXT:    add.d $a0, $a4, $a0
 ; LA64-NEXT:    ret
 entry:
   %0 = add i64 %a, %b
@@ -612,28 +542,26 @@ define i64 @sub_minuend_true_multi_use(i64 %a, i64 %b, i32 signext %c, i32 signe
 ; LA32-NEXT:    sltu $a6, $a0, $a2
 ; LA32-NEXT:    sub.w $a3, $a1, $a3
 ; LA32-NEXT:    sub.w $a3, $a3, $a6
-; LA32-NEXT:    sub.w $a2, $a0, $a2
+; LA32-NEXT:    sub.w $a6, $a0, $a2
 ; LA32-NEXT:    slt $a4, $a4, $a5
-; LA32-NEXT:    maskeqz $a5, $a2, $a4
-; LA32-NEXT:    masknez $a0, $a0, $a4
-; LA32-NEXT:    or $a0, $a5, $a0
 ; LA32-NEXT:    maskeqz $a5, $a3, $a4
 ; LA32-NEXT:    masknez $a1, $a1, $a4
 ; LA32-NEXT:    or $a1, $a5, $a1
+; LA32-NEXT:    maskeqz $a2, $a2, $a4
+; LA32-NEXT:    sub.w $a0, $a0, $a2
 ; LA32-NEXT:    add.w $a1, $a3, $a1
-; LA32-NEXT:    add.w $a0, $a2, $a0
-; LA32-NEXT:    sltu $a2, $a0, $a2
+; LA32-NEXT:    add.w $a0, $a6, $a0
+; LA32-NEXT:    sltu $a2, $a0, $a6
 ; LA32-NEXT:    add.w $a1, $a1, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: sub_minuend_true_multi_use:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    sub.d $a1, $a0, $a1
+; LA64-NEXT:    sub.d $a4, $a0, $a1
 ; LA64-NEXT:    slt $a2, $a2, $a3
-; LA64-NEXT:    maskeqz $a3, $a1, $a2
-; LA64-NEXT:    masknez $a0, $a0, $a2
-; LA64-NEXT:    or $a0, $a3, $a0
-; LA64-NEXT:    add.d $a0, $a1, $a0
+; LA64-NEXT:    maskeqz $a1, $a1, $a2
+; LA64-NEXT:    sub.d $a0, $a0, $a1
+; LA64-NEXT:    add.d $a0, $a4, $a0
 ; LA64-NEXT:    ret
 entry:
   %0 = sub i64 %a, %b
@@ -689,24 +617,21 @@ define i64 @add_imm_true(i64 %a, i32 signext %c, i32 signext %d) nounwind {
 ; LA32-LABEL: add_imm_true:
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    addi.w $a4, $a0, 5
-; LA32-NEXT:    sltu $a5, $a4, $a0
-; LA32-NEXT:    add.w $a5, $a1, $a5
+; LA32-NEXT:    sltu $a4, $a4, $a0
 ; LA32-NEXT:    slt $a2, $a2, $a3
 ; LA32-NEXT:    masknez $a3, $a4, $a2
-; LA32-NEXT:    maskeqz $a0, $a0, $a2
-; LA32-NEXT:    or $a0, $a0, $a3
-; LA32-NEXT:    masknez $a3, $a5, $a2
-; LA32-NEXT:    maskeqz $a1, $a1, $a2
-; LA32-NEXT:    or $a1, $a1, $a3
+; LA32-NEXT:    add.w $a1, $a1, $a3
+; LA32-NEXT:    ori $a3, $zero, 5
+; LA32-NEXT:    masknez $a2, $a3, $a2
+; LA32-NEXT:    add.w $a0, $a0, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: add_imm_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    addi.d $a3, $a0, 5
 ; LA64-NEXT:    slt $a1, $a1, $a2
-; LA64-NEXT:    masknez $a2, $a3, $a1
-; LA64-NEXT:    maskeqz $a0, $a0, $a1
-; LA64-NEXT:    or $a0, $a0, $a2
+; LA64-NEXT:    ori $a2, $zero, 5
+; LA64-NEXT:    masknez $a1, $a2, $a1
+; LA64-NEXT:    add.d $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = add i64 %a, 5
@@ -720,25 +645,24 @@ define i64 @sub_imm_minuend_true(i64 %a, i32 signext %c, i32 signext %d) nounwin
 ; LA32-LABEL: sub_imm_minuend_true:
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    addi.w $a4, $a0, -5
-; LA32-NEXT:    sltu $a5, $a4, $a0
-; LA32-NEXT:    add.w $a5, $a1, $a5
-; LA32-NEXT:    addi.w $a5, $a5, -1
+; LA32-NEXT:    sltu $a4, $a4, $a0
+; LA32-NEXT:    add.w $a4, $a1, $a4
+; LA32-NEXT:    addi.w $a4, $a4, -1
 ; LA32-NEXT:    slt $a2, $a2, $a3
 ; LA32-NEXT:    masknez $a3, $a4, $a2
-; LA32-NEXT:    maskeqz $a0, $a0, $a2
-; LA32-NEXT:    or $a0, $a0, $a3
-; LA32-NEXT:    masknez $a3, $a5, $a2
 ; LA32-NEXT:    maskeqz $a1, $a1, $a2
 ; LA32-NEXT:    or $a1, $a1, $a3
+; LA32-NEXT:    addi.w $a3, $zero, -5
+; LA32-NEXT:    masknez $a2, $a3, $a2
+; LA32-NEXT:    add.w $a0, $a0, $a2
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: sub_imm_minuend_true:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    addi.d $a3, $a0, -5
 ; LA64-NEXT:    slt $a1, $a1, $a2
-; LA64-NEXT:    masknez $a2, $a3, $a1
-; LA64-NEXT:    maskeqz $a0, $a0, $a1
-; LA64-NEXT:    or $a0, $a0, $a2
+; LA64-NEXT:    addi.w $a2, $zero, -5
+; LA64-NEXT:    masknez $a1, $a2, $a1
+; LA64-NEXT:    add.d $a0, $a0, $a1
 ; LA64-NEXT:    ret
 entry:
   %0 = sub i64 %a, 5
@@ -786,11 +710,9 @@ entry:
 define signext i32 @add_lhs_true_i32(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d) nounwind {
 ; CHECK-LABEL: add_lhs_true_i32:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    add.w $a1, $a0, $a1
 ; CHECK-NEXT:    slt $a2, $a2, $a3
 ; CHECK-NEXT:    maskeqz $a1, $a1, $a2
-; CHECK-NEXT:    masknez $a0, $a0, $a2
-; CHECK-NEXT:    or $a0, $a1, $a0
+; CHECK-NEXT:    add.w $a0, $a0, $a1
 ; CHECK-NEXT:    ret
 entry:
   %0 = add i32 %a, %b
diff --git a/llvm/test/CodeGen/LoongArch/sextw-removal.ll b/llvm/test/CodeGen/LoongArch/sextw-removal.ll
index b8b453f205d2e..8097acfd842ad 100644
--- a/llvm/test/CodeGen/LoongArch/sextw-removal.ll
+++ b/llvm/test/CodeGen/LoongArch/sextw-removal.ll
@@ -979,34 +979,31 @@ define signext i32 @bug(i32 signext %x) {
 ; CHECK-NEXT:    bstrpick.d $a2, $a0, 31, 24
 ; CHECK-NEXT:    sltui $a2, $a2, 1
 ; CHECK-NEXT:    slli.d $a3, $a0, 8
-; CHECK-NEXT:    addi.d $a4, $a1, -8
 ; CHECK-NEXT:    masknez $a0, $a0, $a2
 ; CHECK-NEXT:    maskeqz $a3, $a3, $a2
 ; CHECK-NEXT:    or $a0, $a3, $a0
-; CHECK-NEXT:    masknez $a1, $a1, $a2
-; CHECK-NEXT:    maskeqz $a2, $a4, $a2
-; CHECK-NEXT:    or $a1, $a2, $a1
+; CHECK-NEXT:    addi.d $a3, $zero, -8
+; CHECK-NEXT:    maskeqz $a2, $a3, $a2
+; CHECK-NEXT:    add.d $a1, $a1, $a2
 ; CHECK-NEXT:    bstrpick.d $a2, $a0, 31, 28
 ; CHECK-NEXT:    sltui $a2, $a2, 1
 ; CHECK-NEXT:    slli.d $a3, $a0, 4
-; CHECK-NEXT:    addi.d $a4, $a1, -4
 ; CHECK-NEXT:    masknez $a0, $a0, $a2
 ; CHECK-NEXT:    maskeqz $a3, $a3, $a2
 ; CHECK-NEXT:    or $a0, $a3, $a0
-; CHECK-NEXT:    masknez $a1, $a1, $a2
-; CHECK-NEXT:    maskeqz $a2, $a4, $a2
-; CHECK-NEXT:    or $a1, $a2, $a1
+; CHECK-NEXT:    addi.d $a3, $zero, -4
+; CHECK-NEXT:    maskeqz $a2, $a3, $a2
+; CHECK-NEXT:    add.d $a1, $a1, $a2
 ; CHECK-NEXT:    bstrpick.d $a2, $a0, 31, 30
 ; CHECK-NEXT:    sltui $a2, $a2, 1
 ; CHECK-NEXT:    slli.d $a3, $a0, 2
-; CHECK-NEXT:    addi.d $a4, $a1, -2
 ; CHECK-NEXT:    masknez $a0, $a0, $a2
 ; CHECK-NEXT:    maskeqz $a3, $a3, $a2
 ; CHECK-NEXT:    or $a0, $a3, $a0
 ; CHECK-NEXT:    addi.w $a0, $a0, 0
-; CHECK-NEXT:    masknez $a1, $a1, $a2
-; CHECK-NEXT:    maskeqz $a2, $a4, $a2
-; CHECK-NEXT:    or $a1, $a2, $a1
+; CHECK-NEXT:    addi.d $a3, $zero, -2
+; CHECK-NEXT:    maskeqz $a2, $a3, $a2
+; CHECK-NEXT:    add.d $a1, $a1, $a2
 ; CHECK-NEXT:    nor $a0, $a0, $zero
 ; CHECK-NEXT:    srli.d $a0, $a0, 31
 ; CHECK-NEXT:    add.w $a0, $a1, $a0
@@ -1033,34 +1030,31 @@ define signext i32 @bug(i32 signext %x) {
 ; NORMV-NEXT:    bstrpick.d $a2, $a0, 31, 24
 ; NORMV-NEXT:    sltui $a2, $a2, 1
 ; NORMV-NEXT:    slli.d $a3, $a0, 8
-; NORMV-NEXT:    addi.d $a4, $a1, -8
 ; NORMV-NEXT:    masknez $a0, $a0, $a2
 ; NORMV-NEXT:    maskeqz $a3, $a3, $a2
 ; NORMV-NEXT:    or $a0, $a3, $a0
-; NORMV-NEXT:    masknez $a1, $a1, $a2
-; NORMV-NEXT:    maskeqz $a2, $a4, $a2
-; NORMV-NEXT:    or $a1, $a2, $a1
+; NORMV-NEXT:    addi.d $a3, $zero, -8
+; NORMV-NEXT:    maskeqz $a2, $a3, $a2
+; NORMV-NEXT:    add.d $a1, $a1, $a2
 ; NORMV-NEXT:    bstrpick.d $a2, $a0, 31, 28
 ; NORMV-NEXT:    sltui $a2, $a2, 1
 ; NORMV-NEXT:    slli.d $a3, $a0, 4
-; NORMV-NEXT:    addi.d $a4, $a1, -4
 ; NORMV-NEXT:    masknez $a0, $a0, $a2
 ; NORMV-NEXT:    maskeqz $a3, $a3, $a2
 ; NORMV-NEXT:    or $a0, $a3, $a0
-; NORMV-NEXT:    masknez $a1, $a1, $a2
-; NORMV-NEXT:    maskeqz $a2, $a4, $a2
-; NORMV-NEXT:    or $a1, $a2, $a1
+; NORMV-NEXT:    addi.d $a3, $zero, -4
+; NORMV-NEXT:    maskeqz $a2, $a3, $a2
+; NORMV-NEXT:    add.d $a1, $a1, $a2
 ; NORMV-NEXT:    bstrpick.d $a2, $a0, 31, 30
 ; NORMV-NEXT:    sltui $a2, $a2, 1
 ; NORMV-NEXT:    slli.d $a3, $a0, 2
-; NORMV-NEXT:    addi.d $a4, $a1, -2
 ; NORMV-NEXT:    masknez $a0, $a0, $a2
 ; NORMV-NEXT:    maskeqz $a3, $a3, $a2
 ; NORMV-NEXT:    or $a0, $a3, $a0
 ; NORMV-NEXT:    addi.w $a0, $a0, 0
-; NORMV-NEXT:    masknez $a1, $a1, $a2
-; NORMV-NEXT:    maskeqz $a2, $a4, $a2
-; NORMV-NEXT:    or $a1, $a2, $a1
+; NORMV-NEXT:    addi.d $a3, $zero, -2
+; NORMV-NEXT:    maskeqz $a2, $a3, $a2
+; NORMV-NEXT:    add.d $a1, $a1, $a2
 ; NORMV-NEXT:    nor $a0, $a0, $zero
 ; NORMV-NEXT:    srli.d $a0, $a0, 31
 ; NORMV-NEXT:    add.d $a0, $a1, $a0



More information about the llvm-branch-commits mailing list