1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes 2; FIXME: Add -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations below. 3; This flag was removed because max iterations is 2 in most cases, but in windows it is 1. 4; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s 5; ModuleID = 'callback_simple.c' 6target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 7 8; Test 0 9; 10; Make sure we propagate information from the caller to the callback callee but 11; only for arguments that are mapped through the callback metadata. Here, the 12; first two arguments of the call and the callback callee do not correspond to 13; each other but argument 3-5 of the transitive call site in the caller match 14; arguments 2-4 of the callback callee. Here we should see information and value 15; transfer in both directions. 16 17define void @t0_caller(i32* %a) { 18; CHECK-LABEL: define {{[^@]+}}@t0_caller 19; CHECK-SAME: (i32* align 256 [[A:%.*]]) 20; CHECK-NEXT: entry: 21; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32 22; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64 23; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128 24; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* 25; CHECK-NEXT: store i32 42, i32* [[B]], align 32 26; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64 27; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) 28; CHECK-NEXT: ret void 29; 30 31entry: 32 %b = alloca i32, align 32 33 %c = alloca i32*, align 64 34 %ptr = alloca i32, align 128 35 %0 = bitcast i32* %b to i8* 36 store i32 42, i32* %b, align 4 37 store i32* %b, i32** %c, align 8 38 call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c) 39 ret void 40} 41 42; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below! 43; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call. 44define internal void @t0_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { 45; CHECK-LABEL: define {{[^@]+}}@t0_callback_callee 46; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) 47; CHECK-NEXT: entry: 48; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 49; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 50; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 51; CHECK-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]]) 52; CHECK-NEXT: ret void 53; 54entry: 55 %ptr_val = load i32, i32* %ptr, align 8 56 store i32 %ptr_val, i32* %is_not_null 57 %0 = load i32*, i32** %c, align 8 58 tail call void @t0_check(i32* %a, i64 %b, i32* %0) 59 ret void 60} 61 62declare void @t0_check(i32* align 256, i64, i32*) 63 64declare !callback !0 void @t0_callback_broker(i32*, i32*, void (i32*, i32*, ...)*, ...) 65 66; Test 1 67; 68; Similar to test 0 but with some additional annotations (noalias/nocapute) to make sure 69; we deduce and propagate noalias and others properly. 70 71define void @t1_caller(i32* noalias %a) { 72; CHECK-LABEL: define {{[^@]+}}@t1_caller 73; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) 74; CHECK-NEXT: entry: 75; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32 76; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64 77; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128 78; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* 79; CHECK-NEXT: store i32 42, i32* [[B]], align 32 80; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64 81; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) 82; CHECK-NEXT: ret void 83; 84entry: 85 %b = alloca i32, align 32 86 %c = alloca i32*, align 64 87 %ptr = alloca i32, align 128 88 %0 = bitcast i32* %b to i8* 89 store i32 42, i32* %b, align 4 90 store i32* %b, i32** %c, align 8 91 call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c) 92 ret void 93} 94 95; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below! 96; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call. 97define internal void @t1_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { 98; CHECK-LABEL: define {{[^@]+}}@t1_callback_callee 99; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* noalias nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) 100; CHECK-NEXT: entry: 101; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 102; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 103; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 104; CHECK-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) 105; CHECK-NEXT: ret void 106; 107entry: 108 %ptr_val = load i32, i32* %ptr, align 8 109 store i32 %ptr_val, i32* %is_not_null 110 %0 = load i32*, i32** %c, align 8 111 tail call void @t1_check(i32* %a, i64 %b, i32* %0) 112 ret void 113} 114 115declare void @t1_check(i32* nocapture align 256, i64, i32* nocapture) nosync 116 117declare !callback !0 void @t1_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...) 118 119; Test 2 120; 121; Similar to test 1 but checking that the noalias is only placed if potential synchronization through @t2_check is preserved. 122 123define void @t2_caller(i32* noalias %a) { 124; CHECK-LABEL: define {{[^@]+}}@t2_caller 125; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) 126; CHECK-NEXT: entry: 127; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32 128; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64 129; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128 130; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* 131; CHECK-NEXT: store i32 42, i32* [[B]], align 32 132; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64 133; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) 134; CHECK-NEXT: ret void 135; 136entry: 137 %b = alloca i32, align 32 138 %c = alloca i32*, align 64 139 %ptr = alloca i32, align 128 140 %0 = bitcast i32* %b to i8* 141 store i32 42, i32* %b, align 4 142 store i32* %b, i32** %c, align 8 143 call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c) 144 ret void 145} 146 147; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below! 148; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call. 149; 150; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls. 151define internal void @t2_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { 152; CHECK-LABEL: define {{[^@]+}}@t2_callback_callee 153; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) 154; CHECK-NEXT: entry: 155; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 156; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 157; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 158; CHECK-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) 159; CHECK-NEXT: ret void 160; 161entry: 162 %ptr_val = load i32, i32* %ptr, align 8 163 store i32 %ptr_val, i32* %is_not_null 164 %0 = load i32*, i32** %c, align 8 165 tail call void @t2_check(i32* %a, i64 %b, i32* %0) 166 ret void 167} 168 169declare void @t2_check(i32* nocapture align 256, i64, i32* nocapture) 170 171declare !callback !0 void @t2_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...) 172 173; Test 3 174; 175; Basically test 2 with the casted callback callee used twice. 176 177define void @t3_caller(i32* noalias %a) { 178; CHECK-LABEL: define {{[^@]+}}@t3_caller 179; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) 180; CHECK-NEXT: entry: 181; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32 182; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64 183; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128 184; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* 185; CHECK-NEXT: store i32 42, i32* [[B]], align 32 186; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64 187; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) 188; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) 189; CHECK-NEXT: ret void 190; 191entry: 192 %b = alloca i32, align 32 193 %c = alloca i32*, align 64 194 %ptr = alloca i32, align 128 195 %0 = bitcast i32* %b to i8* 196 store i32 42, i32* %b, align 4 197 store i32* %b, i32** %c, align 8 198 call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c) 199 call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c) 200 ret void 201} 202 203; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below! 204; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call. 205; 206; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls. 207define internal void @t3_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { 208; CHECK-LABEL: define {{[^@]+}}@t3_callback_callee 209; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) 210; CHECK-NEXT: entry: 211; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 212; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 213; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 214; CHECK-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]]) 215; CHECK-NEXT: ret void 216; 217entry: 218 %ptr_val = load i32, i32* %ptr, align 8 219 store i32 %ptr_val, i32* %is_not_null 220 %0 = load i32*, i32** %c, align 8 221 tail call void @t3_check(i32* %a, i64 %b, i32* %0) 222 ret void 223} 224 225declare void @t3_check(i32* nocapture align 256, i64, i32* nocapture) 226 227declare !callback !0 void @t3_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...) 228 229!0 = !{!1} 230!1 = !{i64 2, i64 -1, i64 -1, i1 true} 231