[PATCH] D13285: Fix for bug 24196: clang fails on assertion on complex doubles multiplication when EH is enabled

Denis Zobnin via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 30 05:51:29 PDT 2015


d.zobnin.bugzilla created this revision.
d.zobnin.bugzilla added reviewers: rsmith, rjmccall.
d.zobnin.bugzilla added a subscriber: cfe-commits.

This patch fixes an assertion failure, caused by EmitCall function producing llvm::InvokeInst* when llvm::CallInst* is needed (when multiplication of complex arguments is being emitted).

http://reviews.llvm.org/D13285

Files:
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGenCXX/complex_mul_call.cpp

Index: lib/CodeGen/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -592,7 +592,7 @@
   llvm::Instruction *Call;
 
   RValue Res = CGF.EmitCall(FuncInfo, Func, ReturnValueSlot(), Args,
-                            nullptr, &Call);
+                            nullptr, &Call, /*forceCallInstCreation =*/ true);
   cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC());
   cast<llvm::CallInst>(Call)->setDoesNotThrow();
 
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -3102,9 +3102,17 @@
                                  ReturnValueSlot ReturnValue,
                                  const CallArgList &CallArgs,
                                  const Decl *TargetDecl,
-                                 llvm::Instruction **callOrInvoke) {
+                                 llvm::Instruction **callOrInvoke,
+                                 bool forceCallInstCreation) {
   // FIXME: We no longer need the types from CallArgs; lift up and simplify.
 
+  // It may be nessesary to create a CallInst* even if TargetDecl is not given
+  // (e. g. when emitting a complex operation call). Without TargetDecl there is
+  // no way to check the NoUnwind attribute required for CallInst creation. Use
+  // specific flag then, but take care of possible logical violations.
+  assert(!(TargetDecl && forceCallInstCreation) &&
+         "Should not force creation of CallInst if TargetDecl is present!");
+
   // Handle struct-return functions by passing a pointer to the
   // location that we would like to return into.
   QualType RetTy = CallInfo.getReturnType();
@@ -3442,7 +3450,7 @@
     InvokeDest = getInvokeDest();
 
   llvm::CallSite CS;
-  if (!InvokeDest) {
+  if (!InvokeDest || forceCallInstCreation) {
     CS = Builder.CreateCall(Callee, IRCallArgs);
   } else {
     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -2651,7 +2651,8 @@
                   ReturnValueSlot ReturnValue,
                   const CallArgList &Args,
                   const Decl *TargetDecl = nullptr,
-                  llvm::Instruction **callOrInvoke = nullptr);
+                  llvm::Instruction **callOrInvoke = nullptr,
+                  bool forceCallInstCreation = false);
 
   RValue EmitCall(QualType FnType, llvm::Value *Callee, const CallExpr *E,
                   ReturnValueSlot ReturnValue,
Index: test/CodeGenCXX/complex_mul_call.cpp
===================================================================
--- test/CodeGenCXX/complex_mul_call.cpp
+++ test/CodeGenCXX/complex_mul_call.cpp
@@ -0,0 +1,24 @@
+// Check that multiplication of complex arguments is performed properly without
+// assersion fails when exceptions are enabled.
+//
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s
+
+struct A {
+  int x;
+  A() { x = 10; }
+  ~A() { x = 20; }
+};
+
+int main() {
+  {
+    A a;
+    double __complex__ d;
+    float __complex__ f;
+    // CHECK-LABEL: main
+    // CHECK-DAG: call {{.*}} @__muldc3
+    double __complex__ d1 = d * d;
+    // CHECK-DAG: call {{.*}} @__mulsc3
+    float __complex__ f1 = f * f;
+  }
+  return 0;
+}


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13285.36084.patch
Type: text/x-patch
Size: 3526 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150930/7a756ce1/attachment-0001.bin>


More information about the cfe-commits mailing list