[llvm] 5c91b98 - [ARMISelLowering] avoid emitting libcalls to __mulodi4()
Nick Desaulniers via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 27 15:15:05 PDT 2021
Author: Nick Desaulniers
Date: 2021-08-27T15:14:47-07:00
New Revision: 5c91b98c5d45243352bf10262454bcac77cd3fed
URL: https://github.com/llvm/llvm-project/commit/5c91b98c5d45243352bf10262454bcac77cd3fed
DIFF: https://github.com/llvm/llvm-project/commit/5c91b98c5d45243352bf10262454bcac77cd3fed.diff
LOG: [ARMISelLowering] avoid emitting libcalls to __mulodi4()
__has_builtin(__builtin_mul_overflow) returns true for 32b ARM targets,
but Clang is deferring to compiler RT when encountering `long long`
types. This breaks sanitizer builds of the Linux kernel that are using
__builtin_mul_overflow with these types for these targets.
If the semantics of __has_builtin mean "the compiler resolves these,
always" then we shouldn't conditionally emit a libcall.
This will still need to be worked around in the Linux kernel in order to
continue to support allmodconfig builds of the Linux kernel for this
target with older releases of clang.
Link: https://bugs.llvm.org/show_bug.cgi?id=28629
Link: https://github.com/ClangBuiltLinux/linux/issues/1438
Reviewed By: rengolin
Differential Revision: https://reviews.llvm.org/D108842
Added:
Modified:
llvm/lib/Target/ARM/ARMISelLowering.cpp
llvm/test/CodeGen/ARM/overflow-intrinsic-optimizations.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 5366a64bcf899..fb150b32cdf21 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -545,6 +545,8 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setLibcallName(RTLIB::SRL_I128, nullptr);
setLibcallName(RTLIB::SRA_I128, nullptr);
setLibcallName(RTLIB::MUL_I128, nullptr);
+ setLibcallName(RTLIB::MULO_I64, nullptr);
+ setLibcallName(RTLIB::MULO_I128, nullptr);
// RTLIB
if (Subtarget->isAAPCS_ABI() &&
diff --git a/llvm/test/CodeGen/ARM/overflow-intrinsic-optimizations.ll b/llvm/test/CodeGen/ARM/overflow-intrinsic-optimizations.ll
index 048a1205febea..1a7809e369ea1 100644
--- a/llvm/test/CodeGen/ARM/overflow-intrinsic-optimizations.ll
+++ b/llvm/test/CodeGen/ARM/overflow-intrinsic-optimizations.ll
@@ -234,6 +234,22 @@ while.end:
ret i32 %conv
}
+define i1 @no__mulodi4(i32 %a, i64 %b, i32* %c) {
+; CHECK-LABEL: no__mulodi4
+; CHECK-NOT: bl __mulodi4
+entry:
+ %0 = sext i32 %a to i64
+ %1 = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %0, i64 %b)
+ %2 = extractvalue { i64, i1 } %1, 1
+ %3 = extractvalue { i64, i1 } %1, 0
+ %4 = trunc i64 %3 to i32
+ %5 = sext i32 %4 to i64
+ %6 = icmp ne i64 %3, %5
+ %7 = or i1 %2, %6
+ store i32 %4, i32* %c, align 4
+ ret i1 %7
+}
+
declare void @llvm.trap() #2
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) #1
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1
@@ -241,3 +257,4 @@ declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) #1
declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) #1
declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) #1
declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) #1
+declare { i64, i1 } @llvm.smul.with.overflow.i64(i64, i64)
More information about the llvm-commits
mailing list