[llvm] [SDag][ARM][RISCV] Allow lowering CTPOP into a libcall (PR #101786)

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 24 03:41:28 PDT 2025


mstorsjo wrote:

FYI, this showed up as issues while building for armv7 windows in MSVC style environments; in an MSVC style environment, we don't have the regular libgcc/compiler-rt builtins, only the ones shipped with MSVC.

I can work around it with a change like this:
```diff
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index bdebd842b011..d65d48a6611f 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1221,8 +1221,13 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::ROTR, VT, Expand);
   }
   setOperationAction(ISD::CTTZ,  MVT::i32, Custom);
-  setOperationAction(ISD::CTPOP, MVT::i32, LibCall);
-  setOperationAction(ISD::CTPOP, MVT::i64, LibCall);
+  if (Subtarget->isTargetMSVC()) {
+    setOperationAction(ISD::CTPOP, MVT::i32, Expand);
+    setOperationAction(ISD::CTPOP, MVT::i64, Expand);
+  } else {
+    setOperationAction(ISD::CTPOP, MVT::i32, LibCall);
+    setOperationAction(ISD::CTPOP, MVT::i64, LibCall);
+  }
   if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) {
     setOperationAction(ISD::CTLZ, MVT::i32, Expand);
     setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, LibCall);
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index 7329d3f2055f..9a9a9b45adb2 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -340,6 +340,7 @@ public:
   bool isTargetWatchABI() const { return TargetTriple.isWatchABI(); }
   bool isTargetDriverKit() const { return TargetTriple.isDriverKit(); }
   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
+  bool isTargetMSVC() const { return TargetTriple.isWindowsMSVCEnvironment(); }
   bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
   bool isTargetNetBSD() const { return TargetTriple.isOSNetBSD(); }
   bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
```

It's probably fine to just use the existing `isTargetWindows()` as well, but for an `armv7-windows-gnu` target, we can use  libgcc/compiler-rt style libcalls if we want to, but not for `armv7-windows-msvc`.

I see this was already somewhat turned off again, but I'd appreciate if you can fold this in before reenabling!

https://github.com/llvm/llvm-project/pull/101786


More information about the llvm-commits mailing list