Instruction *Prev = I.getPrevNonDebugInstruction();
if (Prev && !Prev->isEHPad() &&
isGuaranteedToTransferExecutionToSuccessor(Prev)) {
+ // Temporarily disable removal of volatile stores preceding unreachable,
+ // pending a potential LangRef change permitting volatile stores to trap.
+ // TODO: Either remove this code, or properly integrate the check into
+ // isGuaranteedToTransferExecutionToSuccessor().
+ if (auto *SI = dyn_cast<StoreInst>(Prev))
+ if (SI->isVolatile())
+ return nullptr;
+
eraseInstFromFunction(*Prev);
return &I;
}
-; NOTE: Assertions have been autogenerated by update_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
@x = weak global i32 0
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP:%.*]] = load volatile i32, i32* @x, align 4
; CHECK-NEXT: store volatile i32 [[TMP]], i32* @x, align 4
-; CHECK-NEXT: br label %return
+; CHECK-NEXT: br label [[RETURN:%.*]]
; CHECK: return:
; CHECK-NEXT: ret void
;
return:
ret void
}
+
+define void @volatile_store_before_unreachable(i1 %c, i8* %p) {
+; CHECK-LABEL: @volatile_store_before_unreachable(
+; CHECK-NEXT: br i1 [[C:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
+; CHECK: true:
+; CHECK-NEXT: store volatile i8 0, i8* [[P:%.*]], align 1
+; CHECK-NEXT: unreachable
+; CHECK: false:
+; CHECK-NEXT: ret void
+;
+ br i1 %c, label %true, label %false
+
+true:
+ store volatile i8 0, i8* %p
+ unreachable
+
+false:
+ ret void
+}