1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC 4 5; The original C source looked like this: 6; 7; long long a101, b101, e101; 8; volatile long c101; 9; int d101; 10; 11; static inline int bar(p1, p2) 12; { 13; return 0; 14; } 15; 16; void foo(unsigned p1) 17; { 18; long long *f = &b101, *g = &e101; 19; c101 = 0; 20; (void)((*f |= a101) - (*g = bar(d101))); 21; c101 = (*f |= a101 &= p1) == d101; 22; } 23; 24; When compiled with Clang it gives a warning 25; warning: too few arguments in call to 'bar' 26; 27; This ll reproducer has been reduced to only include tha call. 28; 29; Note that -lint will report this as UB, but it passes -verify. 30 31; This test is just to verify that we do not crash/assert due to mismatch in 32; argument count between the caller and callee. 33 34; FIXME we should recognize this as UB and make it an unreachable. 35 36define dso_local i16 @foo(i16 %a) { 37; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 38; TUNIT-LABEL: define {{[^@]+}}@foo 39; TUNIT-SAME: (i16 [[A:%.*]]) #[[ATTR0:[0-9]+]] { 40; TUNIT-NEXT: ret i16 0 41; 42; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 43; CGSCC-LABEL: define {{[^@]+}}@foo 44; CGSCC-SAME: (i16 [[A:%.*]]) #[[ATTR0:[0-9]+]] { 45; CGSCC-NEXT: [[CALL:%.*]] = call noundef i16 @bar(i16 [[A]]) #[[ATTR2:[0-9]+]] 46; CGSCC-NEXT: ret i16 [[CALL]] 47; 48 %call = call i16 @bar(i16 %a) 49 ret i16 %call 50} 51 52define internal i16 @bar(i16 %p1, i16 %p2) { 53; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 54; CGSCC-LABEL: define {{[^@]+}}@bar 55; CGSCC-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR1:[0-9]+]] { 56; CGSCC-NEXT: ret i16 0 57; 58 ret i16 0 59} 60 61define dso_local i16 @foo2(i16 %a) { 62; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 63; TUNIT-LABEL: define {{[^@]+}}@foo2 64; TUNIT-SAME: (i16 [[A:%.*]]) #[[ATTR0]] { 65; TUNIT-NEXT: [[CALL:%.*]] = call i16 @bar2(i16 [[A]]) #[[ATTR1:[0-9]+]] 66; TUNIT-NEXT: ret i16 [[CALL]] 67; 68; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 69; CGSCC-LABEL: define {{[^@]+}}@foo2 70; CGSCC-SAME: (i16 [[A:%.*]]) #[[ATTR0]] { 71; CGSCC-NEXT: [[CALL:%.*]] = call i16 @bar2(i16 [[A]]) #[[ATTR2]] 72; CGSCC-NEXT: ret i16 [[CALL]] 73; 74 %call = call i16 @bar2(i16 %a) 75 ret i16 %call 76} 77 78define internal i16 @bar2(i16 %p1, i16 %p2) { 79; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 80; TUNIT-LABEL: define {{[^@]+}}@bar2 81; TUNIT-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR0]] { 82; TUNIT-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]] 83; TUNIT-NEXT: ret i16 [[A]] 84; 85; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 86; CGSCC-LABEL: define {{[^@]+}}@bar2 87; CGSCC-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR1]] { 88; CGSCC-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]] 89; CGSCC-NEXT: ret i16 [[A]] 90; 91 %a = add i16 %p1, %p2 92 ret i16 %a 93} 94 95 96;------------------------------------------------------------------------------- 97; Additional tests to verify that we still optimize when having a mismatch 98; in argument count due to varargs (as long as all non-variadic arguments have 99; been provided), 100 101define dso_local i16 @vararg_tests(i16 %a) { 102; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 103; TUNIT-LABEL: define {{[^@]+}}@vararg_tests 104; TUNIT-SAME: (i16 [[A:%.*]]) #[[ATTR0]] { 105; TUNIT-NEXT: ret i16 14 106; 107; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 108; CGSCC-LABEL: define {{[^@]+}}@vararg_tests 109; CGSCC-SAME: (i16 [[A:%.*]]) #[[ATTR0]] { 110; CGSCC-NEXT: [[CALL1:%.*]] = call i16 (i16, ...) @vararg_prop(i16 noundef 7, i16 noundef 8, i16 [[A]]) #[[ATTR2]] 111; CGSCC-NEXT: [[CALL2:%.*]] = call i16 @vararg_no_prop(i16 noundef 7) #[[ATTR2]] 112; CGSCC-NEXT: [[ADD:%.*]] = add i16 [[CALL1]], [[CALL2]] 113; CGSCC-NEXT: ret i16 [[ADD]] 114; 115 %call1 = call i16 (i16, ...) @vararg_prop(i16 7, i16 8, i16 %a) 116 %call2 = call i16 @vararg_no_prop (i16 7) 117 %add = add i16 %call1, %call2 118 ret i16 %add 119} 120 121define internal i16 @vararg_prop(i16 %p1, ...) { 122; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 123; CGSCC-LABEL: define {{[^@]+}}@vararg_prop 124; CGSCC-SAME: (i16 [[P1:%.*]], ...) #[[ATTR1]] { 125; CGSCC-NEXT: ret i16 7 126; 127 ret i16 %p1 128} 129 130define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) { 131; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 132; CGSCC-LABEL: define {{[^@]+}}@vararg_no_prop 133; CGSCC-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR1]] { 134; CGSCC-NEXT: ret i16 7 135; 136 ret i16 %p1 137} 138 139;. 140; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } 141; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) } 142;. 143; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree nosync nounwind willreturn memory(none) } 144; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } 145; CGSCC: attributes #[[ATTR2]] = { nofree nosync willreturn } 146;. 147;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 148; CHECK: {{.*}} 149