; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=globalopt -S < %s | FileCheck %s
@g1 = internal unnamed_addr global i32 0
@g2 = internal unnamed_addr global i32 0
@g3 = internal unnamed_addr global i32 0
@g4 = internal unnamed_addr global i32 0
@g5 = internal unnamed_addr global i32 0
@g6 = internal unnamed_addr global i32 0
@g7 = internal unnamed_addr global i32 0
@g8 = internal unnamed_addr global ptr null
@tl = internal thread_local unnamed_addr global i32 0
declare void @b()
define i1 @dom_const() {
; CHECK-LABEL: @dom_const(
; CHECK-NEXT: call void @b()
; CHECK-NEXT: ret i1 true
;
store i1 true, ptr @g1
call void @b()
%r = load i1, ptr @g1
ret i1 %r
}
define i32 @dom_arg(i32 %a) {
; CHECK-LABEL: @dom_arg(
; CHECK-NEXT: store i32 [[A:%.*]], ptr @g2, align 4
; CHECK-NEXT: call void @b()
; CHECK-NEXT: [[R:%.*]] = load i32, ptr @g2, align 4
; CHECK-NEXT: ret i32 [[R]]
;
store i32 %a, ptr @g2
call void @b()
%r = load i32, ptr @g2
ret i32 %r
}
define ptr @dom_thread_local_global() {
; CHECK-LABEL: @dom_thread_local_global(
; CHECK-NEXT: [[P:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @tl)
; CHECK-NEXT: store ptr [[P]], ptr @g3, align 8
; CHECK-NEXT: call void @b()
; CHECK-NEXT: [[R:%.*]] = load ptr, ptr @g3, align 8
; CHECK-NEXT: ret ptr [[R]]
;
%p = call ptr @llvm.threadlocal.address(ptr @tl)
store ptr %p, ptr @g3
call void @b()
%r = load ptr, ptr @g3
ret ptr %r
}
define i32 @dom_different_types() {
; CHECK-LABEL: @dom_different_types(
; CHECK-NEXT: store i1 true, ptr @g4, align 1
; CHECK-NEXT: call void @b()
; CHECK-NEXT: [[R:%.*]] = load i32, ptr @g4, align 4
; CHECK-NEXT: ret i32 [[R]]
;
store i1 true, ptr @g4
call void @b()
%r = load i32, ptr @g4
ret i32 %r
}
define i1 @no_dom(i1 %i) {
; CHECK-LABEL: @no_dom(
; CHECK-NEXT: br i1 [[I:%.*]], label [[BB1:%.*]], label [[END:%.*]]
; CHECK: bb1:
; CHECK-NEXT: store i1 true, ptr @g5, align 1
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: call void @b()
; CHECK-NEXT: [[R:%.*]] = load i1, ptr @g5, align 1
; CHECK-NEXT: ret i1 [[R]]
;
br i1 %i, label %bb1, label %end
bb1:
store i1 true, ptr @g5
br label %end
end:
call void @b()
%r = load i1, ptr @g5
ret i1 %r
}
define i1 @dom_multiple_function_loads() {
; CHECK-LABEL: @dom_multiple_function_loads(
; CHECK-NEXT: store i1 true, ptr @g6, align 1
; CHECK-NEXT: call void @b()
; CHECK-NEXT: ret i1 true
;
store i1 true, ptr @g6
call void @b()
%r = load i1, ptr @g6
ret i1 %r
}
define i1 @other() {
; CHECK-LABEL: @other(
; CHECK-NEXT: call void @b()
; CHECK-NEXT: [[R:%.*]] = load i1, ptr @g6, align 1
; CHECK-NEXT: ret i1 [[R]]
;
call void @b()
%r = load i1, ptr @g6
ret i1 %r
}
define i1 @dom_volatile() {
; CHECK-LABEL: @dom_volatile(
; CHECK-NEXT: store i1 true, ptr @g7, align 1
; CHECK-NEXT: call void @b()
; CHECK-NEXT: [[R:%.*]] = load volatile i1, ptr @g7, align 1
; CHECK-NEXT: ret i1 [[R]]
;
store i1 true, ptr @g7
call void @b()
%r = load volatile i1, ptr @g7
ret i1 %r
}
define i1 @dom_store_const_and_initializer() {
; CHECK-LABEL: @dom_store_const_and_initializer(
; CHECK-NEXT: store i1 true, ptr @g8, align 1
; CHECK-NEXT: store i1 false, ptr @g8, align 1
; CHECK-NEXT: call void @b()
; CHECK-NEXT: [[R:%.*]] = load i1, ptr @g8, align 1
; CHECK-NEXT: ret i1 [[R]]
;
store i1 true, ptr @g8
store i1 false, ptr @g8
call void @b()
%r = load i1, ptr @g8
ret i1 %r
}