New user self-registration is disabled due to spam. For an account please email bugs-admin@lists.llvm.org with your e-mail address and full name.

Bug 24141 - Clang asserts with -menable-unsafe-fp-math
Summary: Clang asserts with -menable-unsafe-fp-math
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Common Code Generator Code (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Sanjay Patel
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-07-15 17:28 PDT by rtrieu
Modified: 2015-07-29 11:13 PDT (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description rtrieu 2015-07-15 17:28:34 PDT
Reproduction:
struct pair {
  double first;
  double second;
  pair() : first(0), second(0) {}
};

static pair ReturnPair(double x) {
  double Dnext = 1 + (2) * x;
  return pair();
}

void Run() {
  double x = 0;
  while (true) {
    pair Q = ReturnPair(x);
    double step =  Q.first / Q.second;
    x -= step;
  }
}

Command line:
clang -cc1 -emit-obj -O1 -menable-unsafe-fp-math foo.cpp

Cause:
SelectionDAG::getNode is called with a null pointer for the N1 parameter, which the function assumes is non-null.  The actual assert is triggered inside casting code when N1 is the argument to a dyn_cast.

Stack dump:
0.	Program arguments: clang -cc1 -emit-obj -O1 -menable-unsafe-fp-math foo.cpp 
1.	<eof> parser at end of file
2.	Code generation
3.	Running pass 'Function Pass Manager' on module 'foo.cpp'.
4.	Running pass 'X86 DAG->DAG Instruction Selection' on function '@_Z3Runv'
Aborted (core dumped)

clang: ../include/llvm/Support/Casting.h:81: static bool llvm::isa_impl_cl<llvm::ConstantSDNode, llvm::SDNode *>::doit(const From *) [To = llvm::ConstantSDNode, From = llvm::SDNode *]: Assertion `Val && "isa<> used on a null pointer"' failed.
#0 0x16801ad llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/local/bin/clang-3.5+0x16801ad)
#1 0x16815bb SignalHandler(int) (/usr/local/bin/clang-3.5+0x16815bb)
#2 0x7f988f1c3340 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10340)
#3 0x7f988e6efcc9 gsignal /build/buildd/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
#4 0x7f988e6f30d8 abort /build/buildd/eglibc-2.19/stdlib/abort.c:91:0
#5 0x7f988e6e8b86 __assert_fail_base /build/buildd/eglibc-2.19/assert/assert.c:92:0
#6 0x7f988e6e8c32 (/lib/x86_64-linux-gnu/libc.so.6+0x2fc32)
#7 0x1bc28ff llvm::SelectionDAG::getNode(unsigned int, llvm::SDLoc, llvm::EVT, llvm::SDValue, llvm::SDValue, llvm::SDNodeFlags const*) (/usr/local/bin/clang-3.5+0x1bc28ff)
#8 0x1b3a474 (anonymous namespace)::DAGCombiner::visit(llvm::SDNode*) (/usr/local/bin/clang-3.5+0x1b3a474)
#9 0x1b2186c (anonymous namespace)::DAGCombiner::combine(llvm::SDNode*) (/usr/local/bin/clang-3.5+0x1b2186c)
#10 0x1b20dcd llvm::SelectionDAG::Combine(llvm::CombineLevel, llvm::AliasAnalysis&, llvm::CodeGenOpt::Level) (/usr/local/bin/clang-3.5+0x1b20dcd)
#11 0x1c39a50 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/usr/local/bin/clang-3.5+0x1c39a50)
#12 0x1c392c8 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/usr/local/bin/clang-3.5+0x1c392c8)
#13 0x1c35fe4 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/usr/local/bin/clang-3.5+0x1c35fe4)
#14 0xdb9b81 (anonymous namespace)::X86DAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/usr/local/bin/clang-3.5+0xdb9b81)
#15 0x10b460c llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/usr/local/bin/clang-3.5+0x10b460c)
#16 0x1339fd4 llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/local/bin/clang-3.5+0x1339fd4)
#17 0x133a20b llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/local/bin/clang-3.5+0x133a20b)
#18 0x133a6f5 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/local/bin/clang-3.5+0x133a6f5)
#19 0x177d725 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::raw_pwrite_stream*) (/usr/local/bin/clang-3.5+0x177d725)
#20 0x1cf2965 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/usr/local/bin/clang-3.5+0x1cf2965)
#21 0x201f703 clang::ParseAST(clang::Sema&, bool, bool) (/usr/local/bin/clang-3.5+0x201f703)
#22 0x1a4cef2 clang::FrontendAction::Execute() (/usr/local/bin/clang-3.5+0x1a4cef2)
#23 0x1a1d07c clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/usr/local/bin/clang-3.5+0x1a1d07c)
#24 0x1ac5dfc clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/usr/local/bin/clang-3.5+0x1ac5dfc)
#25 0x706394 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/usr/local/bin/clang-3.5+0x706394)
#26 0x70512e main (/usr/local/bin/clang-3.5+0x70512e)
#27 0x7f988e6daec5 __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:321:0
#28 0x702173 _start (/usr/local/bin/clang-3.5+0x702173)
Comment 1 rtrieu 2015-07-15 19:14:58 PDT
Sanjay,

This bug first appears with your commit of r241826
Comment 2 David Majnemer 2015-07-16 15:36:57 PDT
Sanjay, here is some reduced IR:
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define void @f() #0 {
entry:
  br label %while.body

while.body:                                       ; preds = %while.body, %entry
  %x.0 = phi double [ undef, %entry ], [ %div, %while.body ]
  %call = call { double, double } @g(double %x.0)
  %xv0 = extractvalue { double, double } %call, 0
  %xv1 = extractvalue { double, double } %call, 1
  %div = fdiv double %xv0, %xv1
  br label %while.body
}

declare { double, double } @g(double)

attributes #0 = { "unsafe-fp-math"="true" }
Comment 3 Sanjay Patel 2015-07-19 18:21:21 PDT
Richard/David - thanks for the simple test case. Sorry for the delayed reply (vacation).

The test case exposes another problem with the repeated FP divisors optimization logic. It wasn't visible before r241826 because we weren't deleting uses() nodes. This is now done by CombineTo() where we were just doing a RAUW before.

In this test case, we have duplicate entries in the divisor node's uses() list. We can avoid the bug with a one-line patch to check that, but I'm not sure if that's the best fix. I haven't looked at IR with aggregates before this, so I wonder if the duplicate uses() entries are expected? Are duplicate uses() limited to only aggregates?

I'll post the patch via phab for review and further comment.
Comment 4 Sanjay Patel 2015-07-19 18:55:42 PDT
Patch posted for review:
http://reviews.llvm.org/D11345
Comment 5 Sanjay Patel 2015-07-24 10:47:56 PDT
Fix checked in:
http://reviews.llvm.org/rL243057
Comment 6 Sanjay Patel 2015-07-24 10:48:38 PDT
Oops - wrong bug report.
Comment 7 Sanjay Patel 2015-07-29 11:13:05 PDT
Fixes checked into trunk at:
http://reviews.llvm.org/rL243293
http://reviews.llvm.org/rL243498
http://reviews.llvm.org/rL243500

And minimal bug fix merged into 3.7 branch (thanks, Hans!) at:
http://reviews.llvm.org/rL243524