[llvm] RuntimeLibcalls: Describe register-returning divmod libcall ABIs (PR #217825)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 23:30:40 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Teach RuntimeLibcallsInfo::getFunctionTy about the ARM AEABI
(__aeabi_*divmod) and Windows (__rt_*div*) divmod sigantures. Currently
the custom lowering to these calls hardcodes the call signature information,
but in the future this should be automatically handled.
Co-authored-by: Claude (Claude-Opus-4.8) <noreply@<!-- -->anthropic.com>
---
Full diff: https://github.com/llvm/llvm-project/pull/217825.diff
2 Files Affected:
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+57)
- (added) llvm/test/Transforms/Util/DeclareRuntimeLibcalls/divmod.ll (+26)
``````````diff
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 1befff9d5f00e..7a040c36d99a5 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -275,6 +275,63 @@ RuntimeLibcallsInfo::getFunctionTy(LLVMContext &Ctx, const Triple &TT,
false),
Attrs};
}
+ case RTLIB::impl___aeabi_idivmod:
+ case RTLIB::impl___aeabi_uidivmod:
+ case RTLIB::impl___aeabi_ldivmod:
+ case RTLIB::impl___aeabi_uldivmod:
+ case RTLIB::impl___rt_sdiv:
+ case RTLIB::impl___rt_udiv:
+ case RTLIB::impl___rt_sdiv64:
+ case RTLIB::impl___rt_udiv64: {
+ // The ARM AEABI (__aeabi_*divmod) and Windows (__rt_*div*) divmod functions
+ // return both values modeled as an inreg { iN, iN } struct (quotient,
+ // remainder). The __rt_*div* cases pass the arguments in opposite order.
+ bool IsSigned;
+ unsigned Bits;
+ switch (LibcallImpl) {
+ case RTLIB::impl___aeabi_idivmod:
+ case RTLIB::impl___rt_sdiv:
+ IsSigned = true;
+ Bits = 32;
+ break;
+ case RTLIB::impl___aeabi_uidivmod:
+ case RTLIB::impl___rt_udiv:
+ IsSigned = false;
+ Bits = 32;
+ break;
+ case RTLIB::impl___aeabi_ldivmod:
+ case RTLIB::impl___rt_sdiv64:
+ IsSigned = true;
+ Bits = 64;
+ break;
+ case RTLIB::impl___aeabi_uldivmod:
+ case RTLIB::impl___rt_udiv64:
+ IsSigned = false;
+ Bits = 64;
+ break;
+ default:
+ llvm_unreachable("unexpected divmod libcall");
+ }
+
+ Type *IntTy = IntegerType::get(Ctx, Bits);
+ StructType *RetTy = StructType::get(IntTy, IntTy);
+ FunctionType *FuncTy = FunctionType::get(RetTy, {IntTy, IntTy}, false);
+
+ AttrBuilder FuncAttrBuilder(Ctx);
+ for (Attribute::AttrKind Attr : CommonFnAttrs)
+ FuncAttrBuilder.addAttribute(Attr);
+ FuncAttrBuilder.addMemoryAttr(MemoryEffects::none());
+
+ AttributeList Attrs;
+ Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
+
+ Attribute::AttrKind ExtKind = IsSigned ? Attribute::SExt : Attribute::ZExt;
+ Attrs = Attrs.addRetAttribute(Ctx, Attribute::InReg);
+ Attrs = Attrs.addParamAttribute(Ctx, 0, ExtKind);
+ Attrs = Attrs.addParamAttribute(Ctx, 1, ExtKind);
+
+ return {FuncTy, Attrs};
+ }
case RTLIB::impl_sqrtf:
case RTLIB::impl_sqrt: {
AttrBuilder FuncAttrBuilder(Ctx);
diff --git a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/divmod.ll b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/divmod.ll
new file mode 100644
index 0000000000000..be7c8c62ff978
--- /dev/null
+++ b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/divmod.ll
@@ -0,0 +1,26 @@
+; REQUIRES: arm-registered-target
+
+; RUN: opt -S -passes=declare-runtime-libcalls -mtriple=armv7-none-eabi < %s | FileCheck -check-prefix=AEABI %s
+; RUN: opt -S -passes=declare-runtime-libcalls -mtriple=thumbv7-windows-msvc < %s | FileCheck -check-prefix=WINDOWS %s
+
+; RUN: opt -S -passes=declare-runtime-libcalls -mtriple=armv7-apple-ios5.0 < %s | FileCheck -check-prefix=DARWIN %s
+
+; AEABI: declare arm_aapcscc inreg { i32, i32 } @__aeabi_idivmod(i32 signext, i32 signext) #0
+; AEABI: declare arm_aapcscc inreg { i64, i64 } @__aeabi_ldivmod(i64 signext, i64 signext) #0
+; AEABI: declare arm_aapcscc inreg { i32, i32 } @__aeabi_uidivmod(i32 zeroext, i32 zeroext) #0
+; AEABI: declare arm_aapcscc inreg { i64, i64 } @__aeabi_uldivmod(i64 zeroext, i64 zeroext) #0
+; AEABI: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
+
+; WINDOWS: declare arm_aapcscc inreg { i32, i32 } @__rt_sdiv(i32 signext, i32 signext) #0
+; WINDOWS: declare arm_aapcscc inreg { i64, i64 } @__rt_sdiv64(i64 signext, i64 signext) #0
+; WINDOWS: declare arm_aapcscc inreg { i32, i32 } @__rt_udiv(i32 zeroext, i32 zeroext) #0
+; WINDOWS: declare arm_aapcscc inreg { i64, i64 } @__rt_udiv64(i64 zeroext, i64 zeroext) #0
+; WINDOWS: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
+
+; DARWIN: declare void @__divmodsi4(...)
+; DARWIN: declare void @__udivmodsi4(...)
+; DARWIN-NOT: inreg { i32, i32 } @__divmodsi4
+
+define void @f() {
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/217825
More information about the llvm-commits
mailing list