158 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4 5declare void @unknown()6 7declare void @bar(ptr)8 9define void @foo() {10; CHECK-LABEL: define {{[^@]+}}@foo() {11; CHECK-NEXT: [[X:%.*]] = alloca i32, align 412; CHECK-NEXT: call void @unknown()13; CHECK-NEXT: call void @bar(ptr noundef nonnull align 4 dereferenceable(4) [[X]])14; CHECK-NEXT: ret void15;16 %x = alloca i3217 call void @unknown()18 call void @bar(ptr %x)19 ret void20}21 22define internal ptr @returned_dead() {23; CHECK-LABEL: define {{[^@]+}}@returned_dead() {24; CHECK-NEXT: call void @unknown()25; CHECK-NEXT: ret ptr undef26;27 call void @unknown()28 ret ptr null29}30 31define void @caller1() {32; CHECK-LABEL: define {{[^@]+}}@caller1() {33; CHECK-NEXT: [[TMP1:%.*]] = call ptr @returned_dead()34; CHECK-NEXT: ret void35;36 call ptr @returned_dead()37 ret void38}39 40define internal void @argument_dead_callback_callee(ptr %c) {41; CHECK-LABEL: define {{[^@]+}}@argument_dead_callback_callee42; CHECK-SAME: (ptr noalias nofree readnone align 4294967296 captures(none) [[C:%.*]]) {43; CHECK-NEXT: call void @unknown()44; CHECK-NEXT: ret void45;46 call void @unknown()47 ret void48}49 50define void @callback_caller() {51; TUNIT-LABEL: define {{[^@]+}}@callback_caller() {52; TUNIT-NEXT: call void @callback_broker(ptr noundef nonnull @argument_dead_callback_callee, ptr nofree readnone undef)53; TUNIT-NEXT: ret void54;55; CGSCC-LABEL: define {{[^@]+}}@callback_caller() {56; CGSCC-NEXT: call void @callback_broker(ptr noundef nonnull @argument_dead_callback_callee, ptr nofree noundef readnone null)57; CGSCC-NEXT: ret void58;59 call void @callback_broker(ptr @argument_dead_callback_callee, ptr null)60 ret void61}62 63; Drop the noundef if when we replace the call argument with `undef`. We use a64; varargs function as we cannot (yet) rewrite their signature. If we ever can,65; try to come up with a different scheme to verify the `noundef` is dropped if66; signature rewriting is not happening.67define internal void @callee_with_dead_noundef_arg(i1 noundef %create, ...) {68; TUNIT-LABEL: define {{[^@]+}}@callee_with_dead_noundef_arg69; TUNIT-SAME: (i1 [[CREATE:%.*]], ...) {70; TUNIT-NEXT: call void @unknown()71; TUNIT-NEXT: ret void72;73; CGSCC-LABEL: define {{[^@]+}}@callee_with_dead_noundef_arg74; CGSCC-SAME: (i1 noundef [[CREATE:%.*]], ...) {75; CGSCC-NEXT: call void @unknown()76; CGSCC-NEXT: ret void77;78 call void @unknown()79 ret void80}81 82define void @caller_with_unused_arg(i1 %c) {83; TUNIT-LABEL: define {{[^@]+}}@caller_with_unused_arg84; TUNIT-SAME: (i1 noundef [[C:%.*]]) {85; TUNIT-NEXT: call void (i1, ...) @callee_with_dead_noundef_arg(i1 undef)86; TUNIT-NEXT: ret void87;88; CGSCC-LABEL: define {{[^@]+}}@caller_with_unused_arg89; CGSCC-SAME: (i1 noundef [[C:%.*]]) {90; CGSCC-NEXT: call void (i1, ...) @callee_with_dead_noundef_arg(i1 noundef [[C]])91; CGSCC-NEXT: ret void92;93 call void (i1, ...) @callee_with_dead_noundef_arg(i1 %c)94 ret void95}96 97define internal void @callee_with_dead_arg(i1 %create, ...) {98;99; TUNIT-LABEL: define {{[^@]+}}@callee_with_dead_arg100; TUNIT-SAME: (i1 [[CREATE:%.*]], ...) {101; TUNIT-NEXT: entry:102; TUNIT-NEXT: br label [[IF_THEN3:%.*]]103; TUNIT: if.then:104; TUNIT-NEXT: unreachable105; TUNIT: if.then3:106; TUNIT-NEXT: call void @unknown()107; TUNIT-NEXT: ret void108;109; CGSCC-LABEL: define {{[^@]+}}@callee_with_dead_arg110; CGSCC-SAME: (i1 noundef [[CREATE:%.*]], ...) {111; CGSCC-NEXT: entry:112; CGSCC-NEXT: br label [[IF_THEN3:%.*]]113; CGSCC: if.then:114; CGSCC-NEXT: unreachable115; CGSCC: if.then3:116; CGSCC-NEXT: call void @unknown()117; CGSCC-NEXT: ret void118;119entry:120 br i1 %create, label %if.then3, label %if.then121 122if.then: ; preds = %entry123 ret void124 125if.then3: ; preds = %entry126 call void @unknown()127 ret void128}129 130; Drop the noundef if when we replace the call argument with `undef`. We use a131; varargs function as we cannot (yet) rewrite their signature. If we ever can,132; try to come up with a different scheme to verify the `noundef` is dropped if133; signature rewriting is not happening.134define void @caller_with_noundef_arg() {135;136; TUNIT-LABEL: define {{[^@]+}}@caller_with_noundef_arg() {137; TUNIT-NEXT: call void (i1, ...) @callee_with_dead_arg(i1 undef)138; TUNIT-NEXT: ret void139;140; CGSCC-LABEL: define {{[^@]+}}@caller_with_noundef_arg() {141; CGSCC-NEXT: call void (i1, ...) @callee_with_dead_arg(i1 noundef true)142; CGSCC-NEXT: ret void143;144 call void (i1, ...) @callee_with_dead_arg(i1 noundef true)145 ret void146}147 148declare !callback !0 void @callback_broker(ptr, ptr)149!1 = !{i64 0, i64 1, i1 false}150!0 = !{!1}151;.152; TUNIT: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}153; TUNIT: [[META1]] = !{i64 0, i64 1, i1 false}154;.155; CGSCC: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}156; CGSCC: [[META1]] = !{i64 0, i64 1, i1 false}157;.158