diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -9783,16 +9783,20 @@ continue; // Check if the offsets match the XTHeadMemPair encoding contraints. + bool Valid = false; if (MemVT == MVT::i32) { // Check for adjacent i32 values and a 2-bit index. - if ((Offset1 + 4 != Offset2) || !isShiftedUInt<2, 3>(Offset1)) - continue; + if ((Offset1 + 4 == Offset2) && isShiftedUInt<2, 3>(Offset1)) + Valid = true; } else if (MemVT == MVT::i64) { // Check for adjacent i64 values and a 2-bit index. - if ((Offset1 + 8 != Offset2) || !isShiftedUInt<2, 4>(Offset1)) - continue; + if ((Offset1 + 8 == Offset2) && isShiftedUInt<2, 4>(Offset1)) + Valid = true; } + if (!Valid) + continue; + // Try to combine. if (SDValue Res = tryMemPairCombine(DAG, LSNode1, LSNode2, Base1, Offset1)) diff --git a/llvm/test/CodeGen/RISCV/xtheadmempair.ll b/llvm/test/CodeGen/RISCV/xtheadmempair.ll --- a/llvm/test/CodeGen/RISCV/xtheadmempair.ll +++ b/llvm/test/CodeGen/RISCV/xtheadmempair.ll @@ -293,3 +293,51 @@ store i128 %b, i128* %1, align 8 ret void } + +define i32 @lh(i16* %a) { +; RV32XTHEADMEMPAIR-LABEL: lh: +; RV32XTHEADMEMPAIR: # %bb.0: +; RV32XTHEADMEMPAIR-NEXT: lh a1, 0(a0) +; RV32XTHEADMEMPAIR-NEXT: lh a0, 2(a0) +; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a0 +; RV32XTHEADMEMPAIR-NEXT: ret +; +; RV64XTHEADMEMPAIR-LABEL: lh: +; RV64XTHEADMEMPAIR: # %bb.0: +; RV64XTHEADMEMPAIR-NEXT: lh a1, 0(a0) +; RV64XTHEADMEMPAIR-NEXT: lh a0, 2(a0) +; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a0 +; RV64XTHEADMEMPAIR-NEXT: ret + %1 = getelementptr i16, i16* %a, i64 0 + %2 = load i16, i16* %1, align 4 + %3 = getelementptr i16, i16* %a, i64 1 + %4 = load i16, i16* %3, align 4 + %5 = sext i16 %2 to i32 + %6 = sext i16 %4 to i32 + %7 = add i32 %5, %6 + ret i32 %7 +} + +define i32 @lb(i8* %a) { +; RV32XTHEADMEMPAIR-LABEL: lb: +; RV32XTHEADMEMPAIR: # %bb.0: +; RV32XTHEADMEMPAIR-NEXT: lb a1, 0(a0) +; RV32XTHEADMEMPAIR-NEXT: lb a0, 1(a0) +; RV32XTHEADMEMPAIR-NEXT: add a0, a1, a0 +; RV32XTHEADMEMPAIR-NEXT: ret +; +; RV64XTHEADMEMPAIR-LABEL: lb: +; RV64XTHEADMEMPAIR: # %bb.0: +; RV64XTHEADMEMPAIR-NEXT: lb a1, 0(a0) +; RV64XTHEADMEMPAIR-NEXT: lb a0, 1(a0) +; RV64XTHEADMEMPAIR-NEXT: add a0, a1, a0 +; RV64XTHEADMEMPAIR-NEXT: ret + %1 = getelementptr i8, i8* %a, i64 0 + %2 = load i8, i8* %1, align 4 + %3 = getelementptr i8, i8* %a, i64 1 + %4 = load i8, i8* %3, align 4 + %5 = sext i8 %2 to i32 + %6 = sext i8 %4 to i32 + %7 = add i32 %5, %6 + ret i32 %7 +}