1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 3 4declare ptr @foo0() 5declare ptr @foo(ptr %p, i64 %x) 6declare ptr @foo2(ptr %p, ptr %p2, i64 %x) 7declare void @side.effect() 8 9define ptr @test_sink_no_args_oneside(i1 %c) { 10; CHECK-LABEL: define {{[^@]+}}@test_sink_no_args_oneside 11; CHECK-SAME: (i1 [[C:%.*]]) { 12; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[END:%.*]] 13; CHECK: if: 14; CHECK-NEXT: call void @side.effect() 15; CHECK-NEXT: br label [[END]] 16; CHECK: end: 17; CHECK-NEXT: [[R2:%.*]] = call ptr @foo0() 18; CHECK-NEXT: ret ptr [[R2]] 19; 20 br i1 %c, label %if, label %else 21if: 22 call void @side.effect() 23 %r = call ptr @foo0() 24 br label %end 25 26else: 27 %r2 = call ptr @foo0() readonly 28 br label %end 29end: 30 %pr = phi ptr [ %r, %if], [%r2, %else] 31 ret ptr %pr 32} 33 34define ptr @test_sink_no_args_oneside_fail(i1 %c) { 35; CHECK-LABEL: define {{[^@]+}}@test_sink_no_args_oneside_fail 36; CHECK-SAME: (i1 [[C:%.*]]) { 37; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]] 38; CHECK: if: 39; CHECK-NEXT: call void @side.effect() 40; CHECK-NEXT: [[R:%.*]] = call ptr @foo0() 41; CHECK-NEXT: br label [[END:%.*]] 42; CHECK: else: 43; CHECK-NEXT: [[R2:%.*]] = call ptr @foo0() #[[ATTR0:[0-9]+]] 44; CHECK-NEXT: br label [[END]] 45; CHECK: end: 46; CHECK-NEXT: [[PR:%.*]] = phi ptr [ [[R]], [[IF]] ], [ [[R2]], [[ELSE]] ] 47; CHECK-NEXT: ret ptr [[PR]] 48; 49 br i1 %c, label %if, label %else 50if: 51 call void @side.effect() 52 %r = call ptr @foo0() 53 br label %end 54 55else: 56 %r2 = call ptr @foo0() readonly alwaysinline 57 br label %end 58end: 59 %pr = phi ptr [ %r, %if], [%r2, %else] 60 ret ptr %pr 61} 62 63define ptr @test_sink_int_attrs(i1 %c, ptr %p, ptr %p2, i64 %x) { 64; CHECK-LABEL: define {{[^@]+}}@test_sink_int_attrs 65; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P2:%.*]], i64 [[X:%.*]]) { 66; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[END:%.*]] 67; CHECK: if: 68; CHECK-NEXT: call void @side.effect() 69; CHECK-NEXT: br label [[END]] 70; CHECK: end: 71; CHECK-NEXT: [[R2:%.*]] = call ptr @foo2(ptr align 32 dereferenceable_or_null(100) [[P]], ptr align 32 dereferenceable(50) [[P2]], i64 range(i64 10, 100000) [[X]]) #[[ATTR1:[0-9]+]] 72; CHECK-NEXT: ret ptr [[R2]] 73; 74 br i1 %c, label %if, label %else 75if: 76 call void @side.effect() 77 %r = call ptr @foo2(ptr align 64 dereferenceable_or_null(100) %p, ptr dereferenceable(50) align 64 %p2, i64 range(i64 10, 1000) %x) memory(read) 78 br label %end 79 80else: 81 %r2 = call ptr @foo2(ptr align 32 dereferenceable_or_null(200) %p, ptr dereferenceable(100) align 32 %p2, i64 range(i64 10000, 100000) %x) memory(write) 82 br label %end 83end: 84 %pr = phi ptr [ %r, %if], [%r2, %else] 85 ret ptr %pr 86} 87 88define ptr @test_sink_int_attrs2(i1 %c, ptr %p, i64 %x) { 89; CHECK-LABEL: define {{[^@]+}}@test_sink_int_attrs2 90; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) { 91; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[END:%.*]] 92; CHECK: if: 93; CHECK-NEXT: call void @side.effect() 94; CHECK-NEXT: br label [[END]] 95; CHECK: end: 96; CHECK-NEXT: [[R2:%.*]] = call ptr @foo(ptr dereferenceable(50) [[P]], i64 range(i64 10, 1000) [[X]]) #[[ATTR2:[0-9]+]] 97; CHECK-NEXT: ret ptr [[R2]] 98; 99 br i1 %c, label %if, label %else 100if: 101 call void @side.effect() 102 %r = call ptr @foo(ptr dereferenceable(50) %p, i64 range(i64 10, 1000) %x) memory(read) 103 br label %end 104 105else: 106 %r2 = call ptr @foo(ptr dereferenceable(100) align 32 dereferenceable_or_null(200) %p, i64 range(i64 11, 100) %x) memory(none) 107 br label %end 108end: 109 %pr = phi ptr [ %r, %if], [%r2, %else] 110 ret ptr %pr 111} 112 113define ptr @test_sink_bool_attrs2(i1 %c, ptr %p, i64 %x) { 114; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs2 115; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) { 116; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[END:%.*]] 117; CHECK: if: 118; CHECK-NEXT: call void @side.effect() 119; CHECK-NEXT: br label [[END]] 120; CHECK: end: 121; CHECK-NEXT: [[R2:%.*]] = call noundef ptr @foo(ptr nonnull [[P]], i64 noundef [[X]]) #[[ATTR3:[0-9]+]] 122; CHECK-NEXT: ret ptr [[R2]] 123; 124 br i1 %c, label %if, label %else 125if: 126 call void @side.effect() 127 %r = call noundef ptr @foo(ptr readnone nonnull noundef %p, i64 noundef %x) cold mustprogress nocallback nofree nosync willreturn 128 br label %end 129 130else: 131 %r2 = call noundef nonnull ptr @foo(ptr readonly nonnull %p, i64 noundef %x) mustprogress nocallback nofree willreturn 132 br label %end 133end: 134 %pr = phi ptr [ %r, %if], [%r2, %else] 135 ret ptr %pr 136} 137 138define ptr @test_sink_bool_attrs3(i1 %c, ptr %p, i64 %x) { 139; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs3 140; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) { 141; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[END:%.*]] 142; CHECK: if: 143; CHECK-NEXT: call void @side.effect() 144; CHECK-NEXT: br label [[END]] 145; CHECK: end: 146; CHECK-NEXT: [[R2:%.*]] = call nonnull ptr @foo(ptr [[P]], i64 noundef [[X]]) #[[ATTR4:[0-9]+]] 147; CHECK-NEXT: ret ptr [[R2]] 148; 149 br i1 %c, label %if, label %else 150if: 151 call void @side.effect() 152 %r = call nonnull ptr @foo(ptr readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn alwaysinline 153 br label %end 154 155else: 156 %r2 = call noundef nonnull ptr @foo(ptr writeonly nonnull %p, i64 noundef %x) nosync willreturn alwaysinline 157 br label %end 158end: 159 %pr = phi ptr [ %r, %if], [%r2, %else] 160 ret ptr %pr 161} 162 163define ptr @test_sink_bool_attrs_fail_non_droppable(i1 %c, ptr %p, i64 %x) { 164; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs_fail_non_droppable 165; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) { 166; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]] 167; CHECK: if: 168; CHECK-NEXT: call void @side.effect() 169; CHECK-NEXT: [[R:%.*]] = call nonnull ptr @foo(ptr noundef readonly [[P]], i64 noundef [[X]]) #[[ATTR5:[0-9]+]] 170; CHECK-NEXT: br label [[END:%.*]] 171; CHECK: else: 172; CHECK-NEXT: [[R2:%.*]] = call noundef nonnull ptr @foo(ptr nonnull writeonly [[P]], i64 noundef [[X]]) #[[ATTR6:[0-9]+]] 173; CHECK-NEXT: br label [[END]] 174; CHECK: end: 175; CHECK-NEXT: [[PR:%.*]] = phi ptr [ [[R]], [[IF]] ], [ [[R2]], [[ELSE]] ] 176; CHECK-NEXT: ret ptr [[PR]] 177; 178 br i1 %c, label %if, label %else 179if: 180 call void @side.effect() 181 %r = call nonnull ptr @foo(ptr readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn alwaysinline 182 br label %end 183 184else: 185 %r2 = call noundef nonnull ptr @foo(ptr writeonly nonnull %p, i64 noundef %x) nosync willreturn 186 br label %end 187end: 188 %pr = phi ptr [ %r, %if], [%r2, %else] 189 ret ptr %pr 190} 191 192define ptr @test_sink_bool_attrs_fail_non_droppable2(i1 %c, ptr %p, i64 %x) { 193; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs_fail_non_droppable2 194; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) { 195; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]] 196; CHECK: if: 197; CHECK-NEXT: call void @side.effect() 198; CHECK-NEXT: [[R:%.*]] = call nonnull ptr @foo(ptr noundef readonly [[P]], i64 noundef [[X]]) #[[ATTR7:[0-9]+]] 199; CHECK-NEXT: br label [[END:%.*]] 200; CHECK: else: 201; CHECK-NEXT: [[R2:%.*]] = call noundef nonnull ptr @foo(ptr nonnull writeonly byval(i64) [[P]], i64 noundef [[X]]) #[[ATTR6]] 202; CHECK-NEXT: br label [[END]] 203; CHECK: end: 204; CHECK-NEXT: [[PR:%.*]] = phi ptr [ [[R]], [[IF]] ], [ [[R2]], [[ELSE]] ] 205; CHECK-NEXT: ret ptr [[PR]] 206; 207 br i1 %c, label %if, label %else 208if: 209 call void @side.effect() 210 %r = call nonnull ptr @foo(ptr readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn 211 br label %end 212 213else: 214 %r2 = call noundef nonnull ptr @foo(ptr byval(i64) writeonly nonnull %p, i64 noundef %x) nosync willreturn 215 br label %end 216end: 217 %pr = phi ptr [ %r, %if], [%r2, %else] 218 ret ptr %pr 219} 220 221define ptr @test_sink_bool_attrs_fail_non_droppable3(i1 %c, ptr %p, i64 %x) { 222; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs_fail_non_droppable3 223; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) { 224; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]] 225; CHECK: if: 226; CHECK-NEXT: call void @side.effect() 227; CHECK-NEXT: [[R:%.*]] = call nonnull ptr @foo(ptr noundef readonly byval(i32) [[P]], i64 noundef [[X]]) #[[ATTR7]] 228; CHECK-NEXT: br label [[END:%.*]] 229; CHECK: else: 230; CHECK-NEXT: [[R2:%.*]] = call noundef nonnull ptr @foo(ptr nonnull writeonly byval(i64) [[P]], i64 noundef [[X]]) #[[ATTR8:[0-9]+]] 231; CHECK-NEXT: br label [[END]] 232; CHECK: end: 233; CHECK-NEXT: [[PR:%.*]] = phi ptr [ [[R]], [[IF]] ], [ [[R2]], [[ELSE]] ] 234; CHECK-NEXT: ret ptr [[PR]] 235; 236 br i1 %c, label %if, label %else 237if: 238 call void @side.effect() 239 %r = call nonnull ptr @foo(ptr byval(i32) readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn 240 br label %end 241 242else: 243 %r2 = call noundef nonnull ptr @foo(ptr byval(i64) writeonly nonnull %p, i64 noundef %x) nosync 244 br label %end 245end: 246 %pr = phi ptr [ %r, %if], [%r2, %else] 247 ret ptr %pr 248} 249 250define ptr @test_sink_bool_attrs4(i1 %c, ptr %p, i64 %x) { 251; CHECK-LABEL: define {{[^@]+}}@test_sink_bool_attrs4 252; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]], i64 [[X:%.*]]) { 253; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[END:%.*]] 254; CHECK: if: 255; CHECK-NEXT: call void @side.effect() 256; CHECK-NEXT: br label [[END]] 257; CHECK: end: 258; CHECK-NEXT: [[R2:%.*]] = call nonnull ptr @foo(ptr byval(i64) [[P]], i64 noundef [[X]]) #[[ATTR8]] 259; CHECK-NEXT: ret ptr [[R2]] 260; 261 br i1 %c, label %if, label %else 262if: 263 call void @side.effect() 264 %r = call nonnull ptr @foo(ptr byval(i64) readonly noundef %p, i64 noundef %x) cold nocallback nofree nosync willreturn 265 br label %end 266 267else: 268 %r2 = call noundef nonnull ptr @foo(ptr byval(i64) writeonly nonnull %p, i64 noundef %x) nosync 269 br label %end 270end: 271 %pr = phi ptr [ %r, %if], [%r2, %else] 272 ret ptr %pr 273} 274 275;. 276; CHECK: attributes #[[ATTR0]] = { alwaysinline memory(read) } 277; CHECK: attributes #[[ATTR1]] = { memory(readwrite) } 278; CHECK: attributes #[[ATTR2]] = { memory(read) } 279; CHECK: attributes #[[ATTR3]] = { mustprogress nocallback nofree willreturn } 280; CHECK: attributes #[[ATTR4]] = { alwaysinline nosync willreturn } 281; CHECK: attributes #[[ATTR5]] = { alwaysinline cold nocallback nofree nosync willreturn } 282; CHECK: attributes #[[ATTR6]] = { nosync willreturn } 283; CHECK: attributes #[[ATTR7]] = { cold nocallback nofree nosync willreturn } 284; CHECK: attributes #[[ATTR8]] = { nosync } 285;. 286