[llvm] [RISCV] Fold Bitcast long bitwidth int to vector type (PR #194788)
Zaky Hermawan via llvm-commits
llvm-commits at lists.llvm.org
Thu May 21 09:16:45 PDT 2026
https://github.com/ZakyHermawan updated https://github.com/llvm/llvm-project/pull/194788
>From e573784962c831590c62e96465e519ce04603e85 Mon Sep 17 00:00:00 2001
From: ZakyHermawan <zaky.hermawan9615 at gmail.com>
Date: Tue, 19 May 2026 13:11:24 +0700
Subject: [PATCH 1/7] Precommit test
Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll | 75 ++++++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
diff --git a/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll b/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
new file mode 100644
index 0000000000000..c4810e7e2201d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
@@ -0,0 +1,75 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv64 -mattr=+rva23u64 %s -o - | FileCheck %s
+
+define { i1, <32 x i8> } @bitcast_v32i8(ptr %a0) {
+; CHECK-LABEL: bitcast_v32i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a1, 32
+; CHECK-NEXT: vsetvli zero, a1, e8, m2, ta, ma
+; CHECK-NEXT: vle8.v v8, (a0)
+; CHECK-NEXT: vmsne.vi v10, v8, 0
+; CHECK-NEXT: vcpop.m a0, v10
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %src256 = load i256, ptr %a0, align 32
+ %src256.bitcast = bitcast i256 %src256 to <32 x i8>
+ %iszero = icmp eq i256 %src256, 0
+
+ %res1 = insertvalue { i1, <32 x i8> } poison, i1 %iszero, 0
+ %res2 = insertvalue { i1, <32 x i8> } %res1, <32 x i8> %src256.bitcast, 1
+ ret { i1, <32 x i8> } %res2
+}
+
+define { i1, <16 x i16> } @bitcast_v16i16(ptr %a0) {
+; CHECK-LABEL: bitcast_v16i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: ld a1, 0(a0)
+; CHECK-NEXT: ld a2, 8(a0)
+; CHECK-NEXT: ld a3, 16(a0)
+; CHECK-NEXT: ld a0, 24(a0)
+; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma
+; CHECK-NEXT: vmv.v.x v8, a1
+; CHECK-NEXT: vslide1down.vx v8, v8, a2
+; CHECK-NEXT: vslide1down.vx v8, v8, a3
+; CHECK-NEXT: vslide1down.vx v8, v8, a0
+; CHECK-NEXT: li a0, 32
+; CHECK-NEXT: vsetvli zero, a0, e8, m2, ta, ma
+; CHECK-NEXT: vmsne.vi v10, v8, 0
+; CHECK-NEXT: vcpop.m a0, v10
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %src256 = load i256, ptr %a0, align 32
+ %src256.bitcast = bitcast i256 %src256 to <16 x i16>
+ %iszero = icmp eq i256 %src256, 0
+
+ %res1 = insertvalue { i1, <16 x i16> } poison, i1 %iszero, 0
+ %res2 = insertvalue { i1, <16 x i16> } %res1, <16 x i16> %src256.bitcast, 1
+ ret { i1, <16 x i16> } %res2
+}
+
+define { i1, <8 x i32> } @bitcast_v8i32(ptr %a0) {
+; CHECK-LABEL: bitcast_v8i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: ld a1, 0(a0)
+; CHECK-NEXT: ld a2, 8(a0)
+; CHECK-NEXT: ld a3, 16(a0)
+; CHECK-NEXT: ld a0, 24(a0)
+; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma
+; CHECK-NEXT: vmv.v.x v8, a1
+; CHECK-NEXT: vslide1down.vx v8, v8, a2
+; CHECK-NEXT: vslide1down.vx v8, v8, a3
+; CHECK-NEXT: vslide1down.vx v8, v8, a0
+; CHECK-NEXT: li a0, 32
+; CHECK-NEXT: vsetvli zero, a0, e8, m2, ta, ma
+; CHECK-NEXT: vmsne.vi v10, v8, 0
+; CHECK-NEXT: vcpop.m a0, v10
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %src256 = load i256, ptr %a0, align 32
+ %src256.bitcast = bitcast i256 %src256 to <8 x i32>
+ %iszero = icmp eq i256 %src256, 0
+
+ %res1 = insertvalue { i1, <8 x i32> } poison, i1 %iszero, 0
+ %res2 = insertvalue { i1, <8 x i32> } %res1, <8 x i32> %src256.bitcast, 1
+ ret { i1, <8 x i32> } %res2
+}
>From a7b9d881f8781a233cbe9bb8bab3bf1fd8d08e2c Mon Sep 17 00:00:00 2001
From: ZakyHermawan <zaky.hermawan9615 at gmail.com>
Date: Tue, 19 May 2026 13:15:08 +0700
Subject: [PATCH 2/7] [RISCV] Apply fix
Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 51 +++++++++++++++++++--
llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll | 26 ++---------
2 files changed, 51 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 26281a8976fcf..8b657a719804e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -17625,14 +17625,57 @@ combineVectorSizedSetCCEquality(EVT VT, SDValue X, SDValue Y, ISD::CondCode CC,
if (!OpVT.isByteSized())
return SDValue();
- unsigned VecSize = OpSize / 8;
- EVT VecVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, VecSize);
- EVT CmpVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, VecSize);
+ // Find a preferred vector element type by inspecting how the value is used.
+ auto GetPreferredEltVT = [](SDValue V) -> MVT {
+ // Look backwards: check if V itself is derived from a vector
+ SDValue Peek = peekThroughBitcasts(V);
+ if (Peek.getValueType().isVector() && Peek.getValueType().isInteger())
+ return Peek.getSimpleValueType().getVectorElementType();
+
+ // Look forwards: check if V is bitcasted to a vector elsewhere in the DAG
+ for (SDUse &Use : V->uses()) {
+ // Ensure we are checking the use of the specific value result, not the
+ // node's chain
+ if (Use.getResNo() != V.getResNo())
+ continue;
+
+ SDNode *User = Use.getUser();
+ if (User->getOpcode() == ISD::BITCAST) {
+ EVT CastVT = User->getValueType(0);
+ if (CastVT.isVector() && CastVT.isInteger())
+ return CastVT.getVectorElementType().getSimpleVT();
+ }
+ }
+ return MVT::INVALID_SIMPLE_VALUE_TYPE;
+ };
+
+ auto IsValidEltVT = [&](MVT VT) {
+ return VT != MVT::INVALID_SIMPLE_VALUE_TYPE && VT.isInteger() &&
+ VT.getSizeInBits() >= 8 &&
+ VT.getSizeInBits() <= Subtarget.getXLen() &&
+ OpSize % VT.getSizeInBits() == 0;
+ };
+
+ // Get preferred VT from either X or Y.
+ MVT EltVT = GetPreferredEltVT(X);
+ if (!IsValidEltVT(EltVT)) {
+ EltVT = GetPreferredEltVT(Y);
+ }
+
+ // If both are unsuitable, use the safe default (i8)
+ if (!IsValidEltVT(EltVT)) {
+ EltVT = MVT::i8;
+ }
+
+ unsigned EltSize = EltVT.getSizeInBits();
+ unsigned NumElts = OpSize / EltSize;
+ EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts);
+ EVT CmpVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, NumElts);
SDValue VecX = DAG.getBitcast(VecVT, X);
SDValue VecY = DAG.getBitcast(VecVT, Y);
SDValue Mask = DAG.getAllOnesConstant(DL, CmpVT);
- SDValue VL = DAG.getConstant(VecSize, DL, XLenVT);
+ SDValue VL = DAG.getConstant(NumElts, DL, XLenVT);
SDValue Cmp = DAG.getSetCC(DL, CmpVT, VecX, VecY, ISD::SETNE);
return DAG.getSetCC(DL, VT,
diff --git a/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll b/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
index c4810e7e2201d..2d9100da4f5e0 100644
--- a/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
@@ -23,17 +23,8 @@ define { i1, <32 x i8> } @bitcast_v32i8(ptr %a0) {
define { i1, <16 x i16> } @bitcast_v16i16(ptr %a0) {
; CHECK-LABEL: bitcast_v16i16:
; CHECK: # %bb.0:
-; CHECK-NEXT: ld a1, 0(a0)
-; CHECK-NEXT: ld a2, 8(a0)
-; CHECK-NEXT: ld a3, 16(a0)
-; CHECK-NEXT: ld a0, 24(a0)
-; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma
-; CHECK-NEXT: vmv.v.x v8, a1
-; CHECK-NEXT: vslide1down.vx v8, v8, a2
-; CHECK-NEXT: vslide1down.vx v8, v8, a3
-; CHECK-NEXT: vslide1down.vx v8, v8, a0
-; CHECK-NEXT: li a0, 32
-; CHECK-NEXT: vsetvli zero, a0, e8, m2, ta, ma
+; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
+; CHECK-NEXT: vle16.v v8, (a0)
; CHECK-NEXT: vmsne.vi v10, v8, 0
; CHECK-NEXT: vcpop.m a0, v10
; CHECK-NEXT: seqz a0, a0
@@ -50,17 +41,8 @@ define { i1, <16 x i16> } @bitcast_v16i16(ptr %a0) {
define { i1, <8 x i32> } @bitcast_v8i32(ptr %a0) {
; CHECK-LABEL: bitcast_v8i32:
; CHECK: # %bb.0:
-; CHECK-NEXT: ld a1, 0(a0)
-; CHECK-NEXT: ld a2, 8(a0)
-; CHECK-NEXT: ld a3, 16(a0)
-; CHECK-NEXT: ld a0, 24(a0)
-; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma
-; CHECK-NEXT: vmv.v.x v8, a1
-; CHECK-NEXT: vslide1down.vx v8, v8, a2
-; CHECK-NEXT: vslide1down.vx v8, v8, a3
-; CHECK-NEXT: vslide1down.vx v8, v8, a0
-; CHECK-NEXT: li a0, 32
-; CHECK-NEXT: vsetvli zero, a0, e8, m2, ta, ma
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vle32.v v8, (a0)
; CHECK-NEXT: vmsne.vi v10, v8, 0
; CHECK-NEXT: vcpop.m a0, v10
; CHECK-NEXT: seqz a0, a0
>From 1481c548826fbc17902b2c41db8231202c16f43c Mon Sep 17 00:00:00 2001
From: ZakyHermawan <zaky.hermawan9615 at gmail.com>
Date: Tue, 19 May 2026 13:30:55 +0700
Subject: [PATCH 3/7] sanity check for EVT to become MVT
Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 8b657a719804e..eb1ff7149fd47 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -17629,8 +17629,13 @@ combineVectorSizedSetCCEquality(EVT VT, SDValue X, SDValue Y, ISD::CondCode CC,
auto GetPreferredEltVT = [](SDValue V) -> MVT {
// Look backwards: check if V itself is derived from a vector
SDValue Peek = peekThroughBitcasts(V);
- if (Peek.getValueType().isVector() && Peek.getValueType().isInteger())
- return Peek.getSimpleValueType().getVectorElementType();
+ EVT PeekVT = Peek.getValueType();
+
+ if (PeekVT.isVector() && PeekVT.isInteger()) {
+ EVT EltVT = PeekVT.getVectorElementType();
+ if (EltVT.isSimple())
+ return EltVT.getSimpleVT();
+ }
// Look forwards: check if V is bitcasted to a vector elsewhere in the DAG
for (SDUse &Use : V->uses()) {
@@ -17642,8 +17647,11 @@ combineVectorSizedSetCCEquality(EVT VT, SDValue X, SDValue Y, ISD::CondCode CC,
SDNode *User = Use.getUser();
if (User->getOpcode() == ISD::BITCAST) {
EVT CastVT = User->getValueType(0);
- if (CastVT.isVector() && CastVT.isInteger())
- return CastVT.getVectorElementType().getSimpleVT();
+ if (CastVT.isVector() && CastVT.isInteger()) {
+ EVT EltVT = CastVT.getVectorElementType();
+ if (EltVT.isSimple())
+ return EltVT.getSimpleVT();
+ }
}
}
return MVT::INVALID_SIMPLE_VALUE_TYPE;
@@ -17663,9 +17671,8 @@ combineVectorSizedSetCCEquality(EVT VT, SDValue X, SDValue Y, ISD::CondCode CC,
}
// If both are unsuitable, use the safe default (i8)
- if (!IsValidEltVT(EltVT)) {
+ if (!IsValidEltVT(EltVT))
EltVT = MVT::i8;
- }
unsigned EltSize = EltVT.getSizeInBits();
unsigned NumElts = OpSize / EltSize;
>From 93d9431883276a0f19e2021fb8e901bcf1de792a Mon Sep 17 00:00:00 2001
From: ZakyHermawan <zaky.hermawan9615 at gmail.com>
Date: Wed, 20 May 2026 03:48:49 +0700
Subject: [PATCH 4/7] [RISCV] use isTypeLegal to simplify EVT validation
Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index eb1ff7149fd47..e5cd68cc7785c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -17658,10 +17658,19 @@ combineVectorSizedSetCCEquality(EVT VT, SDValue X, SDValue Y, ISD::CondCode CC,
};
auto IsValidEltVT = [&](MVT VT) {
- return VT != MVT::INVALID_SIMPLE_VALUE_TYPE && VT.isInteger() &&
- VT.getSizeInBits() >= 8 &&
- VT.getSizeInBits() <= Subtarget.getXLen() &&
- OpSize % VT.getSizeInBits() == 0;
+ if (VT == MVT::INVALID_SIMPLE_VALUE_TYPE || !VT.isInteger())
+ return false;
+
+ // Make sure we don't try to create an impossible vector type where the
+ // elements don't perfectly fill up the OpSize boundary.
+ unsigned EltSize = VT.getSizeInBits();
+ if (EltSize == 0 || OpSize % EltSize != 0)
+ return false;
+
+ // Construct the proposed vector type to check its legality
+ unsigned NumElts = OpSize / EltSize;
+ EVT TestVecVT = EVT::getVectorVT(*DAG.getContext(), VT, NumElts);
+ return Subtarget.getTargetLowering()->isTypeLegal(TestVecVT);
};
// Get preferred VT from either X or Y.
>From ac67b3e02330b18ecce5305f33eaf766232e66fb Mon Sep 17 00:00:00 2001
From: Zaky Hermawan <44158147+ZakyHermawan at users.noreply.github.com>
Date: Thu, 21 May 2026 01:18:09 +0700
Subject: [PATCH 5/7] Remove redundant check for zero element size
The minimum size of MVT is i1, so i0 will never happened, hence, the check is unnecessary.
Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index e5cd68cc7785c..d936b7b28289c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -17664,7 +17664,7 @@ combineVectorSizedSetCCEquality(EVT VT, SDValue X, SDValue Y, ISD::CondCode CC,
// Make sure we don't try to create an impossible vector type where the
// elements don't perfectly fill up the OpSize boundary.
unsigned EltSize = VT.getSizeInBits();
- if (EltSize == 0 || OpSize % EltSize != 0)
+ if (OpSize % EltSize != 0)
return false;
// Construct the proposed vector type to check its legality
>From 796bcafa34eadba3bed9fbfe4ae25477e60aa64c Mon Sep 17 00:00:00 2001
From: ZakyHermawan <zaky.hermawan9615 at gmail.com>
Date: Thu, 21 May 2026 22:36:08 +0700
Subject: [PATCH 6/7] [RISCV] Add test when the casted operand is a vector of
simple VT
Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll | 46 ++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll b/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
index 2d9100da4f5e0..61b54c7fc5e2e 100644
--- a/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
@@ -55,3 +55,49 @@ define { i1, <8 x i32> } @bitcast_v8i32(ptr %a0) {
%res2 = insertvalue { i1, <8 x i32> } %res1, <8 x i32> %src256.bitcast, 1
ret { i1, <8 x i32> } %res2
}
+
+define i1 @bitcast_from_v32i8(ptr %a0) {
+; CHECK-LABEL: bitcast_from_v32i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a1, 32
+; CHECK-NEXT: vsetvli zero, a1, e8, m2, ta, ma
+; CHECK-NEXT: vle8.v v8, (a0)
+; CHECK-NEXT: vmsne.vi v10, v8, 0
+; CHECK-NEXT: vcpop.m a0, v10
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %vec = load <32 x i8>, ptr %a0, align 32
+ %int = bitcast <32 x i8> %vec to i256
+ %iszero = icmp eq i256 %int, 0
+ ret i1 %iszero
+}
+
+define i1 @bitcast_from_v16i16(ptr %a0) {
+; CHECK-LABEL: bitcast_from_v16i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
+; CHECK-NEXT: vle16.v v8, (a0)
+; CHECK-NEXT: vmsne.vi v10, v8, 0
+; CHECK-NEXT: vcpop.m a0, v10
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %vec = load <16 x i16>, ptr %a0, align 32
+ %int = bitcast <16 x i16> %vec to i256
+ %iszero = icmp eq i256 %int, 0
+ ret i1 %iszero
+}
+
+define i1 @bitcast_from_v8i32(ptr %a0) {
+; CHECK-LABEL: bitcast_from_v8i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
+; CHECK-NEXT: vle32.v v8, (a0)
+; CHECK-NEXT: vmsne.vi v10, v8, 0
+; CHECK-NEXT: vcpop.m a0, v10
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %vec = load <8 x i32>, ptr %a0, align 32
+ %int = bitcast <8 x i32> %vec to i256
+ %iszero = icmp eq i256 %int, 0
+ ret i1 %iszero
+}
>From 2489f4ee8181a1af0b3b7f4e39feffcbe666d2d6 Mon Sep 17 00:00:00 2001
From: ZakyHermawan <zaky.hermawan9615 at gmail.com>
Date: Thu, 21 May 2026 23:15:44 +0700
Subject: [PATCH 7/7] [RISCV] Add test for comparison between large int and
vector
This will make sure at least one of them failed on GetPreferredEltVT (because it is not a simple type)
nit: Use getValueType() instead of getValueType(0) for more consistency, because bitcase will only produce one value anyway.
Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll | 36 ++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll b/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
index 61b54c7fc5e2e..a94ddac083705 100644
--- a/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/bitcast-cmp.ll
@@ -101,3 +101,39 @@ define i1 @bitcast_from_v8i32(ptr %a0) {
%iszero = icmp eq i256 %int, 0
ret i1 %iszero
}
+
+; Compare a plain i256 against a bitcasted vector.
+define i1 @cmp_plain_to_v16i16(ptr %a0, ptr %a1) {
+; CHECK-LABEL: cmp_plain_to_v16i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
+; CHECK-NEXT: vle16.v v8, (a0)
+; CHECK-NEXT: vle16.v v10, (a1)
+; CHECK-NEXT: vmsne.vv v12, v8, v10
+; CHECK-NEXT: vcpop.m a0, v12
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %x = load i256, ptr %a0, align 32
+ %y_vec = load <16 x i16>, ptr %a1, align 32
+ %y = bitcast <16 x i16> %y_vec to i256
+ %cmp = icmp eq i256 %x, %y
+ ret i1 %cmp
+}
+
+; Flipped operands to guarantee the Y-path is covered regardless of DAG sorting.
+define i1 @cmp_v16i16_to_plain(ptr %a0, ptr %a1) {
+; CHECK-LABEL: cmp_v16i16_to_plain:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
+; CHECK-NEXT: vle16.v v8, (a0)
+; CHECK-NEXT: vle16.v v10, (a1)
+; CHECK-NEXT: vmsne.vv v12, v8, v10
+; CHECK-NEXT: vcpop.m a0, v12
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: ret
+ %x_vec = load <16 x i16>, ptr %a0, align 32
+ %x = bitcast <16 x i16> %x_vec to i256
+ %y = load i256, ptr %a1, align 32
+ %cmp = icmp eq i256 %x, %y
+ ret i1 %cmp
+}
More information about the llvm-commits
mailing list