[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
This commit is contained in:
Alex Bradbury 2018-04-26 14:04:18 +00:00
parent e74f519241
commit 15e894baee
3 changed files with 22 additions and 10 deletions

View File

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

View File

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

View File

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