Polly sometimes mishandles debug information inside SCoPs which eventually prevents generating optimised code. This patch strips this information the code before it's verified.
This behaviour was first observed when attempting to optimise gemm written in Julia using Polly-ACC. The code-generation of the NVPTX kernel used to fail silently until the error was revealed by passing &(llvm::errs()) to verifyModule in GPUNodebuilder::finalizeKernelFunction,
DICompileUnit not listed in llvm.dbg.cu !11 = distinct !DICompileUnit(language: DW_LANG_C89, file: !3, producer: "julia", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !12)
This was solved by calling "llvm::StripDebugInfo" right before verifyModule.
--- a/lib/CodeGen/PPCGCodeGeneration.cpp +++ b/lib/CodeGen/PPCGCodeGeneration.cpp @@ -28,6 +28,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/LegacyPassManager.h" @@ -1707,7 +1708,8 @@ std::string GPUNodeBuilder::createKernelASM() { } std::string GPUNodeBuilder::finalizeKernelFunction() { - if (verifyModule(*GPUModule)) { + //llvm::StripDebugInfo(*GPUModule); + if (verifyModule(*GPUModule,&(llvm::errs()))) { BuildSuccessful = false; return ""; }
Julia then crashed with the following error,
Invalid user of intrinsic instruction! store void (metadata, i64, metadata, metadata)* @llvm.dbg.value, void (metadata, i64, metadata, metadata)** %polly_launch_0_param_7, align 8 LLVM ERROR: Broken module found, compilation aborted!
Since this looked like a debug-intrinsic, the solution (a guess) was to use polly::isIgnoredIntrinsic to identify such instructions and avoid adding them in findReferencesInBlock, in IslNodeBuilder.cpp.
--- a/lib/CodeGen/IslNodeBuilder.cpp +++ b/lib/CodeGen/IslNodeBuilder.cpp @@ -204,7 +204,9 @@ int IslNodeBuilder::getNumberOfIterations(__isl_keep isl_ast_node *For) { /// Extract the values and SCEVs needed to generate code for a block. static int findReferencesInBlock(struct SubtreeReferences &References, const ScopStmt *Stmt, const BasicBlock *BB) { - for (const Instruction &Inst : *BB) + for (const Instruction &Inst : *BB) { + if (polly::isIgnoredIntrinsic(&Inst)) + continue; for (Value *SrcVal : Inst.operands()) { auto *Scope = References.LI.getLoopFor(BB); if (canSynthesize(SrcVal, References.S, &References.SE, Scope)) { @@ -213,6 +215,7 @@ static int findReferencesInBlock(struct SubtreeReferences &References, } else if (Value *NewVal = References.GlobalMap.lookup(SrcVal)) References.Values.insert(NewVal); } + } return 0; }
NVPTX code was then successfully generated.
We usually do not have braces around a single statement in an if-condition.