diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index d5cc8dc6608df..aad963582e3d5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -2413,6 +2413,12 @@ bool FastISel::tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst) { if (LI->isVolatile()) return false; + // Swifterror loads are not actually loads. + if (auto AI = dyn_cast(LI->getPointerOperand())) { + if (AI->isSwiftError()) + return false; + } + // Figure out which vreg this is going into. If there is no assigned vreg yet // then there actually was no reference to it. Perhaps the load is referenced // by a dead instruction. diff --git a/llvm/test/CodeGen/X86/swifterror-O0.ll b/llvm/test/CodeGen/X86/swifterror-O0.ll new file mode 100644 index 0000000000000..5dd1bbd0572be --- /dev/null +++ b/llvm/test/CodeGen/X86/swifterror-O0.ll @@ -0,0 +1,20 @@ +; RUN: llc -mtriple=x86_64-apple-darwin -O0 %s -o - | FileCheck %s + +define i32 @foo() { +; CHECK-LABEL: foo: +; CHECK: cmpq $0, %r12 + + %swifterror = alloca swifterror i8* + call void @callee(i8** swifterror %swifterror) + %err = load i8*, i8** %swifterror + %tst = icmp ne i8* %err, null + br i1 %tst, label %true, label %false + +true: + ret i32 0 + +false: + ret i32 1 +} + +declare void @callee(i8** swifterror)