From 15e894baeeb96612ae471fa83d1729a2d3388fc8 Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Thu, 26 Apr 2018 14:04:18 +0000 Subject: [PATCH] [RISCV] Implement isZextFree This returns true for 8-bit and 16-bit loads, allowing LBU/LHU to be selected and avoiding unnecessary masks. llvm-svn: 330943 --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 14 ++++++++++++++ llvm/lib/Target/RISCV/RISCVISelLowering.h | 1 + .../CodeGen/RISCV/zext-with-load-is-free.ll | 17 +++++++---------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index d1ad453fbf8a..ead9f0bdc632 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -211,6 +211,20 @@ bool RISCVTargetLowering::isTruncateFree(EVT SrcVT, EVT DstVT) const { return (SrcBits == 64 && DestBits == 32); } +bool RISCVTargetLowering::isZExtFree(SDValue Val, EVT VT2) const { + // Zexts are free if they can be combined with a load. + if (auto *LD = dyn_cast(Val)) { + EVT MemVT = LD->getMemoryVT(); + if ((MemVT == MVT::i8 || MemVT == MVT::i16 || + (Subtarget.is64Bit() && MemVT == MVT::i32)) && + (LD->getExtensionType() == ISD::NON_EXTLOAD || + LD->getExtensionType() == ISD::ZEXTLOAD)) + return true; + } + + return TargetLowering::isZExtFree(Val, VT2); +} + // Changes the condition code and swaps operands if necessary, so the SetCC // operation matches one of the comparisons supported directly in the RISC-V // ISA. diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 2a2016ef5f50..83a3bfdda4de 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -46,6 +46,7 @@ public: bool isLegalAddImmediate(int64_t Imm) const override; bool isTruncateFree(Type *SrcTy, Type *DstTy) const override; bool isTruncateFree(EVT SrcVT, EVT DstVT) const override; + bool isZExtFree(SDValue Val, EVT VT2) const override; // Provide custom lowering hooks for some operations. SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; diff --git a/llvm/test/CodeGen/RISCV/zext-with-load-is-free.ll b/llvm/test/CodeGen/RISCV/zext-with-load-is-free.ll index a937e638e0cf..8c8965afa462 100644 --- a/llvm/test/CodeGen/RISCV/zext-with-load-is-free.ll +++ b/llvm/test/CodeGen/RISCV/zext-with-load-is-free.ll @@ -15,8 +15,7 @@ define i32 @test_zext_i8() { ; RV32I-NEXT: bne a0, a1, .LBB0_3 ; RV32I-NEXT: # %bb.1: # %entry ; RV32I-NEXT: lui a0, %hi(bytes+1) -; RV32I-NEXT: lb a0, %lo(bytes+1)(a0) -; RV32I-NEXT: andi a0, a0, 255 +; RV32I-NEXT: lbu a0, %lo(bytes+1)(a0) ; RV32I-NEXT: addi a1, zero, 7 ; RV32I-NEXT: bne a0, a1, .LBB0_3 ; RV32I-NEXT: # %bb.2: # %if.end @@ -46,15 +45,13 @@ define i32 @test_zext_i16() { ; RV32I-LABEL: test_zext_i16: ; RV32I: # %bb.0: # %entry ; RV32I-NEXT: lui a0, 16 -; RV32I-NEXT: addi a1, a0, -120 -; RV32I-NEXT: lui a2, %hi(shorts) -; RV32I-NEXT: lhu a2, %lo(shorts)(a2) -; RV32I-NEXT: bne a2, a1, .LBB1_3 +; RV32I-NEXT: addi a0, a0, -120 +; RV32I-NEXT: lui a1, %hi(shorts) +; RV32I-NEXT: lhu a1, %lo(shorts)(a1) +; RV32I-NEXT: bne a1, a0, .LBB1_3 ; RV32I-NEXT: # %bb.1: # %entry -; RV32I-NEXT: lui a1, %hi(shorts+2) -; RV32I-NEXT: lh a1, %lo(shorts+2)(a1) -; RV32I-NEXT: addi a0, a0, -1 -; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: lui a0, %hi(shorts+2) +; RV32I-NEXT: lhu a0, %lo(shorts+2)(a0) ; RV32I-NEXT: addi a1, zero, 7 ; RV32I-NEXT: bne a0, a1, .LBB1_3 ; RV32I-NEXT: # %bb.2: # %if.end