[llvm] 6dbb050 - [LoongArch] Fold shifted vector extract comparisons (#214204)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 00:19:46 PDT 2026


Author: hev
Date: 2026-08-13T15:19:42+08:00
New Revision: 6dbb0508fec4453ba8b8801444930b15e868a507

URL: https://github.com/llvm/llvm-project/commit/6dbb0508fec4453ba8b8801444930b15e868a507
DIFF: https://github.com/llvm/llvm-project/commit/6dbb0508fec4453ba8b8801444930b15e868a507.diff

LOG: [LoongArch] Fold shifted vector extract comparisons (#214204)

Fold comparisons of the form:

  (shl (extract_vector_elt X, I), GRLen - EleBits) ==/!= 0

into:

  (extract_vector_elt X, I) ==/!= 0

When the shift amount equals `GRLen - EleBits`, the left shift only
moves the extracted element into the most significant bits without
affecting whether the value is zero. This canonicalization exposes
EXTRACT_VECTOR_ELT to later combines and enables selecting VPICKVE2GR_*
instructions directly.

Added: 
    

Modified: 
    llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
    llvm/test/CodeGen/LoongArch/lasx/vec-extract-brcond.ll
    llvm/test/CodeGen/LoongArch/lsx/vec-extract-brcond.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index e4a369c096545..3b57a338b86f2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -7297,6 +7297,23 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
     return true;
   }
 
+  // Fold ((shl (extract_vector_elt X, I), GRLen - EleBits)), 0, eq/ne) ->
+  //      ((extract_vector_elt X, I), 0, eq/ne)
+  if (isNullConstant(RHS) && (CCVal == ISD::SETEQ || CCVal == ISD::SETNE) &&
+      LHS.getOpcode() == ISD::SHL && LHS.hasOneUse() &&
+      isa<ConstantSDNode>(LHS.getOperand(1))) {
+    SDValue Ext = LHS.getOperand(0);
+    unsigned Sht = LHS.getConstantOperandVal(1);
+    if (Ext.getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
+      SDValue Vec = Ext.getOperand(0);
+      unsigned EleBits = Vec.getScalarValueSizeInBits();
+      if ((EleBits + Sht) == Subtarget.getGRLen()) {
+        LHS = Ext;
+        return true;
+      }
+    }
+  }
+
   return false;
 }
 

diff  --git a/llvm/test/CodeGen/LoongArch/lasx/vec-extract-brcond.ll b/llvm/test/CodeGen/LoongArch/lasx/vec-extract-brcond.ll
index e16d9be1a95d9..3f5ddcee5236a 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/vec-extract-brcond.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/vec-extract-brcond.ll
@@ -29,33 +29,18 @@ bb2:
 }
 
 define void @extract_16xi16_br_ne_0(ptr %src, ptr %dst) nounwind {
-; LA32-LABEL: extract_16xi16_br_ne_0:
-; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    xvld $xr0, $a0, 0
-; LA32-NEXT:    vpickve2gr.h $a0, $vr0, 0
-; LA32-NEXT:    slli.w $a0, $a0, 16
-; LA32-NEXT:    beqz $a0, .LBB1_2
-; LA32-NEXT:  # %bb.1: # %bb1
-; LA32-NEXT:    st.b $zero, $a1, 0
-; LA32-NEXT:    ret
-; LA32-NEXT:  .LBB1_2: # %bb2
-; LA32-NEXT:    ori $a0, $zero, 1
-; LA32-NEXT:    st.b $a0, $a1, 0
-; LA32-NEXT:    ret
-;
-; LA64-LABEL: extract_16xi16_br_ne_0:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    xvld $xr0, $a0, 0
-; LA64-NEXT:    vpickve2gr.h $a0, $vr0, 0
-; LA64-NEXT:    slli.d $a0, $a0, 48
-; LA64-NEXT:    beqz $a0, .LBB1_2
-; LA64-NEXT:  # %bb.1: # %bb1
-; LA64-NEXT:    st.b $zero, $a1, 0
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB1_2: # %bb2
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    st.b $a0, $a1, 0
-; LA64-NEXT:    ret
+; CHECK-LABEL: extract_16xi16_br_ne_0:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 0
+; CHECK-NEXT:    beqz $a0, .LBB1_2
+; CHECK-NEXT:  # %bb.1: # %bb1
+; CHECK-NEXT:    st.b $zero, $a1, 0
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB1_2: # %bb2
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    st.b $a0, $a1, 0
+; CHECK-NEXT:    ret
 entry:
   %0 = load volatile <16 x i16>, ptr %src
   %1 = extractelement <16 x i16> %0, i64 0

diff  --git a/llvm/test/CodeGen/LoongArch/lsx/vec-extract-brcond.ll b/llvm/test/CodeGen/LoongArch/lsx/vec-extract-brcond.ll
index e78590b3a62db..b748d48e3d341 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/vec-extract-brcond.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/vec-extract-brcond.ll
@@ -29,33 +29,18 @@ bb2:
 }
 
 define void @extract_8xi16_br_ne_0(ptr %src, ptr %dst) nounwind {
-; LA32-LABEL: extract_8xi16_br_ne_0:
-; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    vld $vr0, $a0, 0
-; LA32-NEXT:    vpickve2gr.h $a0, $vr0, 0
-; LA32-NEXT:    slli.w $a0, $a0, 16
-; LA32-NEXT:    beqz $a0, .LBB1_2
-; LA32-NEXT:  # %bb.1: # %bb1
-; LA32-NEXT:    st.b $zero, $a1, 0
-; LA32-NEXT:    ret
-; LA32-NEXT:  .LBB1_2: # %bb2
-; LA32-NEXT:    ori $a0, $zero, 1
-; LA32-NEXT:    st.b $a0, $a1, 0
-; LA32-NEXT:    ret
-;
-; LA64-LABEL: extract_8xi16_br_ne_0:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    vld $vr0, $a0, 0
-; LA64-NEXT:    vpickve2gr.h $a0, $vr0, 0
-; LA64-NEXT:    slli.d $a0, $a0, 48
-; LA64-NEXT:    beqz $a0, .LBB1_2
-; LA64-NEXT:  # %bb.1: # %bb1
-; LA64-NEXT:    st.b $zero, $a1, 0
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB1_2: # %bb2
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    st.b $a0, $a1, 0
-; LA64-NEXT:    ret
+; CHECK-LABEL: extract_8xi16_br_ne_0:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 0
+; CHECK-NEXT:    beqz $a0, .LBB1_2
+; CHECK-NEXT:  # %bb.1: # %bb1
+; CHECK-NEXT:    st.b $zero, $a1, 0
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB1_2: # %bb2
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    st.b $a0, $a1, 0
+; CHECK-NEXT:    ret
 entry:
   %0 = load volatile <8 x i16>, ptr %src
   %1 = extractelement <8 x i16> %0, i64 0


        


More information about the llvm-commits mailing list