Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

clang crashes when calling a float sqrt/.. function with a double constant #16584

Open Quuxplusone opened 11 years ago

Quuxplusone commented 11 years ago
Bugzilla Link PR16585
Status NEW
Importance P normal
Reported by Stefan Hepp (stefan@stefant.org)
Reported on 2013-07-10 06:52:58 -0700
Last modified on 2015-05-22 09:20:40 -0700
Version trunk
Hardware PC Linux
CC emaste@freebsd.org, llvm-bugs@lists.llvm.org, rafael@espindo.la, richard-llvm@metafoo.co.uk
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Compiling this C code:

static float sqrt(val)
float val;
{
  return val;
}

int main(int argc, char** argv) {
    float f = sqrt(-2.0f * 0.1);
    return 1;
}

with "clang -O2 -o sqrt sqrt.c" causes the following assertion

clang-3.3: /home/stefan/Uni/tcrest/dev/llvm/lib/Support/APFloat.cpp:2950: float
llvm::APFloat::convertToFloat() const: Assertion `semantics == (const
llvm::fltSemantics*)&IEEEsingle && "Float semantics are not IEEEsingle"' failed.
0  clang-3.3       0x00000000013fd532 llvm::sys::PrintStackTrace(_IO_FILE*) + 34
1  clang-3.3       0x00000000013fd189
2  libpthread.so.0 0x00007fccbd4adbd0
3  libc.so.6       0x00007fccbc8ef037 gsignal + 55
4  libc.so.6       0x00007fccbc8f2698 abort + 328
5  libc.so.6       0x00007fccbc8e7e03
6  libc.so.6       0x00007fccbc8e7eb2
7  clang-3.3       0x000000000139c466
8  clang-3.3       0x0000000001161a7d llvm::ConstantFoldCall(llvm::Function*,
llvm::ArrayRef<llvm::Constant*>, llvm::TargetLibraryInfo const*) + 2941
9  clang-3.3       0x0000000001187da4 llvm::SimplifyCall(llvm::Value*,
llvm::Use*, llvm::Use*, llvm::DataLayout const*, llvm::TargetLibraryInfo
const*, llvm::DominatorTree const*) + 644
10 clang-3.3       0x000000000118e41b
llvm::SimplifyInstruction(llvm::Instruction*, llvm::DataLayout const*,
llvm::TargetLibraryInfo const*, llvm::DominatorTree const*) + 491
11 clang-3.3       0x0000000000fa7a0a
12 clang-3.3       0x0000000000fa8e84
13 clang-3.3       0x000000000130ee3f
llvm::FPPassManager::runOnFunction(llvm::Function&) + 639
14 clang-3.3       0x00000000013109c3
llvm::FunctionPassManagerImpl::run(llvm::Function&) + 163
15 clang-3.3       0x0000000001310af9
llvm::FunctionPassManager::run(llvm::Function&) + 105
16 clang-3.3       0x0000000001421c0d
clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions
const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::Module*,
clang::BackendAction, llvm::raw_ostream*) + 3389
17 clang-3.3       0x000000000141f82f
18 clang-3.3       0x00000000016f3732 clang::ParseAST(clang::Sema&, bool, bool)
+ 514
19 clang-3.3       0x000000000141e5e1 clang::CodeGenAction::ExecuteAction() + 97
20 clang-3.3       0x000000000161e139 clang::FrontendAction::Execute() + 265
21 clang-3.3       0x00000000015ffe15
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 357
22 clang-3.3       0x0000000001400552
clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1794
23 clang-3.3       0x0000000000667488 cc1_main(char const**, char const**, char
const*, void*) + 1208
24 clang-3.3       0x0000000000665d2e main + 4974
25 libc.so.6       0x00007fccbc8d9ea5 __libc_start_main + 245
26 clang-3.3       0x0000000000661c69
Stack dump:
0.      Program arguments: /home/stefan/Uni/tcrest/ssd/llvm-obj/bin/clang-3.3 -
cc1 -triple x86_64-unknown-linux-gnu -emit-obj -disable-free -main-file-name
sqrt.c -mrelocation-model static -fmath-errno -masm-verbose -mconstructor-
aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -momit-leaf-frame-
pointer -resource-dir /home/stefan/Uni/tcrest/ssd/llvm-obj/bin/../lib/clang/3.3
-internal-isystem /usr/local/include -internal-isystem
/home/stefan/Uni/tcrest/ssd/llvm-obj/bin/../lib/clang/3.3/include -internal-
externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem
/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir
/home/stefan/Uni/tcrest/ssd/test -ferror-limit 19 -fmessage-length 225 -
mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -
fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -
o /tmp/sqrt-3opIhb.o -x c sqrt.c
1.      <eof> parser at end of file
2.      Per-function optimization
3.      Running pass 'Early CSE' on function '@main'
clang-3.3: error: unable to execute command: Aborted (core dumped)
clang-3.3: error: clang frontend command failed due to signal (use -v to see
invocation)
clang version 3.3
Target: x86_64-unknown-linux-gnu
Thread model: posix

This seems to be new in clang 3.3. The reason for this is that the code checks
if the _return-type_ of the function is float, and then casts the operand to
float. This fails if the operand is a double expression (or if you define a
function called 'float sqrt(double x) { return x; }', by that matter. This
should happen for all functions named like libm functions (sqrt, sin, cos, ..).

The following patch fixes it for me (checks the type of the operand instead of
the function return type for casting):

diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index bc0dffc..5f8cb21 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -1302,9 +1302,9 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *>
Operands,
       /// directly but for all these it is true (float)(f((double)arg)) ==
       /// f(arg).  Long double not supported yet.
       double V;
-      if (Ty->isFloatTy())
+      if (Op->getType()->isFloatTy())
         V = Op->getValueAPF().convertToFloat();
-      else if (Ty->isDoubleTy())
+      else if (Op->getType()->isDoubleTy())
         V = Op->getValueAPF().convertToDouble();
       else {
         bool unused;
@@ -1477,9 +1477,9 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *>
Operands,
       if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
         return 0;
       double Op1V;
-      if (Ty->isFloatTy())
+      if (Op1->getType()->isFloatTy())
         Op1V = Op1->getValueAPF().convertToFloat();
-      else if (Ty->isDoubleTy())
+      else if (Op1->getType()->isDoubleTy())
         Op1V = Op1->getValueAPF().convertToDouble();
       else {
         bool unused;
@@ -1493,9 +1493,9 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *>
Operands,
           return 0;

         double Op2V;
-        if (Ty->isFloatTy())
+        if (Op2->getType()->isFloatTy())
           Op2V = Op2->getValueAPF().convertToFloat();
-        else if (Ty->isDoubleTy())
+        else if (Op2->getType()->isDoubleTy())
           Op2V = Op2->getValueAPF().convertToDouble();
         else {
           bool unused;
Quuxplusone commented 11 years ago

Please send your patch (with a testcase) to llvm-commits@cs.uiuc.edu.

Quuxplusone commented 9 years ago

Seems not reproducible now.