-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[DAG][AArch64] Handle truncated buildvectors to allow and(subvector(anyext)) fold. #133915
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/davemgreen/gh-a64-v4i8subvec
Are you sure you want to change the base?
[DAG][AArch64] Handle truncated buildvectors to allow and(subvector(anyext)) fold. #133915
Conversation
…nyext)) fold. This fold was not handling the extended BUILDVECTORs that we see when i8/i16 are not legal types. Using isConstOrConstSplat(N1, false, true) allows it to match truncated constants. The other changes are to make sure that truncated values in N1C are treated correctly, the fold we are mostly interested in is ``` if (N0.getOpcode() == ISD::EXTRACT_SUBVECTOR && N0.hasOneUse() && N1C && ISD::isExtOpcode(N0.getOperand(0).getOpcode())) { ```
@@ -7166,7 +7166,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { | ||
|
||
// if (and x, c) is known to be zero, return 0 | ||
unsigned BitWidth = VT.getScalarSizeInBits(); | ||
ConstantSDNode *N1C = isConstOrConstSplat(N1); | ||
ConstantSDNode *N1C = | ||
isConstOrConstSplat(N1, /*AllowUndef*/ false, /*AllowTrunc*/ true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you check all the uses of N1C? Some of them look a little suspicious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 7170 is checking DAG.MaskedValueIsZero.
7200 is being truncated, 7208 is the one being updated.
7346/7353 is checking for a mask, which I believe should be OK.
7389 will be checked inside reduceLoadWidth.
7491 is checking a constant, which I believed would again be OK.
Any of them in particular seem suspicious to you? We can make them more defensive if necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AllowTrunc means the input constant is truncated. But we don't promise zero-extension, I think, so the high bits could be anything. Therefore any comparison that checks those high bits is broken. The check on 7491 is most suspect in this respect, but 7346/7353 is also slightly suspect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could replace this with something like:
std::optional<APInt> N1C;
if (ConstantSDNode *C1 = isConstOrConstSplat(N1, /*AllowUndef*/ false, /*AllowTrunc*/ true))
N1C = C1->getAPIntValue().zextOrTrunc(BitWidth);
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AllowTrunc means the input constant is truncated. But we don't promise zero-extension, I think, so the high bits could be anything. Therefore any comparison that checks those high bits is broken. The check on 7491 is most suspect in this respect, but 7346/7353 is also slightly suspect.
Checking for a mask (either via isMask with a shorter ScalarWidth or by checking == 0xffff as in 7491) would check that the top bits are 0. (MatchBSwapHWordLow also only handles scalars). So they should be OK, and truncating the constant should just make it is more likely to match in cases where the top bits are non-zero.
It would be a good idea to try and protect against future uses not realizing that the constant had been truncated, so a optional sounds like a good idea.
@llvm/pr-subscribers-llvm-selectiondag @llvm/pr-subscribers-backend-aarch64 Author: David Green (davemgreen) ChangesThis fold was not handling the extended BUILDVECTORs that we see when i8/i16 are not legal types. Using isConstOrConstSplat(N1, false, true) allows it to match truncated constants. The other changes are to make sure that truncated values in N1C are treated correctly, the fold we are mostly interested in is
Full diff: https://github.com/llvm/llvm-project/pull/133915.diff 8 Files Affected:
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index dc5c5f38e3bd8..a0969fe575d00 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7166,7 +7166,10 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
// if (and x, c) is known to be zero, return 0
unsigned BitWidth = VT.getScalarSizeInBits();
- ConstantSDNode *N1C = isConstOrConstSplat(N1);
+ std::optional<APInt> N1C;
+ if (ConstantSDNode *C1 =
+ isConstOrConstSplat(N1, /*AllowUndef*/ false, /*AllowTrunc*/ true))
+ N1C = C1->getAPIntValue().zextOrTrunc(BitWidth);
if (N1C && DAG.MaskedValueIsZero(SDValue(N, 0), APInt::getAllOnes(BitWidth)))
return DAG.getConstant(0, DL, VT);
@@ -7197,7 +7200,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
SDValue N0Op0 = N0.getOperand(0);
EVT SrcVT = N0Op0.getValueType();
unsigned SrcBitWidth = SrcVT.getScalarSizeInBits();
- APInt Mask = ~N1C->getAPIntValue();
+ APInt Mask = ~*N1C;
Mask = Mask.trunc(SrcBitWidth);
// fold (and (any_ext V), c) -> (zero_ext V) if 'and' only clears top bits.
@@ -7205,7 +7208,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0Op0);
// fold (and (any_ext V), c) -> (zero_ext (and (trunc V), c)) if profitable.
- if (N1C->getAPIntValue().countLeadingZeros() >= (BitWidth - SrcBitWidth) &&
+ if (N1C->countLeadingZeros() >= (BitWidth - SrcBitWidth) &&
TLI.isTruncateFree(VT, SrcVT) && TLI.isZExtFree(SrcVT, VT) &&
TLI.isTypeDesirableForOp(ISD::AND, SrcVT) &&
TLI.isNarrowingProfitable(N, VT, SrcVT))
@@ -7350,7 +7353,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
SDValue Extendee = Ext->getOperand(0);
unsigned ScalarWidth = Extendee.getValueType().getScalarSizeInBits();
- if (N1C->getAPIntValue().isMask(ScalarWidth) &&
+ if (N1C->isMask(ScalarWidth) &&
(!LegalOperations || TLI.isOperationLegal(ISD::ZERO_EXTEND, ExtVT))) {
// (and (extract_subvector (zext|anyext|sext v) _) iN_mask)
// => (extract_subvector (iN_zeroext v))
@@ -7488,7 +7491,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
}
// fold (and (or (srl N, 8), (shl N, 8)), 0xffff) -> (srl (bswap N), const)
- if (N1C && N1C->getAPIntValue() == 0xffff && N0.getOpcode() == ISD::OR) {
+ if (N1C && *N1C == 0xffff && N0.getOpcode() == ISD::OR) {
if (SDValue BSwap = MatchBSwapHWordLow(N0.getNode(), N0.getOperand(0),
N0.getOperand(1), false))
return BSwap;
diff --git a/llvm/test/CodeGen/AArch64/aarch64-neon-vector-insert-uaddlv.ll b/llvm/test/CodeGen/AArch64/aarch64-neon-vector-insert-uaddlv.ll
index 412f39f8adc1b..f37767291ca14 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-neon-vector-insert-uaddlv.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-neon-vector-insert-uaddlv.ll
@@ -282,8 +282,7 @@ define void @insert_vec_v16i8_uaddlv_from_v8i8(ptr %0) {
; CHECK-NEXT: uaddlv.8b h1, v0
; CHECK-NEXT: stp q0, q0, [x0, #32]
; CHECK-NEXT: mov.b v2[0], v1[0]
-; CHECK-NEXT: zip1.8b v2, v2, v2
-; CHECK-NEXT: bic.4h v2, #255, lsl #8
+; CHECK-NEXT: ushll.8h v2, v2, #0
; CHECK-NEXT: ushll.4s v2, v2, #0
; CHECK-NEXT: ucvtf.4s v2, v2
; CHECK-NEXT: stp q2, q0, [x0]
@@ -305,8 +304,7 @@ define void @insert_vec_v8i8_uaddlv_from_v8i8(ptr %0) {
; CHECK-NEXT: stp xzr, xzr, [x0, #16]
; CHECK-NEXT: uaddlv.8b h1, v0
; CHECK-NEXT: mov.b v0[0], v1[0]
-; CHECK-NEXT: zip1.8b v0, v0, v0
-; CHECK-NEXT: bic.4h v0, #255, lsl #8
+; CHECK-NEXT: ushll.8h v0, v0, #0
; CHECK-NEXT: ushll.4s v0, v0, #0
; CHECK-NEXT: ucvtf.4s v0, v0
; CHECK-NEXT: str q0, [x0]
@@ -436,8 +434,7 @@ define void @insert_vec_v8i8_uaddlv_from_v4i32(ptr %0) {
; CHECK-NEXT: stp xzr, xzr, [x0, #16]
; CHECK-NEXT: uaddlv.4s d0, v0
; CHECK-NEXT: mov.b v1[0], v0[0]
-; CHECK-NEXT: zip1.8b v1, v1, v1
-; CHECK-NEXT: bic.4h v1, #255, lsl #8
+; CHECK-NEXT: ushll.8h v1, v1, #0
; CHECK-NEXT: ushll.4s v1, v1, #0
; CHECK-NEXT: ucvtf.4s v1, v1
; CHECK-NEXT: str q1, [x0]
@@ -461,8 +458,7 @@ define void @insert_vec_v16i8_uaddlv_from_v4i32(ptr %0) {
; CHECK-NEXT: uaddlv.4s d0, v0
; CHECK-NEXT: stp q2, q2, [x0, #32]
; CHECK-NEXT: mov.b v1[0], v0[0]
-; CHECK-NEXT: zip1.8b v1, v1, v1
-; CHECK-NEXT: bic.4h v1, #255, lsl #8
+; CHECK-NEXT: ushll.8h v1, v1, #0
; CHECK-NEXT: ushll.4s v1, v1, #0
; CHECK-NEXT: ucvtf.4s v1, v1
; CHECK-NEXT: stp q1, q2, [x0]
diff --git a/llvm/test/CodeGen/AArch64/bitcast-extend.ll b/llvm/test/CodeGen/AArch64/bitcast-extend.ll
index 5dc335900a798..08a7493d0ba7f 100644
--- a/llvm/test/CodeGen/AArch64/bitcast-extend.ll
+++ b/llvm/test/CodeGen/AArch64/bitcast-extend.ll
@@ -6,8 +6,8 @@ define <4 x i16> @z_i32_v4i16(i32 %x) {
; CHECK-SD-LABEL: z_i32_v4i16:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: fmov s0, w0
-; CHECK-SD-NEXT: zip1 v0.8b, v0.8b, v0.8b
-; CHECK-SD-NEXT: bic v0.4h, #255, lsl #8
+; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #0
+; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: z_i32_v4i16:
diff --git a/llvm/test/CodeGen/AArch64/ctlz.ll b/llvm/test/CodeGen/AArch64/ctlz.ll
index afdeff06fdef6..facc15ef15e8b 100644
--- a/llvm/test/CodeGen/AArch64/ctlz.ll
+++ b/llvm/test/CodeGen/AArch64/ctlz.ll
@@ -44,8 +44,7 @@ define void @v3i8(ptr %p1) {
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
; CHECK-SD-NEXT: ldr s1, [x0]
; CHECK-SD-NEXT: movi v0.4h, #8
-; CHECK-SD-NEXT: zip1 v1.8b, v1.8b, v1.8b
-; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8
+; CHECK-SD-NEXT: ushll v1.8h, v1.8b, #0
; CHECK-SD-NEXT: clz v1.4h, v1.4h
; CHECK-SD-NEXT: sub v0.4h, v1.4h, v0.4h
; CHECK-SD-NEXT: uzp1 v1.8b, v0.8b, v0.8b
diff --git a/llvm/test/CodeGen/AArch64/ctpop.ll b/llvm/test/CodeGen/AArch64/ctpop.ll
index c7c378d3e67cd..edb1d55a15733 100644
--- a/llvm/test/CodeGen/AArch64/ctpop.ll
+++ b/llvm/test/CodeGen/AArch64/ctpop.ll
@@ -43,8 +43,7 @@ define void @v3i8(ptr %p1) {
; CHECK-SD-NEXT: sub sp, sp, #16
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
; CHECK-SD-NEXT: ldr s0, [x0]
-; CHECK-SD-NEXT: zip1 v0.8b, v0.8b, v0.8b
-; CHECK-SD-NEXT: bic v0.4h, #255, lsl #8
+; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #0
; CHECK-SD-NEXT: cnt v0.8b, v0.8b
; CHECK-SD-NEXT: uaddlp v0.4h, v0.8b
; CHECK-SD-NEXT: uzp1 v1.8b, v0.8b, v0.8b
diff --git a/llvm/test/CodeGen/AArch64/itofp.ll b/llvm/test/CodeGen/AArch64/itofp.ll
index e4fb2b7c2a3c7..80a7d47c063e4 100644
--- a/llvm/test/CodeGen/AArch64/itofp.ll
+++ b/llvm/test/CodeGen/AArch64/itofp.ll
@@ -5503,14 +5503,10 @@ define <8 x float> @utofp_v8i8_v8f32(<8 x i8> %a) {
; CHECK-SD-LABEL: utofp_v8i8_v8f32:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #0
-; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8
-; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
-; CHECK-SD-NEXT: bic v0.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8
+; CHECK-SD-NEXT: ushll2 v1.4s, v0.8h, #0
; CHECK-SD-NEXT: ushll v0.4s, v0.4h, #0
-; CHECK-SD-NEXT: ushll v1.4s, v1.4h, #0
-; CHECK-SD-NEXT: ucvtf v0.4s, v0.4s
; CHECK-SD-NEXT: ucvtf v1.4s, v1.4s
+; CHECK-SD-NEXT: ucvtf v0.4s, v0.4s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: utofp_v8i8_v8f32:
@@ -5562,24 +5558,16 @@ entry:
define <16 x float> @utofp_v16i8_v16f32(<16 x i8> %a) {
; CHECK-SD-LABEL: utofp_v16i8_v16f32:
; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ushll2 v1.8h, v0.16b, #0
-; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #0
-; CHECK-SD-NEXT: ext v2.16b, v1.16b, v1.16b, #8
-; CHECK-SD-NEXT: ext v3.16b, v0.16b, v0.16b, #8
-; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
-; CHECK-SD-NEXT: // kill: def $d1 killed $d1 killed $q1
-; CHECK-SD-NEXT: bic v0.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v3.4h, #255, lsl #8
-; CHECK-SD-NEXT: ushll v0.4s, v0.4h, #0
-; CHECK-SD-NEXT: ushll v1.4s, v1.4h, #0
-; CHECK-SD-NEXT: ushll v4.4s, v2.4h, #0
-; CHECK-SD-NEXT: ushll v5.4s, v3.4h, #0
-; CHECK-SD-NEXT: ucvtf v0.4s, v0.4s
-; CHECK-SD-NEXT: ucvtf v2.4s, v1.4s
-; CHECK-SD-NEXT: ucvtf v3.4s, v4.4s
-; CHECK-SD-NEXT: ucvtf v1.4s, v5.4s
+; CHECK-SD-NEXT: ushll v1.8h, v0.8b, #0
+; CHECK-SD-NEXT: ushll2 v0.8h, v0.16b, #0
+; CHECK-SD-NEXT: ushll v2.4s, v1.4h, #0
+; CHECK-SD-NEXT: ushll2 v3.4s, v0.8h, #0
+; CHECK-SD-NEXT: ushll2 v1.4s, v1.8h, #0
+; CHECK-SD-NEXT: ushll v4.4s, v0.4h, #0
+; CHECK-SD-NEXT: ucvtf v0.4s, v2.4s
+; CHECK-SD-NEXT: ucvtf v3.4s, v3.4s
+; CHECK-SD-NEXT: ucvtf v1.4s, v1.4s
+; CHECK-SD-NEXT: ucvtf v2.4s, v4.4s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: utofp_v16i8_v16f32:
@@ -5656,42 +5644,26 @@ entry:
define <32 x float> @utofp_v32i8_v32f32(<32 x i8> %a) {
; CHECK-SD-LABEL: utofp_v32i8_v32f32:
; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ushll2 v2.8h, v0.16b, #0
-; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #0
-; CHECK-SD-NEXT: ushll2 v3.8h, v1.16b, #0
-; CHECK-SD-NEXT: ushll v1.8h, v1.8b, #0
-; CHECK-SD-NEXT: ext v4.16b, v2.16b, v2.16b, #8
-; CHECK-SD-NEXT: ext v5.16b, v0.16b, v0.16b, #8
-; CHECK-SD-NEXT: ext v6.16b, v3.16b, v3.16b, #8
-; CHECK-SD-NEXT: ext v7.16b, v1.16b, v1.16b, #8
-; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2
-; CHECK-SD-NEXT: // kill: def $d3 killed $d3 killed $q3
-; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
-; CHECK-SD-NEXT: // kill: def $d1 killed $d1 killed $q1
-; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v0.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v3.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v4.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v5.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v6.4h, #255, lsl #8
-; CHECK-SD-NEXT: bic v7.4h, #255, lsl #8
+; CHECK-SD-NEXT: ushll v2.8h, v0.8b, #0
+; CHECK-SD-NEXT: ushll2 v0.8h, v0.16b, #0
+; CHECK-SD-NEXT: ushll v3.8h, v1.8b, #0
+; CHECK-SD-NEXT: ushll2 v1.8h, v1.16b, #0
+; CHECK-SD-NEXT: ushll2 v4.4s, v2.8h, #0
; CHECK-SD-NEXT: ushll v2.4s, v2.4h, #0
-; CHECK-SD-NEXT: ushll v0.4s, v0.4h, #0
-; CHECK-SD-NEXT: ushll v1.4s, v1.4h, #0
-; CHECK-SD-NEXT: ushll v17.4s, v3.4h, #0
-; CHECK-SD-NEXT: ushll v16.4s, v4.4h, #0
-; CHECK-SD-NEXT: ushll v5.4s, v5.4h, #0
-; CHECK-SD-NEXT: ushll v18.4s, v6.4h, #0
-; CHECK-SD-NEXT: ushll v19.4s, v7.4h, #0
-; CHECK-SD-NEXT: ucvtf v2.4s, v2.4s
-; CHECK-SD-NEXT: ucvtf v0.4s, v0.4s
-; CHECK-SD-NEXT: ucvtf v4.4s, v1.4s
-; CHECK-SD-NEXT: ucvtf v6.4s, v17.4s
-; CHECK-SD-NEXT: ucvtf v3.4s, v16.4s
-; CHECK-SD-NEXT: ucvtf v1.4s, v5.4s
-; CHECK-SD-NEXT: ucvtf v7.4s, v18.4s
-; CHECK-SD-NEXT: ucvtf v5.4s, v19.4s
+; CHECK-SD-NEXT: ushll2 v5.4s, v0.8h, #0
+; CHECK-SD-NEXT: ushll v6.4s, v0.4h, #0
+; CHECK-SD-NEXT: ushll v7.4s, v3.4h, #0
+; CHECK-SD-NEXT: ushll2 v16.4s, v1.8h, #0
+; CHECK-SD-NEXT: ushll2 v17.4s, v3.8h, #0
+; CHECK-SD-NEXT: ushll v18.4s, v1.4h, #0
+; CHECK-SD-NEXT: ucvtf v1.4s, v4.4s
+; CHECK-SD-NEXT: ucvtf v0.4s, v2.4s
+; CHECK-SD-NEXT: ucvtf v3.4s, v5.4s
+; CHECK-SD-NEXT: ucvtf v2.4s, v6.4s
+; CHECK-SD-NEXT: ucvtf v4.4s, v7.4s
+; CHECK-SD-NEXT: ucvtf v7.4s, v16.4s
+; CHECK-SD-NEXT: ucvtf v5.4s, v17.4s
+; CHECK-SD-NEXT: ucvtf v6.4s, v18.4s
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: utofp_v32i8_v32f32:
diff --git a/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll b/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
index 45b7a2759b0b3..be08dd25c6bb3 100644
--- a/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
+++ b/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
@@ -444,8 +444,7 @@ define void @load_ext_to_64bits(ptr %src, ptr %dst) {
; CHECK-NEXT: orr w8, w9, w8, lsl #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: add x8, x1, #4
-; CHECK-NEXT: zip1.8b v0, v0, v0
-; CHECK-NEXT: bic.4h v0, #255, lsl #8
+; CHECK-NEXT: ushll.8h v0, v0, #0
; CHECK-NEXT: st1.h { v0 }[2], [x8]
; CHECK-NEXT: str s0, [x1]
; CHECK-NEXT: ret
@@ -480,8 +479,7 @@ define void @load_ext_to_64bits_default_align(ptr %src, ptr %dst) {
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: ldr s0, [x0]
; CHECK-NEXT: add x8, x1, #4
-; CHECK-NEXT: zip1.8b v0, v0, v0
-; CHECK-NEXT: bic.4h v0, #255, lsl #8
+; CHECK-NEXT: ushll.8h v0, v0, #0
; CHECK-NEXT: st1.h { v0 }[2], [x8]
; CHECK-NEXT: str s0, [x1]
; CHECK-NEXT: ret
@@ -491,8 +489,7 @@ define void @load_ext_to_64bits_default_align(ptr %src, ptr %dst) {
; BE-NEXT: ldr s0, [x0]
; BE-NEXT: add x8, x1, #4
; BE-NEXT: rev32 v0.8b, v0.8b
-; BE-NEXT: zip1 v0.8b, v0.8b, v0.8b
-; BE-NEXT: bic v0.4h, #255, lsl #8
+; BE-NEXT: ushll v0.8h, v0.8b, #0
; BE-NEXT: rev32 v1.8h, v0.8h
; BE-NEXT: st1 { v0.h }[2], [x8]
; BE-NEXT: str s1, [x1]
@@ -509,8 +506,7 @@ define void @load_ext_to_64bits_align_4(ptr %src, ptr %dst) {
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: ldr s0, [x0]
; CHECK-NEXT: add x8, x1, #4
-; CHECK-NEXT: zip1.8b v0, v0, v0
-; CHECK-NEXT: bic.4h v0, #255, lsl #8
+; CHECK-NEXT: ushll.8h v0, v0, #0
; CHECK-NEXT: st1.h { v0 }[2], [x8]
; CHECK-NEXT: str s0, [x1]
; CHECK-NEXT: ret
@@ -520,8 +516,7 @@ define void @load_ext_to_64bits_align_4(ptr %src, ptr %dst) {
; BE-NEXT: ldr s0, [x0]
; BE-NEXT: add x8, x1, #4
; BE-NEXT: rev32 v0.8b, v0.8b
-; BE-NEXT: zip1 v0.8b, v0.8b, v0.8b
-; BE-NEXT: bic v0.4h, #255, lsl #8
+; BE-NEXT: ushll v0.8h, v0.8b, #0
; BE-NEXT: rev32 v1.8h, v0.8h
; BE-NEXT: st1 { v0.h }[2], [x8]
; BE-NEXT: str s1, [x1]
@@ -541,13 +536,11 @@ define void @load_ext_add_to_64bits(ptr %src, ptr %dst) {
; CHECK-NEXT: Lloh2:
; CHECK-NEXT: adrp x8, lCPI15_0@PAGE
; CHECK-NEXT: Lloh3:
-; CHECK-NEXT: ldr d1, [x8, lCPI15_0@PAGEOFF]
+; CHECK-NEXT: ldr d0, [x8, lCPI15_0@PAGEOFF]
; CHECK-NEXT: add x8, x1, #4
; CHECK-NEXT: orr w9, w10, w9, lsl #16
-; CHECK-NEXT: fmov s0, w9
-; CHECK-NEXT: zip1.8b v0, v0, v0
-; CHECK-NEXT: bic.4h v0, #255, lsl #8
-; CHECK-NEXT: add.4h v0, v0, v1
+; CHECK-NEXT: fmov s1, w9
+; CHECK-NEXT: uaddw.8h v0, v0, v1
; CHECK-NEXT: st1.h { v0 }[2], [x8]
; CHECK-NEXT: str s0, [x1]
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/AArch64/vector-fcvt.ll b/llvm/test/CodeGen/AArch64/vector-fcvt.ll
index ce0a8b5b68d2b..3c763709589a7 100644
--- a/llvm/test/CodeGen/AArch64/vector-fcvt.ll
+++ b/llvm/test/CodeGen/AArch64/vector-fcvt.ll
@@ -114,14 +114,10 @@ define <8 x float> @uitofp_v8i8_float(<8 x i8> %a) {
; CHECK-LABEL: uitofp_v8i8_float:
; CHECK: // %bb.0:
; CHECK-NEXT: ushll v0.8h, v0.8b, #0
-; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8
-; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
-; CHECK-NEXT: bic v0.4h, #255, lsl #8
-; CHECK-NEXT: bic v1.4h, #255, lsl #8
+; CHECK-NEXT: ushll2 v1.4s, v0.8h, #0
; CHECK-NEXT: ushll v0.4s, v0.4h, #0
-; CHECK-NEXT: ushll v1.4s, v1.4h, #0
-; CHECK-NEXT: ucvtf v0.4s, v0.4s
; CHECK-NEXT: ucvtf v1.4s, v1.4s
+; CHECK-NEXT: ucvtf v0.4s, v0.4s
; CHECK-NEXT: ret
%1 = uitofp <8 x i8> %a to <8 x float>
ret <8 x float> %1
@@ -130,24 +126,16 @@ define <8 x float> @uitofp_v8i8_float(<8 x i8> %a) {
define <16 x float> @uitofp_v16i8_float(<16 x i8> %a) {
; CHECK-LABEL: uitofp_v16i8_float:
; CHECK: // %bb.0:
-; CHECK-NEXT: ushll2 v1.8h, v0.16b, #0
-; CHECK-NEXT: ushll v0.8h, v0.8b, #0
-; CHECK-NEXT: ext v2.16b, v1.16b, v1.16b, #8
-; CHECK-NEXT: ext v3.16b, v0.16b, v0.16b, #8
-; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
-; CHECK-NEXT: // kill: def $d1 killed $d1 killed $q1
-; CHECK-NEXT: bic v0.4h, #255, lsl #8
-; CHECK-NEXT: bic v1.4h, #255, lsl #8
-; CHECK-NEXT: bic v2.4h, #255, lsl #8
-; CHECK-NEXT: bic v3.4h, #255, lsl #8
-; CHECK-NEXT: ushll v0.4s, v0.4h, #0
-; CHECK-NEXT: ushll v1.4s, v1.4h, #0
-; CHECK-NEXT: ushll v4.4s, v2.4h, #0
-; CHECK-NEXT: ushll v5.4s, v3.4h, #0
-; CHECK-NEXT: ucvtf v0.4s, v0.4s
-; CHECK-NEXT: ucvtf v2.4s, v1.4s
-; CHECK-NEXT: ucvtf v3.4s, v4.4s
-; CHECK-NEXT: ucvtf v1.4s, v5.4s
+; CHECK-NEXT: ushll v1.8h, v0.8b, #0
+; CHECK-NEXT: ushll2 v0.8h, v0.16b, #0
+; CHECK-NEXT: ushll v2.4s, v1.4h, #0
+; CHECK-NEXT: ushll2 v3.4s, v0.8h, #0
+; CHECK-NEXT: ushll2 v1.4s, v1.8h, #0
+; CHECK-NEXT: ushll v4.4s, v0.4h, #0
+; CHECK-NEXT: ucvtf v0.4s, v2.4s
+; CHECK-NEXT: ucvtf v3.4s, v3.4s
+; CHECK-NEXT: ucvtf v1.4s, v1.4s
+; CHECK-NEXT: ucvtf v2.4s, v4.4s
; CHECK-NEXT: ret
%1 = uitofp <16 x i8> %a to <16 x float>
ret <16 x float> %1
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - cheers
Ping? @davemgreen |
Did you have a reason to need this change? |
No I was not sure if you forgot about it or meant to merge it or wasn't merging for a reason. |
This fold was not handling the extended BUILDVECTORs that we see when i8/i16 are not legal types. Using isConstOrConstSplat(N1, false, true) allows it to match truncated constants. The other changes are to make sure that truncated values in N1C are treated correctly, the fold we are mostly interested in is