blob: ca30a3fe826a37e793d1d7ef1a3c2ebf02f3787e [file] [log] [blame]
commit fadd20f80d6968a5a8623e0d1f804337ce084dcb
Author: Simon Pilgrim <llvm-dev@redking.me.uk>
Date: Sun Feb 27 11:25:17 2022 +0000
[DAG] Ensure type is legal for bswap(shl(x,c)) -> zext(bswap(trunc(shl(x,c-bw/2)))) fold
As reported on D120192
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c3bb838aac5c..996974452c1b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -9618,7 +9618,8 @@ SDValue DAGCombiner::visitBSWAP(SDNode *N) {
EVT HalfVT = EVT::getIntegerVT(*DAG.getContext(), BW / 2);
if (ShAmt && ShAmt->getAPIntValue().ult(BW) &&
ShAmt->getZExtValue() >= (BW / 2) &&
- (ShAmt->getZExtValue() % 16) == 0 && TLI.isTruncateFree(VT, HalfVT) &&
+ (ShAmt->getZExtValue() % 16) == 0 && TLI.isTypeLegal(HalfVT) &&
+ TLI.isTruncateFree(VT, HalfVT) &&
(!LegalOperations || hasOperation(ISD::BSWAP, HalfVT))) {
SDValue Res = N0.getOperand(0);
if (uint64_t NewShAmt = (ShAmt->getZExtValue() - (BW / 2)))
diff --git a/llvm/test/CodeGen/AArch64/arm64-rev.ll b/llvm/test/CodeGen/AArch64/arm64-rev.ll
index aa223eefbbfa..f48b46641821 100644
--- a/llvm/test/CodeGen/AArch64/arm64-rev.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-rev.ll
@@ -645,3 +645,38 @@ fail:
ret void
}
declare i16 @llvm.bswap.i16(i16)
+
+; Reduced regression from D120192
+define void @test_bswap32_narrow(i32* %p0, i16* %p1) nounwind {
+; CHECK-LABEL: test_bswap32_narrow:
+; CHECK: // %bb.0:
+; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT: ldrh w8, [x0, #2]
+; CHECK-NEXT: mov x19, x1
+; CHECK-NEXT: lsl w8, w8, #16
+; CHECK-NEXT: rev w0, w8
+; CHECK-NEXT: bl gid_tbl_len
+; CHECK-NEXT: strh wzr, [x19]
+; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
+; CHECK-NEXT: ret
+;
+; GISEL-LABEL: test_bswap32_narrow:
+; GISEL: // %bb.0:
+; GISEL-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
+; GISEL-NEXT: ldr w8, [x0]
+; GISEL-NEXT: mov x19, x1
+; GISEL-NEXT: and w8, w8, #0xffff0000
+; GISEL-NEXT: rev w0, w8
+; GISEL-NEXT: bl gid_tbl_len
+; GISEL-NEXT: strh wzr, [x19]
+; GISEL-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
+; GISEL-NEXT: ret
+ %ld = load i32, i32* %p0, align 4
+ %and = and i32 %ld, -65536
+ %bswap = tail call i32 @llvm.bswap.i32(i32 %and)
+ %and16 = zext i32 %bswap to i64
+ %call17 = tail call i32 bitcast (i32 (...)* @gid_tbl_len to i32 (i64)*)(i64 %and16)
+ store i16 0, i16* %p1, align 4
+ ret void
+}
+declare i32 @gid_tbl_len(...)
diff --git a/llvm/test/CodeGen/AArch64/load-combine-big-endian.ll b/llvm/test/CodeGen/AArch64/load-combine-big-endian.ll
index 7579d550efb8..14a0162d5269 100644
--- a/llvm/test/CodeGen/AArch64/load-combine-big-endian.ll
+++ b/llvm/test/CodeGen/AArch64/load-combine-big-endian.ll
@@ -442,8 +442,8 @@ define i32 @zext_load_i32_by_i8(i32* %arg) {
; CHECK-LABEL: zext_load_i32_by_i8:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
-; CHECK-NEXT: rev w8, w8
-; CHECK-NEXT: lsr w0, w8, #16
+; CHECK-NEXT: lsl w8, w8, #16
+; CHECK-NEXT: rev w0, w8
; CHECK-NEXT: ret
%tmp = bitcast i32* %arg to i8*
%tmp1 = getelementptr inbounds i8, i8* %tmp, i32 0
diff --git a/llvm/test/CodeGen/AArch64/load-combine.ll b/llvm/test/CodeGen/AArch64/load-combine.ll
index d743ab3f643c..066ecb21dc10 100644
--- a/llvm/test/CodeGen/AArch64/load-combine.ll
+++ b/llvm/test/CodeGen/AArch64/load-combine.ll
@@ -499,8 +499,8 @@ define i32 @zext_load_i32_by_i8_bswap(i32* %arg) {
; CHECK-LABEL: zext_load_i32_by_i8_bswap:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
-; CHECK-NEXT: rev w8, w8
-; CHECK-NEXT: lsr w0, w8, #16
+; CHECK-NEXT: lsl w8, w8, #16
+; CHECK-NEXT: rev w0, w8
; CHECK-NEXT: ret
%tmp = bitcast i32* %arg to i8*