1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 2; RUN: opt -S -passes=gvn < %s | FileCheck %s 3 4declare void @capture(ptr) 5declare void @some_call() 6 7define i32 @test_call_before_capture(ptr %p) { 8; CHECK-LABEL: define i32 @test_call_before_capture( 9; CHECK-SAME: ptr [[P:%.*]]) { 10; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 11; CHECK-NEXT: store i32 123, ptr [[A]], align 4 12; CHECK-NEXT: call void @some_call() 13; CHECK-NEXT: call void @capture(ptr [[A]]) 14; CHECK-NEXT: ret i32 123 15; 16 %a = alloca i32 17 store i32 123, ptr %a 18 call void @some_call() 19 %v = load i32, ptr %a 20 call void @capture(ptr %a) 21 ret i32 %v 22} 23 24define i32 @test_call_after_capture(ptr %p) { 25; CHECK-LABEL: define i32 @test_call_after_capture( 26; CHECK-SAME: ptr [[P:%.*]]) { 27; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 28; CHECK-NEXT: store i32 123, ptr [[A]], align 4 29; CHECK-NEXT: call void @capture(ptr [[A]]) 30; CHECK-NEXT: call void @some_call() 31; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 32; CHECK-NEXT: ret i32 [[V]] 33; 34 %a = alloca i32 35 store i32 123, ptr %a 36 call void @capture(ptr %a) 37 call void @some_call() 38 %v = load i32, ptr %a 39 ret i32 %v 40} 41 42define i32 @test_store_before_capture(ptr %p) { 43; CHECK-LABEL: define i32 @test_store_before_capture( 44; CHECK-SAME: ptr [[P:%.*]]) { 45; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 46; CHECK-NEXT: store i32 123, ptr [[A]], align 4 47; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P]], align 8 48; CHECK-NEXT: store i32 42, ptr [[P2]], align 4 49; CHECK-NEXT: call void @capture(ptr [[A]]) 50; CHECK-NEXT: ret i32 123 51; 52 %a = alloca i32 53 store i32 123, ptr %a 54 %p2 = load ptr, ptr %p 55 store i32 42, ptr %p2 56 %v = load i32, ptr %a 57 call void @capture(ptr %a) 58 ret i32 %v 59} 60 61define i32 @test_store_after_capture(ptr %p) { 62; CHECK-LABEL: define i32 @test_store_after_capture( 63; CHECK-SAME: ptr [[P:%.*]]) { 64; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 65; CHECK-NEXT: store i32 123, ptr [[A]], align 4 66; CHECK-NEXT: call void @capture(ptr [[A]]) 67; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P]], align 8 68; CHECK-NEXT: store i32 42, ptr [[P2]], align 4 69; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 70; CHECK-NEXT: ret i32 [[V]] 71; 72 %a = alloca i32 73 store i32 123, ptr %a 74 call void @capture(ptr %a) 75 %p2 = load ptr, ptr %p 76 store i32 42, ptr %p2 77 %v = load i32, ptr %a 78 ret i32 %v 79} 80 81define i32 @test_capture_readonly() { 82; CHECK-LABEL: define i32 @test_capture_readonly() { 83; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 84; CHECK-NEXT: store i32 123, ptr [[A]], align 4 85; CHECK-NEXT: call void @capture(ptr readonly [[A]]) 86; CHECK-NEXT: ret i32 123 87; 88 %a = alloca i32 89 store i32 123, ptr %a 90 call void @capture(ptr readonly %a) 91 %v = load i32, ptr %a 92 ret i32 %v 93} 94 95define i32 @test_capture_readonly_with_following_call() { 96; CHECK-LABEL: define i32 @test_capture_readonly_with_following_call() { 97; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 98; CHECK-NEXT: store i32 123, ptr [[A]], align 4 99; CHECK-NEXT: call void @capture(ptr readonly [[A]]) 100; CHECK-NEXT: call void @some_call() 101; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 102; CHECK-NEXT: ret i32 [[V]] 103; 104 %a = alloca i32 105 store i32 123, ptr %a 106 call void @capture(ptr readonly %a) 107 call void @some_call() 108 %v = load i32, ptr %a 109 ret i32 %v 110} 111 112declare void @use(i32) 113 114define i32 @test_capture_readonly_in_loop() { 115; CHECK-LABEL: define i32 @test_capture_readonly_in_loop() { 116; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 117; CHECK-NEXT: store i32 123, ptr [[A]], align 4 118; CHECK-NEXT: br label [[LOOP:%.*]] 119; CHECK: loop: 120; CHECK-NEXT: call void @capture(ptr readonly [[A]]) 121; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 122; CHECK-NEXT: call void @use(i32 [[V]]) #[[ATTR0:[0-9]+]] 123; CHECK-NEXT: br label [[LOOP]] 124; 125 %a = alloca i32 126 store i32 123, ptr %a 127 br label %loop 128 129loop: 130 call void @capture(ptr readonly %a) 131 %v = load i32, ptr %a 132 call void @use(i32 %v) memory(none) 133 br label %loop 134} 135 136define i32 @test_splat_gep_capture(<1 x i32> %index) { 137; CHECK-LABEL: define i32 @test_splat_gep_capture( 138; CHECK-SAME: <1 x i32> [[INDEX:%.*]]) { 139; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 140; CHECK-NEXT: store i32 123, ptr [[A]], align 4 141; CHECK-NEXT: [[PTRS:%.*]] = getelementptr inbounds i32, ptr [[A]], <1 x i32> [[INDEX]] 142; CHECK-NEXT: call void @some_call(<1 x ptr> [[PTRS]]) 143; CHECK-NEXT: [[RELOAD:%.*]] = load i32, ptr [[A]], align 4 144; CHECK-NEXT: ret i32 [[RELOAD]] 145; 146 %a = alloca i32 147 store i32 123, ptr %a 148 %ptrs = getelementptr inbounds i32, ptr %a, <1 x i32> %index 149 call void @some_call(<1 x ptr> %ptrs) 150 %reload = load i32, ptr %a 151 ret i32 %reload 152} 153