| ; 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: store ptr @tl, ptr @g3, align 8 |
| ; CHECK-NEXT: call void @b() |
| ; CHECK-NEXT: [[R:%.*]] = load ptr, ptr @g3, align 8 |
| ; CHECK-NEXT: ret ptr [[R]] |
| ; |
| store ptr @tl, 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 |
| } |