[DAG] Ensure type is legal for bswap(shl(x,c)) -> zext(bswap(trunc(shl(x,c-bw/2)))) fold

As reported on D120192
This commit is contained in:
Simon Pilgrim 2022-02-27 11:25:17 +00:00
parent 853ca54723
commit fadd20f80d
4 changed files with 41 additions and 5 deletions

View File

@ -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)))

View File

@ -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(...)

View File

@ -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

View File

@ -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*