; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 ; RUN: opt -S -passes=gvn < %s | FileCheck %s declare void @capture(ptr) declare void @some_call() define i32 @test_call_before_capture(ptr %p) { ; CHECK-LABEL: define i32 @test_call_before_capture( ; CHECK-SAME: ptr [[P:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 123, ptr [[A]], align 4 ; CHECK-NEXT: call void @some_call() ; CHECK-NEXT: call void @capture(ptr [[A]]) ; CHECK-NEXT: ret i32 123 ; %a = alloca i32 store i32 123, ptr %a call void @some_call() %v = load i32, ptr %a call void @capture(ptr %a) ret i32 %v } define i32 @test_call_after_capture(ptr %p) { ; CHECK-LABEL: define i32 @test_call_after_capture( ; CHECK-SAME: ptr [[P:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 123, ptr [[A]], align 4 ; CHECK-NEXT: call void @capture(ptr [[A]]) ; CHECK-NEXT: call void @some_call() ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; %a = alloca i32 store i32 123, ptr %a call void @capture(ptr %a) call void @some_call() %v = load i32, ptr %a ret i32 %v } define i32 @test_store_before_capture(ptr %p) { ; CHECK-LABEL: define i32 @test_store_before_capture( ; CHECK-SAME: ptr [[P:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 123, ptr [[A]], align 4 ; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P]], align 8 ; CHECK-NEXT: store i32 42, ptr [[P2]], align 4 ; CHECK-NEXT: call void @capture(ptr [[A]]) ; CHECK-NEXT: ret i32 123 ; %a = alloca i32 store i32 123, ptr %a %p2 = load ptr, ptr %p store i32 42, ptr %p2 %v = load i32, ptr %a call void @capture(ptr %a) ret i32 %v } define i32 @test_store_after_capture(ptr %p) { ; CHECK-LABEL: define i32 @test_store_after_capture( ; CHECK-SAME: ptr [[P:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 123, ptr [[A]], align 4 ; CHECK-NEXT: call void @capture(ptr [[A]]) ; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P]], align 8 ; CHECK-NEXT: store i32 42, ptr [[P2]], align 4 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; %a = alloca i32 store i32 123, ptr %a call void @capture(ptr %a) %p2 = load ptr, ptr %p store i32 42, ptr %p2 %v = load i32, ptr %a ret i32 %v } define i32 @test_capture_readonly() { ; CHECK-LABEL: define i32 @test_capture_readonly() { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 123, ptr [[A]], align 4 ; CHECK-NEXT: call void @capture(ptr readonly [[A]]) ; CHECK-NEXT: ret i32 123 ; %a = alloca i32 store i32 123, ptr %a call void @capture(ptr readonly %a) %v = load i32, ptr %a ret i32 %v } define i32 @test_capture_readonly_with_following_call() { ; CHECK-LABEL: define i32 @test_capture_readonly_with_following_call() { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 123, ptr [[A]], align 4 ; CHECK-NEXT: call void @capture(ptr readonly [[A]]) ; CHECK-NEXT: call void @some_call() ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 ; CHECK-NEXT: ret i32 [[V]] ; %a = alloca i32 store i32 123, ptr %a call void @capture(ptr readonly %a) call void @some_call() %v = load i32, ptr %a ret i32 %v } declare void @use(i32) define i32 @test_capture_readonly_in_loop() { ; CHECK-LABEL: define i32 @test_capture_readonly_in_loop() { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 123, ptr [[A]], align 4 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: call void @capture(ptr readonly [[A]]) ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 ; CHECK-NEXT: call void @use(i32 [[V]]) #[[ATTR0:[0-9]+]] ; CHECK-NEXT: br label [[LOOP]] ; %a = alloca i32 store i32 123, ptr %a br label %loop loop: call void @capture(ptr readonly %a) %v = load i32, ptr %a call void @use(i32 %v) memory(none) br label %loop } define i32 @test_splat_gep_capture(<1 x i32> %index) { ; CHECK-LABEL: define i32 @test_splat_gep_capture( ; CHECK-SAME: <1 x i32> [[INDEX:%.*]]) { ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 123, ptr [[A]], align 4 ; CHECK-NEXT: [[PTRS:%.*]] = getelementptr inbounds i32, ptr [[A]], <1 x i32> [[INDEX]] ; CHECK-NEXT: call void @some_call(<1 x ptr> [[PTRS]]) ; CHECK-NEXT: [[RELOAD:%.*]] = load i32, ptr [[A]], align 4 ; CHECK-NEXT: ret i32 [[RELOAD]] ; %a = alloca i32 store i32 123, ptr %a %ptrs = getelementptr inbounds i32, ptr %a, <1 x i32> %index call void @some_call(<1 x ptr> %ptrs) %reload = load i32, ptr %a ret i32 %reload }