84 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 62; RUN: opt -passes=gvn -S < %s | FileCheck %s3 4%struct.t = type { ptr }5 6; The loaded address and the location of the address itself are not aliased,7; so the second reload is not necessary. Check that it can be eliminated.8define void @test1(ptr nocapture readonly %p, i32 %v) #0 {9; CHECK-LABEL: define void @test1(10; CHECK-SAME: ptr readonly captures(none) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR0:[0-9]+]] {11; CHECK-NEXT: [[ENTRY:.*:]]12; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 4, !tbaa [[ANYPTR_TBAA0:![0-9]+]]13; CHECK-NEXT: store volatile i32 [[V]], ptr [[TMP0]], align 4, !tbaa [[INT_TBAA5:![0-9]+]]14; CHECK-NEXT: store volatile i32 [[V]], ptr [[TMP0]], align 4, !tbaa [[INT_TBAA5]]15; CHECK-NEXT: ret void16;17entry:18 %0 = load ptr, ptr %p, align 4, !tbaa !119 store volatile i32 %v, ptr %0, align 4, !tbaa !620 %1 = load ptr, ptr %p, align 4, !tbaa !121 store volatile i32 %v, ptr %1, align 4, !tbaa !622 ret void23}24 25; The store via the loaded address may overwrite the address itself.26; Make sure that both loads remain.27define void @test2(ptr nocapture readonly %p, i32 %v) #0 {28; CHECK-LABEL: define void @test2(29; CHECK-SAME: ptr readonly captures(none) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR0]] {30; CHECK-NEXT: [[ENTRY:.*:]]31; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 4, !tbaa [[ANYPTR_TBAA0]]32; CHECK-NEXT: store volatile i32 [[V]], ptr [[TMP0]], align 4, !tbaa [[ANYPTR_TBAA0]]33; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[P]], align 4, !tbaa [[ANYPTR_TBAA0]]34; CHECK-NEXT: store volatile i32 [[V]], ptr [[TMP1]], align 4, !tbaa [[ANYPTR_TBAA0]]35; CHECK-NEXT: ret void36;37entry:38 %0 = load ptr, ptr %p, align 4, !tbaa !139 store volatile i32 %v, ptr %0, align 4, !tbaa !140 %1 = load ptr, ptr %p, align 4, !tbaa !141 store volatile i32 %v, ptr %1, align 4, !tbaa !142 ret void43}44 45; The loads are ordered and non-monotonic. Although they are not aliased to46; the stores, make sure both are preserved.47define void @test3(ptr nocapture readonly %p, i32 %v) #0 {48; CHECK-LABEL: define void @test3(49; CHECK-SAME: ptr readonly captures(none) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR0]] {50; CHECK-NEXT: [[ENTRY:.*:]]51; CHECK-NEXT: [[TMP0:%.*]] = load atomic ptr, ptr [[P]] acquire, align 4, !tbaa [[ANYPTR_TBAA0]]52; CHECK-NEXT: store volatile i32 [[V]], ptr [[TMP0]], align 4, !tbaa [[INT_TBAA5]]53; CHECK-NEXT: [[TMP1:%.*]] = load atomic ptr, ptr [[P]] acquire, align 4, !tbaa [[ANYPTR_TBAA0]]54; CHECK-NEXT: store volatile i32 [[V]], ptr [[TMP1]], align 4, !tbaa [[INT_TBAA5]]55; CHECK-NEXT: ret void56;57entry:58 %0 = load atomic ptr, ptr %p acquire, align 4, !tbaa !159 store volatile i32 %v, ptr %0, align 4, !tbaa !660 %1 = load atomic ptr, ptr %p acquire, align 4, !tbaa !161 store volatile i32 %v, ptr %1, align 4, !tbaa !662 ret void63}64 65attributes #0 = { norecurse nounwind }66 67!1 = !{!2, !3, i64 0}68!2 = !{!"", !3, i64 0}69!3 = !{!"any pointer", !4, i64 0}70!4 = !{!"omnipotent char", !5, i64 0}71!5 = !{!"Simple C/C++ TBAA"}72!6 = !{!7, !7, i64 0}73!7 = !{!"int", !4, i64 0}74 75;.76; CHECK: [[ANYPTR_TBAA0]] = !{[[META1:![0-9]+]], [[META2:![0-9]+]], i64 0}77; CHECK: [[META1]] = !{!"", [[META2]], i64 0}78; CHECK: [[META2]] = !{!"any pointer", [[META3:![0-9]+]], i64 0}79; CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}80; CHECK: [[META4]] = !{!"Simple C/C++ TBAA"}81; CHECK: [[INT_TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0}82; CHECK: [[META6]] = !{!"int", [[META3]], i64 0}83;.84