[llvm] 9505b5c - [AVR] Do not use divmod calls for bigger integers
Ayke van Laethem via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 20 04:57:05 PDT 2020
Author: Ayke van Laethem
Date: 2020-04-20T13:56:38+02:00
New Revision: 9505b5cb66856a53ef2416aaf65adc85d749fd42
URL: https://github.com/llvm/llvm-project/commit/9505b5cb66856a53ef2416aaf65adc85d749fd42
DIFF: https://github.com/llvm/llvm-project/commit/9505b5cb66856a53ef2416aaf65adc85d749fd42.diff
LOG: [AVR] Do not use divmod calls for bigger integers
The avr-libc provides *divmodqi4, *divmodhi4, and *divmodsi4 functions,
but does not provide a *divmoddi4. Instead it provides regular *divdi3
and *moddi3 functions.
Note that avr-libc doesn't support *divti3 or *modti3 for 128-bit
integer manipulation.
Source:
https://github.com/gcc-mirror/gcc/blob/releases/gcc-5.4.0/libgcc/config/avr/lib1funcs.S
Differential Revision: https://reviews.llvm.org/D78437
Added:
Modified:
llvm/lib/Target/AVR/AVRISelLowering.cpp
llvm/test/CodeGen/AVR/div.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index be8f8f75a21e..21363bbbf910 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -151,10 +151,12 @@ AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM,
setOperationAction(ISD::SREM, MVT::i16, Expand);
// Make division and modulus custom
- for (MVT VT : MVT::integer_valuetypes()) {
- setOperationAction(ISD::UDIVREM, VT, Custom);
- setOperationAction(ISD::SDIVREM, VT, Custom);
- }
+ setOperationAction(ISD::UDIVREM, MVT::i8, Custom);
+ setOperationAction(ISD::UDIVREM, MVT::i16, Custom);
+ setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
+ setOperationAction(ISD::SDIVREM, MVT::i8, Custom);
+ setOperationAction(ISD::SDIVREM, MVT::i16, Custom);
+ setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
// Do not use MUL. The AVR instructions are closer to SMUL_LOHI &co.
setOperationAction(ISD::MUL, MVT::i8, Expand);
@@ -190,41 +192,29 @@ AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM,
// improvements in how we treat 16-bit "registers" to be feasible.
}
- // Division rtlib functions (not supported)
+ // Division rtlib functions (not supported), use divmod functions instead
setLibcallName(RTLIB::SDIV_I8, nullptr);
setLibcallName(RTLIB::SDIV_I16, nullptr);
setLibcallName(RTLIB::SDIV_I32, nullptr);
- setLibcallName(RTLIB::SDIV_I64, nullptr);
- setLibcallName(RTLIB::SDIV_I128, nullptr);
setLibcallName(RTLIB::UDIV_I8, nullptr);
setLibcallName(RTLIB::UDIV_I16, nullptr);
setLibcallName(RTLIB::UDIV_I32, nullptr);
- setLibcallName(RTLIB::UDIV_I64, nullptr);
- setLibcallName(RTLIB::UDIV_I128, nullptr);
- // Modulus rtlib functions (not supported)
+ // Modulus rtlib functions (not supported), use divmod functions instead
setLibcallName(RTLIB::SREM_I8, nullptr);
setLibcallName(RTLIB::SREM_I16, nullptr);
setLibcallName(RTLIB::SREM_I32, nullptr);
- setLibcallName(RTLIB::SREM_I64, nullptr);
- setLibcallName(RTLIB::SREM_I128, nullptr);
setLibcallName(RTLIB::UREM_I8, nullptr);
setLibcallName(RTLIB::UREM_I16, nullptr);
setLibcallName(RTLIB::UREM_I32, nullptr);
- setLibcallName(RTLIB::UREM_I64, nullptr);
- setLibcallName(RTLIB::UREM_I128, nullptr);
// Division and modulus rtlib functions
setLibcallName(RTLIB::SDIVREM_I8, "__divmodqi4");
setLibcallName(RTLIB::SDIVREM_I16, "__divmodhi4");
setLibcallName(RTLIB::SDIVREM_I32, "__divmodsi4");
- setLibcallName(RTLIB::SDIVREM_I64, "__divmoddi4");
- setLibcallName(RTLIB::SDIVREM_I128, "__divmodti4");
setLibcallName(RTLIB::UDIVREM_I8, "__udivmodqi4");
setLibcallName(RTLIB::UDIVREM_I16, "__udivmodhi4");
setLibcallName(RTLIB::UDIVREM_I32, "__udivmodsi4");
- setLibcallName(RTLIB::UDIVREM_I64, "__udivmoddi4");
- setLibcallName(RTLIB::UDIVREM_I128, "__udivmodti4");
// Several of the runtime library functions use a special calling conv
setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::AVR_BUILTIN);
@@ -371,12 +361,6 @@ SDValue AVRTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
case MVT::i32:
LC = IsSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
- case MVT::i64:
- LC = IsSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
- break;
- case MVT::i128:
- LC = IsSigned ? RTLIB::SDIVREM_I128 : RTLIB::UDIVREM_I128;
- break;
}
SDValue InChain = DAG.getEntryNode();
diff --git a/llvm/test/CodeGen/AVR/div.ll b/llvm/test/CodeGen/AVR/div.ll
index 7626ecb81722..b22229421963 100644
--- a/llvm/test/CodeGen/AVR/div.ll
+++ b/llvm/test/CodeGen/AVR/div.ll
@@ -65,15 +65,7 @@ define i32 @sdiv32(i32 %a, i32 %b) {
; Unsigned 64-bit division
define i64 @udiv64(i64 %a, i64 %b) {
; CHECK-LABEL: udiv64:
-; CHECK: call __udivmoddi4
-; CHECK-NEXT: ldd r18, Y+1
-; CHECK-NEXT: ldd r19, Y+2
-; CHECK-NEXT: ldd r20, Y+3
-; CHECK-NEXT: ldd r21, Y+4
-; CHECK-NEXT: ldd r22, Y+5
-; CHECK-NEXT: ldd r23, Y+6
-; CHECK-NEXT: ldd r24, Y+7
-; CHECK-NEXT: ldd r25, Y+8
+; CHECK: call __udivdi3
; CHECK: ret
%quot = udiv i64 %a, %b
ret i64 %quot
@@ -82,15 +74,7 @@ define i64 @udiv64(i64 %a, i64 %b) {
; Signed 64-bit division
define i64 @sdiv64(i64 %a, i64 %b) {
; CHECK-LABEL: sdiv64:
-; CHECK: call __divmoddi4
-; CHECK-NEXT: ldd r18, Y+1
-; CHECK-NEXT: ldd r19, Y+2
-; CHECK-NEXT: ldd r20, Y+3
-; CHECK-NEXT: ldd r21, Y+4
-; CHECK-NEXT: ldd r22, Y+5
-; CHECK-NEXT: ldd r23, Y+6
-; CHECK-NEXT: ldd r24, Y+7
-; CHECK-NEXT: ldd r25, Y+8
+; CHECK: call __divdi3
; CHECK: ret
%quot = sdiv i64 %a, %b
ret i64 %quot
@@ -99,7 +83,7 @@ define i64 @sdiv64(i64 %a, i64 %b) {
; Unsigned 128-bit division
define i128 @udiv128(i128 %a, i128 %b) {
; CHECK-LABEL: udiv128:
-; CHECK: call __udivmodti4
+; CHECK: call __udivti3
; CHECK: ret
%quot = udiv i128 %a, %b
ret i128 %quot
@@ -108,7 +92,7 @@ define i128 @udiv128(i128 %a, i128 %b) {
; Signed 128-bit division
define i128 @sdiv128(i128 %a, i128 %b) {
; CHECK-LABEL: sdiv128:
-; CHECK: call __divmodti4
+; CHECK: call __divti3
; CHECK: ret
%quot = sdiv i128 %a, %b
ret i128 %quot
More information about the llvm-commits
mailing list