[llvm] r340458 - [ARM] Lower llvm.ctlz.i32 to a libcall when clz is not available.

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 22 14:47:14 PDT 2018


Author: efriedma
Date: Wed Aug 22 14:47:14 2018
New Revision: 340458

URL: http://llvm.org/viewvc/llvm-project?rev=340458&view=rev
Log:
[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


Modified:
    llvm/trunk/include/llvm/IR/RuntimeLibcalls.def
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
    llvm/trunk/test/CodeGen/ARM/clz.ll

Modified: llvm/trunk/include/llvm/IR/RuntimeLibcalls.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/RuntimeLibcalls.def?rev=340458&r1=340457&r2=340458&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/RuntimeLibcalls.def (original)
+++ llvm/trunk/include/llvm/IR/RuntimeLibcalls.def Wed Aug 22 14:47:14 2018
@@ -83,6 +83,9 @@ HANDLE_LIBCALL(UDIVREM_I64, nullptr)
 HANDLE_LIBCALL(UDIVREM_I128, nullptr)
 HANDLE_LIBCALL(NEG_I32, "__negsi2")
 HANDLE_LIBCALL(NEG_I64, "__negdi2")
+HANDLE_LIBCALL(CTLZ_I32, "__clzsi2")
+HANDLE_LIBCALL(CTLZ_I64, "__clzdi2")
+HANDLE_LIBCALL(CTLZ_I128, "__clzti2")
 
 // Floating-point
 HANDLE_LIBCALL(ADD_F32, "__addsf3")

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=340458&r1=340457&r2=340458&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Aug 22 14:47:14 2018
@@ -4262,6 +4262,21 @@ void SelectionDAGLegalize::ConvertNodeTo
                                        RTLIB::MUL_I16, RTLIB::MUL_I32,
                                        RTLIB::MUL_I64, RTLIB::MUL_I128));
     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.

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=340458&r1=340457&r2=340458&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Aug 22 14:47:14 2018
@@ -850,8 +850,10 @@ ARMTargetLowering::ARMTargetLowering(con
   }
   setOperationAction(ISD::CTTZ,  MVT::i32, Custom);
   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_ZERO_UNDEF, MVT::i32, LibCall);
+  }
 
   // @llvm.readcyclecounter requires the Performance Monitors extension.
   // Default to the 0 expansion on unsupported platforms.

Modified: llvm/trunk/test/CodeGen/ARM/clz.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/clz.ll?rev=340458&r1=340457&r2=340458&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/clz.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/clz.ll Wed Aug 22 14:47:14 2018
@@ -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)
 
 define i32 @test(i32 %x) {
-; CHECK: test
-; CHECK: clz r0, r0
+; CHECK-LABEL: test
+; INLINE: clz r0, r0
+; LIBCALL: b __clzsi2
         %tmp.1 = call i32 @llvm.ctlz.i32( i32 %x, i1 true )
         ret i32 %tmp.1
 }




More information about the llvm-commits mailing list