[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