Skip to content

[EDDI] Transforming a noexcept function could lead to malformed code #2

@EmilioCorigliano

Description

@EmilioCorigliano

Trying to perform the EDDI transformation on the following TestNoExcept function leads to a malformed code.

class myclass
{
public:
    myclass() {}
};

void TestNoExcept() noexcept { volatile myclass m_data; }

The LLVM-IR input to the EDDI module is the following:

; Function Attrs: mustprogress noinline nounwind optnone
define dso_local void @_Z12TestNoExceptv() #0 personality ptr @__gxx_personality_v0 !dbg !16 {
  %1 = alloca %class.myclass, align 1
  call void @llvm.dbg.declare(metadata ptr %1, metadata !20, metadata !DIExpression()), !dbg !22
  %2 = invoke noundef ptr @_ZN7myclassC2Ev(ptr noundef nonnull align 1 dereferenceable(1) %1)
          to label %3 unwind label %4, !dbg !22

3:                                                ; preds = %0
  ret void, !dbg !23

4:                                                ; preds = %0
  %5 = landingpad { ptr, i32 }
          catch ptr null, !dbg !22
  %6 = extractvalue { ptr, i32 } %5, 0, !dbg !22
  call void @__clang_call_terminate(ptr %6) #4, !dbg !22
  unreachable, !dbg !22
}

The EDDI LLVM-IR output is the following:

; Function Attrs: mustprogress noinline nounwind optnone
define dso_local void @_Z12TestNoExceptv_dup() #0 personality ptr @__gxx_personality_v0 !dbg !54 {
  %1 = alloca %class.myclass, align 1
  br label %VerificationBB, !dbg !55

VerificationBB:                                   ; preds = %0
  br label %2, !dbg !55

2:                                                ; preds = %VerificationBB
  call void @llvm.dbg.declare(metadata ptr %1, metadata !56, metadata !DIExpression()), !dbg !55
  %3 = alloca %class.myclass, align 1
  br label %VerificationBB1, !dbg !55

VerificationBB1:                                  ; preds = %2
  br label %4, !dbg !55

4:                                                ; preds = %VerificationBB1
  %5 = invoke ptr @_ZN7myclassC2Ev_dup(ptr %1, ptr %3)
          to label %6 unwind label %VerificationBB2, !dbg !55

6:                                                ; preds = %4
  ret void, !dbg !57

7:                                                ; No predecessors!
  %8 = landingpad { ptr, i32 }
          catch ptr null, !dbg !55
  %9 = extractvalue { ptr, i32 } %8, 0, !dbg !55
  %10 = extractvalue { ptr, i32 } %8, 0, !dbg !55
  br label %VerificationBB2, !dbg !55

VerificationBB2:                                  ; preds = %4, %7
  br label %11, !dbg !55

11:                                               ; preds = %VerificationBB2
  call void @__clang_call_terminate_dup(ptr %9, ptr %10), !dbg !55
  unreachable, !dbg !55
}

The compilation error is the following:

The unwind destination does not have an exception handling instruction!
  %5 = invoke ptr @_ZN7myclassC2Ev_dup(ptr %1, ptr %3)
          to label %6 unwind label %VerificationBB2, !dbg !20
Instruction does not dominate all uses!
  %9 = extractvalue { ptr, i32 } %8, 0, !dbg !20
  call void @__clang_call_terminate_dup(ptr %9, ptr %10), !dbg !20
Instruction does not dominate all uses!
  %10 = extractvalue { ptr, i32 } %8, 0, !dbg !20
  call void @__clang_call_terminate_dup(ptr %9, ptr %10), !dbg !20
The unwind destination does not have an exception handling instruction!
  %5 = invoke ptr @_ZN7myclassC2Ev_dup(ptr %1, ptr %3)
          to label %6 unwind label %VerificationBB2, !dbg !55
Instruction does not dominate all uses!
  %9 = extractvalue { ptr, i32 } %8, 0, !dbg !55
  call void @__clang_call_terminate_dup(ptr %9, ptr %10), !dbg !55
Instruction does not dominate all uses!
  %10 = extractvalue { ptr, i32 } %8, 0, !dbg !55
  call void @__clang_call_terminate_dup(ptr %9, ptr %10), !dbg !55
LLVM ERROR: Broken module found, compilation aborted!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /home/streben/Documenti/llvm-project/build/bin/opt -load-pass-plugin=/home/streben/Documenti/POLIMI/TESI/ASPIS/build/passes/libSEDDI.so --passes=eddi-verify ret_to_ref.bc -o out.bc
 #0 0x0000000004479646 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/streben/Documenti/llvm-project/llvm/lib/Support/Unix/Signals.inc:723:22
 #1 0x0000000004479a84 PrintStackTraceSignalHandler(void*) /home/streben/Documenti/llvm-project/llvm/lib/Support/Unix/Signals.inc:798:1
 #2 0x0000000004477286 llvm::sys::RunSignalHandlers() /home/streben/Documenti/llvm-project/llvm/lib/Support/Signals.cpp:105:20
 #3 0x0000000004479018 SignalHandler(int) /home/streben/Documenti/llvm-project/llvm/lib/Support/Unix/Signals.inc:413:1
 #4 0x00007f94de73dd00 __restore_rt (/lib64/libc.so.6+0x40d00)
 #5 0x00007f94de796664 __pthread_kill_implementation (/lib64/libc.so.6+0x99664)
 #6 0x00007f94de73dc4e gsignal (/lib64/libc.so.6+0x40c4e)
 #7 0x00007f94de725902 abort (/lib64/libc.so.6+0x28902)
 #8 0x00000000043ab122 llvm::report_fatal_error(llvm::Twine const&, bool) /home/streben/Documenti/llvm-project/llvm/lib/Support/ErrorHandling.cpp:125:9
 #9 0x00000000043aaf3b llvm::report_fatal_error(llvm::StringRef, bool) /home/streben/Documenti/llvm-project/llvm/lib/Support/ErrorHandling.cpp:86:68
#10 0x0000000003c7ec07 llvm::VerifierPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /home/streben/Documenti/llvm-project/llvm/lib/IR/Verifier.cpp:7162:33
#11 0x000000000091c73a llvm::detail::PassModel<llvm::Module, llvm::VerifierPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /home/streben/Documenti/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:90:3
#12 0x0000000003c08d13 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /home/streben/Documenti/llvm-project/llvm/include/llvm/IR/PassManager.h:547:20
#13 0x00000000008f8b01 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) /home/streben/Documenti/llvm-project/llvm/tools/opt/NewPMDriver.cpp:527:10
#14 0x0000000000922667 main /home/streben/Documenti/llvm-project/llvm/tools/opt/opt.cpp:739:27
#15 0x00007f94de727088 __libc_start_call_main (/lib64/libc.so.6+0x2a088)
#16 0x00007f94de72714b __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x2a14b)
#17 0x00000000008f5fe5 _start (/home/streben/Documenti/llvm-project/build/bin/opt+0x8f5fe5)

The original invoke with output going in %2 is the invoke that causes the verify step to fail when transformed in the invoke with output going in %5 of the EDDI output code.

The unwind label points to %VerificationBB2 instead of %7 and, for this, the basic block 7: is noted to have no predecessors. Also, the unwind destination label points to a basic block which doesn't handle the exception.

Note that this happens only if the 'noexcept' specifier is present and if 'myArray' has a non-default constructor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions