1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature 2; RUN: opt -passes=inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s 3; RUN: opt -passes=inline -enable-noalias-to-md-conversion --enable-knowledge-retention -S < %s | FileCheck %s 4 5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 6target triple = "x86_64-unknown-linux-gnu" 7 8define void @hello(ptr noalias nocapture %a, ptr noalias nocapture readonly %c) #0 { 9; CHECK-LABEL: define {{[^@]+}}@hello 10; CHECK-SAME: (ptr noalias captures(none) [[A:%.*]], ptr noalias readonly captures(none) [[C:%.*]]) #[[ATTR0:[0-9]+]] { 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[C]], align 4 13; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 5 14; CHECK-NEXT: store float [[TMP0]], ptr [[ARRAYIDX]], align 4 15; CHECK-NEXT: ret void 16; 17entry: 18 %0 = load float, ptr %c, align 4 19 %arrayidx = getelementptr inbounds float, ptr %a, i64 5 20 store float %0, ptr %arrayidx, align 4 21 ret void 22} 23 24define void @foo(ptr noalias nocapture %a, ptr noalias nocapture readonly %c) #0 { 25; CHECK-LABEL: define {{[^@]+}}@foo 26; CHECK-SAME: (ptr noalias captures(none) [[A:%.*]], ptr noalias readonly captures(none) [[C:%.*]]) #[[ATTR0]] { 27; CHECK-NEXT: entry: 28; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) 29; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) 30; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[C]], align 4, !alias.scope [[META3]], !noalias [[META0]] 31; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, ptr [[A]], i64 5 32; CHECK-NEXT: store float [[TMP0]], ptr [[ARRAYIDX_I]], align 4, !alias.scope [[META0]], !noalias [[META3]] 33; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[C]], align 4 34; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 7 35; CHECK-NEXT: store float [[TMP1]], ptr [[ARRAYIDX]], align 4 36; CHECK-NEXT: ret void 37; 38entry: 39 tail call void @hello(ptr %a, ptr %c) 40 %0 = load float, ptr %c, align 4 41 %arrayidx = getelementptr inbounds float, ptr %a, i64 7 42 store float %0, ptr %arrayidx, align 4 43 ret void 44} 45 46define void @hello2(ptr noalias nocapture %a, ptr noalias nocapture %b, ptr nocapture readonly %c) #0 { 47; CHECK-LABEL: define {{[^@]+}}@hello2 48; CHECK-SAME: (ptr noalias captures(none) [[A:%.*]], ptr noalias captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]]) #[[ATTR0]] { 49; CHECK-NEXT: entry: 50; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[C]], align 4 51; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 6 52; CHECK-NEXT: store float [[TMP0]], ptr [[ARRAYIDX]], align 4 53; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, ptr [[B]], i64 8 54; CHECK-NEXT: store float [[TMP0]], ptr [[ARRAYIDX1]], align 4 55; CHECK-NEXT: ret void 56; 57entry: 58 %0 = load float, ptr %c, align 4 59 %arrayidx = getelementptr inbounds float, ptr %a, i64 6 60 store float %0, ptr %arrayidx, align 4 61 %arrayidx1 = getelementptr inbounds float, ptr %b, i64 8 62 store float %0, ptr %arrayidx1, align 4 63 ret void 64} 65 66; Check that when hello() is inlined into foo(), and then foo() is inlined into 67; foo2(), the noalias scopes are properly concatenated. 68define void @foo2(ptr nocapture %a, ptr nocapture %b, ptr nocapture readonly %c) #0 { 69; CHECK-LABEL: define {{[^@]+}}@foo2 70; CHECK-SAME: (ptr captures(none) [[A:%.*]], ptr captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]]) #[[ATTR0]] { 71; CHECK-NEXT: entry: 72; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) 73; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) 74; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) 75; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) 76; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[C]], align 4, !alias.scope [[META15:![0-9]+]], !noalias [[META16:![0-9]+]] 77; CHECK-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, ptr [[A]], i64 5 78; CHECK-NEXT: store float [[TMP0]], ptr [[ARRAYIDX_I_I]], align 4, !alias.scope [[META16]], !noalias [[META15]] 79; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[C]], align 4, !alias.scope [[META8]], !noalias [[META5]] 80; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, ptr [[A]], i64 7 81; CHECK-NEXT: store float [[TMP1]], ptr [[ARRAYIDX_I]], align 4, !alias.scope [[META5]], !noalias [[META8]] 82; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) 83; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) 84; CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[C]], align 4, !noalias [[META22:![0-9]+]] 85; CHECK-NEXT: [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, ptr [[A]], i64 6 86; CHECK-NEXT: store float [[TMP2]], ptr [[ARRAYIDX_I1]], align 4, !alias.scope [[META17]], !noalias [[META20]] 87; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, ptr [[B]], i64 8 88; CHECK-NEXT: store float [[TMP2]], ptr [[ARRAYIDX1_I]], align 4, !alias.scope [[META20]], !noalias [[META17]] 89; CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[C]], align 4 90; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 7 91; CHECK-NEXT: store float [[TMP3]], ptr [[ARRAYIDX]], align 4 92; CHECK-NEXT: ret void 93; 94entry: 95 tail call void @foo(ptr %a, ptr %c) 96 tail call void @hello2(ptr %a, ptr %b, ptr %c) 97 %0 = load float, ptr %c, align 4 98 %arrayidx = getelementptr inbounds float, ptr %a, i64 7 99 store float %0, ptr %arrayidx, align 4 100 ret void 101} 102 103; CHECK: !0 = !{!1} 104; CHECK: !1 = distinct !{!1, !2, !"hello: %a"} 105; CHECK: !2 = distinct !{!2, !"hello"} 106; CHECK: !3 = !{!4} 107; CHECK: !4 = distinct !{!4, !2, !"hello: %c"} 108; CHECK: !5 = !{!6} 109; CHECK: !6 = distinct !{!6, !7, !"foo: %a"} 110; CHECK: !7 = distinct !{!7, !"foo"} 111; CHECK: !8 = !{!9} 112; CHECK: !9 = distinct !{!9, !7, !"foo: %c"} 113; CHECK: !10 = !{!11} 114; CHECK: !11 = distinct !{!11, !12, !"hello: %a"} 115; CHECK: !12 = distinct !{!12, !"hello"} 116; CHECK: !13 = !{!14} 117; CHECK: !14 = distinct !{!14, !12, !"hello: %c"} 118; CHECK: !15 = !{!14, !9} 119; CHECK: !16 = !{!11, !6} 120; CHECK: !17 = !{!18} 121; CHECK: !18 = distinct !{!18, !19, !"hello2: %a"} 122; CHECK: !19 = distinct !{!19, !"hello2"} 123; CHECK: !20 = !{!21} 124; CHECK: !21 = distinct !{!21, !19, !"hello2: %b"} 125; CHECK: !22 = !{!18, !21} 126 127attributes #0 = { nounwind uwtable } 128 129