[RISCV] Implement isTruncateFree

Adapted from ARM's implementation introduced in r313533 and r314280.

llvm-svn: 330940
This commit is contained in:
Alex Bradbury 2018-04-26 13:37:00 +00:00
parent a331f91853
commit 130b8b3f2b
4 changed files with 55 additions and 0 deletions

View File

@ -191,6 +191,26 @@ bool RISCVTargetLowering::isLegalAddImmediate(int64_t Imm) const {
return isInt<12>(Imm);
}
// On RV32, 64-bit integers are split into their high and low parts and held
// in two different registers, so the trunc is free since the low register can
// just be used.
bool RISCVTargetLowering::isTruncateFree(Type *SrcTy, Type *DstTy) const {
if (Subtarget.is64Bit() || !SrcTy->isIntegerTy() || !DstTy->isIntegerTy())
return false;
unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
unsigned DestBits = DstTy->getPrimitiveSizeInBits();
return (SrcBits == 64 && DestBits == 32);
}
bool RISCVTargetLowering::isTruncateFree(EVT SrcVT, EVT DstVT) const {
if (Subtarget.is64Bit() || SrcVT.isVector() || DstVT.isVector() ||
!SrcVT.isInteger() || !DstVT.isInteger())
return false;
unsigned SrcBits = SrcVT.getSizeInBits();
unsigned DestBits = DstVT.getSizeInBits();
return (SrcBits == 64 && DestBits == 32);
}
// 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

@ -44,6 +44,8 @@ public:
Instruction *I = nullptr) const override;
bool isLegalICmpImmediate(int64_t Imm) const override;
bool isLegalAddImmediate(int64_t Imm) const override;
bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
// Provide custom lowering hooks for some operations.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;

View File

@ -0,0 +1,5 @@
config.suffixes = ['.ll']
targets = set(config.root.targets_to_build.split())
if not 'RISCV' in targets:
config.unsupported = True

View File

@ -0,0 +1,28 @@
;RUN: opt -S -simplifycfg -mtriple=riscv32 < %s | FileCheck %s
; Test case taken from test/Transforms/SimplifyCFG/ARM/select-trunc-i64.ll.
; A correct implementation of isTruncateFree allows this test case to be
; reduced to a single basic block.
; CHECK-LABEL: select_trunc_i64
; CHECK-NOT: br
; CHECK: select
; CHECK: select
define i32 @select_trunc_i64(i32 %a, i32 %b) {
entry:
%conv = sext i32 %a to i64
%conv1 = sext i32 %b to i64
%add = add nsw i64 %conv1, %conv
%cmp = icmp sgt i64 %add, 2147483647
br i1 %cmp, label %cond.end7, label %cond.false
cond.false: ; preds = %entry
%0 = icmp sgt i64 %add, -2147483648
%cond = select i1 %0, i64 %add, i64 -2147483648
%extract.t = trunc i64 %cond to i32
br label %cond.end7
cond.end7: ; preds = %cond.false, %entry
%cond8.off0 = phi i32 [ 2147483647, %entry ], [ %extract.t, %cond.false ]
ret i32 %cond8.off0
}