[PATCH] D38861: [CodeGen] Error on unsupported checked multiplies early
Vedant Kumar via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 12 15:26:17 PDT 2017
vsk created this revision.
LLVM's smul.with.overflow intrinsic isn't supported on X86 for bit
widths larger than 64, or on X86-64 for bit widths larger than 128.
The failure mode is either a linker error ("the __muloti4 builtin isn't
available for this target") or an assertion failure ("SelectionDAG
doesn't know what builtin to call").
Until we actually add builtin support for 128-bit multiply-with-overflow
on X86, we should error-out on unsupported calls as early as possible.
https://bugs.llvm.org/show_bug.cgi?id=34920
https://reviews.llvm.org/D38861
Files:
lib/CodeGen/CGBuiltin.cpp
test/CodeGen/builtins-overflow-unsupported.c
test/CodeGen/builtins-overflow.c
Index: test/CodeGen/builtins-overflow.c
===================================================================
--- test/CodeGen/builtins-overflow.c
+++ test/CodeGen/builtins-overflow.c
@@ -2,7 +2,7 @@
// rdar://13421498
// RUN: %clang_cc1 -triple "i686-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck %s
-// RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck %s --check-prefixes=CHECK,M64
// RUN: %clang_cc1 -triple "x86_64-mingw32" -emit-llvm -x c %s -o - | FileCheck %s
extern unsigned UnsignedErrorCode;
@@ -338,3 +338,20 @@
return LongLongErrorCode;
return result;
}
+
+#if defined(__LP64__)
+signed long long test_mixed_sign_mul_i64(signed long long a, unsigned long long b) {
+ // M64-LABEL: define i64 @test_mixed_sign_mul_i64
+ // M64: sext i64 {{.*}} to i65
+ // M64-NEXT: zext i64 {{.*}} to i65
+ // M64-NEXT: call { i65, i1 } @llvm.smul.with.overflow.i65
+ // M64-NEXT: [[OFLOW_1:%.*]] = extractvalue { i65, i1 } {{.*}}, 1
+ // M64-NEXT: [[RES:%.*]] = extractvalue { i65, i1 } {{.*}}, 0
+ // M64-NEXT: [[RES_TRUNC:%.*]] = trunc i65 {{.*}} to i64
+ // M64-NEXT: [[RES_EXT:%.*]] = zext i64 {{.*}} to i65
+ // M64-NEXT: [[OFLOW_2:%.*]] = icmp ne i65 [[RES]], [[RES_EXT]]
+ // M64-NEXT: or i1 [[OFLOW_1]], [[OFLOW_2]]
+ // M64-NEXT: store i64 [[RES_TRUNC]]
+ return __builtin_mul_overflow(a, b, &b);
+}
+#endif
Index: test/CodeGen/builtins-overflow-unsupported.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtins-overflow-unsupported.c
@@ -0,0 +1,14 @@
+// RUN: not %clang_cc1 -triple "i686-unknown-unknown" -emit-llvm -x c %s -o - 2>&1 | FileCheck %s --check-prefix=M32
+// RUN: not %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - 2>&1 | FileCheck %s --check-prefix=M64
+
+signed long long try_smul_i65(signed long long a, unsigned long long b) {
+ // M32: [[@LINE+1]]:10: error: cannot compile this __builtin_mul_overflow with mixed-sign operands yet
+ return __builtin_mul_overflow(a, b, &b);
+}
+
+#if defined(__LP64__)
+__int128_t try_smul_i29(__int128_t a, __uint128_t b) {
+ // M64: [[@LINE+1]]:10: error: cannot compile this __builtin_mul_overflow with mixed-sign operands yet
+ return __builtin_mul_overflow(a, b, &b);
+}
+#endif
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -2248,11 +2248,23 @@
WidthAndSignedness EncompassingInfo =
EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo});
+ llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy);
+
+ const auto &Triple = getTarget().getTriple();
+ if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
+ if ((EncompassingInfo.Width > 64 &&
+ Triple.getArch() == llvm::Triple::ArchType::x86) ||
+ (EncompassingInfo.Width > 128 &&
+ Triple.getArch() == llvm::Triple::ArchType::x86_64)) {
+ CGM.ErrorUnsupported(E,
+ "__builtin_mul_overflow with mixed-sign operands");
+ return RValue::get(llvm::UndefValue::get(ResultLLVMTy));
+ }
+ }
+
llvm::Type *EncompassingLLVMTy =
llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width);
- llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy);
-
llvm::Intrinsic::ID IntrinsicId;
switch (BuiltinID) {
default:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38861.118850.patch
Type: text/x-patch
Size: 3566 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171012/d529706b/attachment.bin>
More information about the cfe-commits
mailing list