diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index e7951b3a3f4d8..8fd876825b7ea 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -3507,7 +3507,9 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { return nullptr; // These aren't actually possible for non-coerced returns, and we // only care about non-coerced returns on this code path. - assert(!SI->isAtomic() && !SI->isVolatile()); + // All memory instructions inside __try block are volatile. + assert(!SI->isAtomic() && + (!SI->isVolatile() || CGF.currentFunctionUsesSEHTry())); return SI; }; // If there are multiple uses of the return-value slot, just check diff --git a/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp b/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp index fab567e763df4..ce2a9528e1908 100644 --- a/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp +++ b/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp @@ -67,3 +67,26 @@ void foo() } } } + +// CHECK-LABEL:@"?bar@@YAHXZ"() +// CHECK: invoke.cont: +// CHECK: invoke void @llvm.seh.try.begin() +// CHECK: invoke.cont1: +// CHECK: store volatile i32 1, ptr %cleanup.dest.slot +// CHECK: invoke void @llvm.seh.try.end() +// CHECK: invoke.cont2: +// CHECK: call void @"?fin$0@0@bar@@" +// CHECK: %cleanup.dest3 = load i32, ptr %cleanup.dest.slot +// CHECK: return: +// CHECK: ret i32 11 +int bar() +{ + int x; + __try { + return 11; + } __finally { + if (_abnormal_termination()) { + x = 9; + } + } +}