[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:59:55 PDT 2017
vsk updated this revision to Diff 118857.
vsk added a comment.
Herald added a subscriber: aheejin.
- Update to check against a whitelist of supported targets.
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,9 @@
// 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 "wasm64-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck %s --check-prefixes=M64
+// RUN: %clang_cc1 -triple "mips64-unknown-unknown" -emit-llvm -x c %s -o - | FileCheck %s --check-prefixes=M64
// RUN: %clang_cc1 -triple "x86_64-mingw32" -emit-llvm -x c %s -o - | FileCheck %s
extern unsigned UnsignedErrorCode;
@@ -338,3 +340,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
@@ -397,6 +397,15 @@
return {Width, Signed};
}
+// Check if the target supports checked multiplication with 128-bit operands.
+static bool has128BitMulOverflowSupport(const llvm::Triple &Triple) {
+ if (!Triple.isArch64Bit())
+ return false;
+ return StringSwitch<bool>(llvm::Triple::getArchTypePrefix(Triple.getArch()))
+ .Cases("x86", "wasm", "mips", true)
+ .Default(false);
+}
+
Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) {
llvm::Type *DestType = Int8PtrTy;
if (ArgValue->getType() != DestType)
@@ -2248,11 +2257,21 @@
WidthAndSignedness EncompassingInfo =
EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo});
+ llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy);
+
+ if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
+ if ((EncompassingInfo.Width > 64 &&
+ !has128BitMulOverflowSupport(getTarget().getTriple())) ||
+ (EncompassingInfo.Width > 128)) {
+ 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.118857.patch
Type: text/x-patch
Size: 4235 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171012/1098a39e/attachment.bin>
More information about the cfe-commits
mailing list