[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