[llvm-branch-commits] [llvm] [LoongArch] Fold shifted vector extract comparisons (PR #214204)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Aug 5 05:07:04 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: hev (heiher)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/214204.diff
3 Files Affected:
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+17)
- (modified) llvm/test/CodeGen/LoongArch/lasx/vec-extract-brcond.ll (+12-27)
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-extract-brcond.ll (+12-27)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 38f46a9fc9855..7c3cda799a697 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
``````````
</details>
https://github.com/llvm/llvm-project/pull/214204
More information about the llvm-branch-commits
mailing list