From 4dac28c5bc2a6bdd2454f8331608e228ab45be5f Mon Sep 17 00:00:00 2001 From: eastb233 Date: Thu, 11 Dec 2025 19:37:56 +0800 Subject: [PATCH] [ISEL] Fix bug in rev16 feature We should return false when data type does not match in tryReadOpt -> SelectRead*, so call site can fallthrough instead of returning. --- .../Target/AArch64/AArch64ISelDAGToDAG.cpp | 18 ++++++------- .../test/CodeGen/AArch64/reduce-load-store.ll | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 691149cd6540..db7c16034a4a 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -4690,9 +4690,6 @@ void AArch64DAGToDAGISel::SelectRead3( SDNode *N, SmallVector> &LD) { assert(N->getOpcode() == ISD::OR && "Expected OR instruction"); - if (N->getValueType(0) != MVT::i32) - return; - SDValue Addr = getLoadStoreAddrWithoutOffset(LD[0].first); int64_t Offset = getLoadStoreOffset(LD[0].first); SDValue Chain = LD[0].first->getChain(); @@ -4725,9 +4722,6 @@ void AArch64DAGToDAGISel::SelectRead6( SDNode *N, SmallVector> &LD) { assert(N->getOpcode() == ISD::OR && "Expected OR instruction"); - if (N->getValueType(0) != MVT::i64) - return; - SDValue Addr = getLoadStoreAddrWithoutOffset(LD[0].first); int64_t Offset = getLoadStoreOffset(LD[0].first); SDValue Chain = LD[0].first->getChain(); @@ -4785,9 +4779,6 @@ void AArch64DAGToDAGISel::SelectRead7( SDNode *N, SmallVector> &LD) { assert(N->getOpcode() == ISD::OR && "Expected OR instruction"); - if (N->getValueType(0) != MVT::i64) - return; - SDValue Addr = getLoadStoreAddrWithoutOffset(LD[0].first); int64_t Offset = getLoadStoreOffset(LD[0].first); SDValue Chain = LD[0].first->getChain(); @@ -4854,14 +4845,23 @@ bool AArch64DAGToDAGISel::tryReadOpt(SDNode *N) { return false; if (canCombineLoads(AllLd, 7)) { + if (N->getValueType(0) != MVT::i64) + return false; + SelectRead7(N, AllLd); return true; } if (canCombineLoads(AllLd, 6)) { + if (N->getValueType(0) != MVT::i64) + return false; + SelectRead6(N, AllLd); return true; } if (canCombineLoads(AllLd, 3)) { + if (N->getValueType(0) != MVT::i32) + return false; + SelectRead3(N, AllLd); return true; } diff --git a/llvm/test/CodeGen/AArch64/reduce-load-store.ll b/llvm/test/CodeGen/AArch64/reduce-load-store.ll index bc5fc901cf93..2ce18720d96b 100644 --- a/llvm/test/CodeGen/AArch64/reduce-load-store.ll +++ b/llvm/test/CodeGen/AArch64/reduce-load-store.ll @@ -24,6 +24,33 @@ entry: ret i32 %or6 } +;; Check for not crash. +define i64 @test_read_3_second(ptr %b) { +; CHECK-LABEL: test_read_3_second: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: ldrb w8, [x0] +; CHECK-NEXT: ldrb w9, [x0, #1] +; CHECK-NEXT: ldrb w10, [x0, #2] +; CHECK-NEXT: lsl x8, x8, #16 +; CHECK-NEXT: orr x8, x8, x9, lsl #8 +; CHECK-NEXT: orr x0, x8, x10 +; CHECK-NEXT: ret +entry: + %0 = load i8, ptr %b, align 1 + %conv = zext i8 %0 to i64 + %shl = shl nuw nsw i64 %conv, 16 + %arrayidx1 = getelementptr inbounds i8, ptr %b, i64 1 + %1 = load i8, ptr %arrayidx1, align 1 + %conv2 = zext i8 %1 to i64 + %shl3 = shl nuw nsw i64 %conv2, 8 + %or = or i64 %shl3, %shl + %arrayidx4 = getelementptr inbounds i8, ptr %b, i64 2 + %2 = load i8, ptr %arrayidx4, align 1 + %conv5 = zext i8 %2 to i64 + %or6 = or i64 %or, %conv5 + ret i64 %or6 +} + define i64 @test_read_6(ptr %b) { ; CHECK-LABEL: test_read_6: ; CHECK: // %bb.0: // %entry -- Gitee