See discussion in D87149. Dropping volatile stores here is legal per LLVM semantics, but causes issues for real code and may result in a change to LLVM volatile semantics. Temporarily treat volatile stores as "not guaranteed to transfer execution" in just this place, until this issue has been resolved.
42 lines
1.0 KiB
LLVM
42 lines
1.0 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
@x = weak global i32 0
|
|
|
|
define void @self_assign_1() {
|
|
; CHECK-LABEL: @self_assign_1(
|
|
; 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: return:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%tmp = load volatile i32, i32* @x
|
|
store volatile i32 %tmp, i32* @x
|
|
br label %return
|
|
|
|
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
|
|
}
|