forked from OSchip/llvm-project
[ARM] Lower llvm.ctlz.i32 to a libcall when clz is not available.
The inline sequence is very long (about 70 bytes on Thumb1), so it's not really a good idea to inline it, especially when optimizing for size. Differential Revision: https://reviews.llvm.org/D47917 llvm-svn: 340458
This commit is contained in:
parent
20f9cd8821
commit
96e3cd85bd
|
@ -83,6 +83,9 @@ HANDLE_LIBCALL(UDIVREM_I64, nullptr)
|
||||||
HANDLE_LIBCALL(UDIVREM_I128, nullptr)
|
HANDLE_LIBCALL(UDIVREM_I128, nullptr)
|
||||||
HANDLE_LIBCALL(NEG_I32, "__negsi2")
|
HANDLE_LIBCALL(NEG_I32, "__negsi2")
|
||||||
HANDLE_LIBCALL(NEG_I64, "__negdi2")
|
HANDLE_LIBCALL(NEG_I64, "__negdi2")
|
||||||
|
HANDLE_LIBCALL(CTLZ_I32, "__clzsi2")
|
||||||
|
HANDLE_LIBCALL(CTLZ_I64, "__clzdi2")
|
||||||
|
HANDLE_LIBCALL(CTLZ_I128, "__clzti2")
|
||||||
|
|
||||||
// Floating-point
|
// Floating-point
|
||||||
HANDLE_LIBCALL(ADD_F32, "__addsf3")
|
HANDLE_LIBCALL(ADD_F32, "__addsf3")
|
||||||
|
|
|
@ -4262,6 +4262,21 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
|
||||||
RTLIB::MUL_I16, RTLIB::MUL_I32,
|
RTLIB::MUL_I16, RTLIB::MUL_I32,
|
||||||
RTLIB::MUL_I64, RTLIB::MUL_I128));
|
RTLIB::MUL_I64, RTLIB::MUL_I128));
|
||||||
break;
|
break;
|
||||||
|
case ISD::CTLZ_ZERO_UNDEF:
|
||||||
|
switch (Node->getSimpleValueType(0).SimpleTy) {
|
||||||
|
default:
|
||||||
|
llvm_unreachable("LibCall explicitly requested, but not available");
|
||||||
|
case MVT::i32:
|
||||||
|
Results.push_back(ExpandLibCall(RTLIB::CTLZ_I32, Node, false));
|
||||||
|
break;
|
||||||
|
case MVT::i64:
|
||||||
|
Results.push_back(ExpandLibCall(RTLIB::CTLZ_I64, Node, false));
|
||||||
|
break;
|
||||||
|
case MVT::i128:
|
||||||
|
Results.push_back(ExpandLibCall(RTLIB::CTLZ_I128, Node, false));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the original node with the legalized result.
|
// Replace the original node with the legalized result.
|
||||||
|
|
|
@ -850,8 +850,10 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||||
}
|
}
|
||||||
setOperationAction(ISD::CTTZ, MVT::i32, Custom);
|
setOperationAction(ISD::CTTZ, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
|
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
|
||||||
if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only())
|
if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) {
|
||||||
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
|
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
|
||||||
|
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, LibCall);
|
||||||
|
}
|
||||||
|
|
||||||
// @llvm.readcyclecounter requires the Performance Monitors extension.
|
// @llvm.readcyclecounter requires the Performance Monitors extension.
|
||||||
// Default to the 0 expansion on unsupported platforms.
|
// Default to the 0 expansion on unsupported platforms.
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
; RUN: llc -mtriple=arm-eabi -mattr=+v5t %s -o - | FileCheck %s
|
; RUN: llc -mtriple=arm-eabi -mattr=+v5t %s -o - | FileCheck %s -check-prefixes=CHECK,INLINE
|
||||||
|
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s -check-prefixes=CHECK,LIBCALL
|
||||||
|
|
||||||
declare i32 @llvm.ctlz.i32(i32, i1)
|
declare i32 @llvm.ctlz.i32(i32, i1)
|
||||||
|
|
||||||
define i32 @test(i32 %x) {
|
define i32 @test(i32 %x) {
|
||||||
; CHECK: test
|
; CHECK-LABEL: test
|
||||||
; CHECK: clz r0, r0
|
; INLINE: clz r0, r0
|
||||||
|
; LIBCALL: b __clzsi2
|
||||||
%tmp.1 = call i32 @llvm.ctlz.i32( i32 %x, i1 true )
|
%tmp.1 = call i32 @llvm.ctlz.i32( i32 %x, i1 true )
|
||||||
ret i32 %tmp.1
|
ret i32 %tmp.1
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue