346 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -mtriple=wasm32-unknown-unknown -S --passes=expand-variadics --expand-variadics-override=optimize < %s | FileCheck %s -check-prefixes=OPT3; RUN: opt -mtriple=wasm32-unknown-unknown -S --passes=expand-variadics --expand-variadics-override=lowering < %s | FileCheck %s -check-prefixes=ABI4; REQUIRES: webassembly-registered-target5 6; Wasm passes struct {char} as an i8 so can check the varargs passing works on integers smaller than the slot size7 8declare void @sink(...)9 10 11define void @pass_nothing() {12; OPT-LABEL: @pass_nothing(13; OPT-NEXT: entry:14; OPT-NEXT: tail call void (...) @sink()15; OPT-NEXT: ret void16;17; ABI-LABEL: @pass_nothing(18; ABI-NEXT: entry:19; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_NOTHING_VARARG:%.*]], align 1620; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])21; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])22; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])23; ABI-NEXT: ret void24;25entry:26 tail call void (...) @sink()27 ret void28}29 30define void @pass_s1(i8 %x) {31; OPT-LABEL: @pass_s1(32; OPT-NEXT: entry:33; OPT-NEXT: tail call void (...) @sink(i8 [[X:%.*]])34; OPT-NEXT: ret void35;36; ABI-LABEL: @pass_s1(37; ABI-NEXT: entry:38; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S1_VARARG:%.*]], align 1639; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])40; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S1_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 041; ABI-NEXT: store i8 [[X:%.*]], ptr [[TMP0]], align 142; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])43; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])44; ABI-NEXT: ret void45;46entry:47 tail call void (...) @sink(i8 %x)48 ret void49}50 51define void @pass_s2(i16 %x) {52; OPT-LABEL: @pass_s2(53; OPT-NEXT: entry:54; OPT-NEXT: tail call void (...) @sink(i16 [[X:%.*]])55; OPT-NEXT: ret void56;57; ABI-LABEL: @pass_s2(58; ABI-NEXT: entry:59; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S2_VARARG:%.*]], align 1660; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])61; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S2_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 062; ABI-NEXT: store i16 [[X:%.*]], ptr [[TMP0]], align 263; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])64; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])65; ABI-NEXT: ret void66;67entry:68 tail call void (...) @sink(i16 %x)69 ret void70}71 72define void @pass_s3(i32 %x) {73; OPT-LABEL: @pass_s3(74; OPT-NEXT: entry:75; OPT-NEXT: tail call void (...) @sink(i32 [[X:%.*]])76; OPT-NEXT: ret void77;78; ABI-LABEL: @pass_s3(79; ABI-NEXT: entry:80; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S3_VARARG:%.*]], align 1681; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])82; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S3_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 083; ABI-NEXT: store i32 [[X:%.*]], ptr [[TMP0]], align 484; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])85; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])86; ABI-NEXT: ret void87;88entry:89 tail call void (...) @sink(i32 %x)90 ret void91}92 93define void @pass_s4(i64 %x) {94; OPT-LABEL: @pass_s4(95; OPT-NEXT: entry:96; OPT-NEXT: tail call void (...) @sink(i64 [[X:%.*]])97; OPT-NEXT: ret void98;99; ABI-LABEL: @pass_s4(100; ABI-NEXT: entry:101; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S4_VARARG:%.*]], align 16102; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])103; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S4_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0104; ABI-NEXT: store i64 [[X:%.*]], ptr [[TMP0]], align 8105; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])106; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])107; ABI-NEXT: ret void108;109entry:110 tail call void (...) @sink(i64 %x)111 ret void112}113 114define void @pass_s5(<4 x i32> %x) {115; OPT-LABEL: @pass_s5(116; OPT-NEXT: entry:117; OPT-NEXT: tail call void (...) @sink(<4 x i32> [[X:%.*]])118; OPT-NEXT: ret void119;120; ABI-LABEL: @pass_s5(121; ABI-NEXT: entry:122; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S5_VARARG:%.*]], align 16123; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])124; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S5_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0125; ABI-NEXT: store <4 x i32> [[X:%.*]], ptr [[TMP0]], align 16126; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])127; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])128; ABI-NEXT: ret void129;130entry:131 tail call void (...) @sink(<4 x i32> %x)132 ret void133}134 135define void @pass_int_s1(i32 %i, i8 %x) {136; OPT-LABEL: @pass_int_s1(137; OPT-NEXT: entry:138; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i8 [[X:%.*]])139; OPT-NEXT: ret void140;141; ABI-LABEL: @pass_int_s1(142; ABI-NEXT: entry:143; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S1_VARARG:%.*]], align 16144; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])145; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S1_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0146; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4147; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S1_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1148; ABI-NEXT: store i8 [[X:%.*]], ptr [[TMP1]], align 1149; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])150; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])151; ABI-NEXT: ret void152;153entry:154 tail call void (...) @sink(i32 %i, i8 %x)155 ret void156}157 158define void @pass_int_s2(i32 %i, i16 %x) {159; OPT-LABEL: @pass_int_s2(160; OPT-NEXT: entry:161; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i16 [[X:%.*]])162; OPT-NEXT: ret void163;164; ABI-LABEL: @pass_int_s2(165; ABI-NEXT: entry:166; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S2_VARARG:%.*]], align 16167; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])168; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S2_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0169; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4170; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S2_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1171; ABI-NEXT: store i16 [[X:%.*]], ptr [[TMP1]], align 2172; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])173; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])174; ABI-NEXT: ret void175;176entry:177 tail call void (...) @sink(i32 %i, i16 %x)178 ret void179}180 181define void @pass_int_s3(i32 %i, i32 %x) {182; OPT-LABEL: @pass_int_s3(183; OPT-NEXT: entry:184; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i32 [[X:%.*]])185; OPT-NEXT: ret void186;187; ABI-LABEL: @pass_int_s3(188; ABI-NEXT: entry:189; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S3_VARARG:%.*]], align 16190; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])191; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S3_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0192; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4193; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S3_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1194; ABI-NEXT: store i32 [[X:%.*]], ptr [[TMP1]], align 4195; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])196; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])197; ABI-NEXT: ret void198;199entry:200 tail call void (...) @sink(i32 %i, i32 %x)201 ret void202}203 204define void @pass_int_s4(i32 %i, i64 %x) {205; OPT-LABEL: @pass_int_s4(206; OPT-NEXT: entry:207; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i64 [[X:%.*]])208; OPT-NEXT: ret void209;210; ABI-LABEL: @pass_int_s4(211; ABI-NEXT: entry:212; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S4_VARARG:%.*]], align 16213; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])214; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S4_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0215; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4216; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S4_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 2217; ABI-NEXT: store i64 [[X:%.*]], ptr [[TMP1]], align 8218; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])219; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])220; ABI-NEXT: ret void221;222entry:223 tail call void (...) @sink(i32 %i, i64 %x)224 ret void225}226 227define void @pass_int_s5(i32 %i, <4 x i32> %x) {228; OPT-LABEL: @pass_int_s5(229; OPT-NEXT: entry:230; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], <4 x i32> [[X:%.*]])231; OPT-NEXT: ret void232;233; ABI-LABEL: @pass_int_s5(234; ABI-NEXT: entry:235; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S5_VARARG:%.*]], align 16236; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])237; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S5_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0238; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4239; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S5_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 2240; ABI-NEXT: store <4 x i32> [[X:%.*]], ptr [[TMP1]], align 16241; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])242; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])243; ABI-NEXT: ret void244;245entry:246 tail call void (...) @sink(i32 %i, <4 x i32> %x)247 ret void248}249 250define void @pass_asc(i8 %x1, i16 %x2, i32 %x3, i64 %x4, <4 x i32> %x5) {251; OPT-LABEL: @pass_asc(252; OPT-NEXT: entry:253; OPT-NEXT: tail call void (...) @sink(i8 [[X1:%.*]], i16 [[X2:%.*]], i32 [[X3:%.*]], i64 [[X4:%.*]], <4 x i32> [[X5:%.*]])254; OPT-NEXT: ret void255;256; ABI-LABEL: @pass_asc(257; ABI-NEXT: entry:258; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_ASC_VARARG:%.*]], align 16259; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])260; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0261; ABI-NEXT: store i8 [[X1:%.*]], ptr [[TMP0]], align 1262; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 2263; ABI-NEXT: store i16 [[X2:%.*]], ptr [[TMP1]], align 2264; ABI-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 4265; ABI-NEXT: store i32 [[X3:%.*]], ptr [[TMP2]], align 4266; ABI-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 6267; ABI-NEXT: store i64 [[X4:%.*]], ptr [[TMP3]], align 8268; ABI-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 8269; ABI-NEXT: store <4 x i32> [[X5:%.*]], ptr [[TMP4]], align 16270; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])271; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])272; ABI-NEXT: ret void273;274entry:275 tail call void (...) @sink(i8 %x1, i16 %x2, i32 %x3, i64 %x4, <4 x i32> %x5)276 ret void277}278 279define void @pass_dsc(<4 x i32> %x0, i64 %x1, i32 %x2, i16 %x3, i8 %x4) {280; OPT-LABEL: @pass_dsc(281; OPT-NEXT: entry:282; OPT-NEXT: tail call void (...) @sink(<4 x i32> [[X0:%.*]], i64 [[X1:%.*]], i32 [[X2:%.*]], i16 [[X3:%.*]], i8 [[X4:%.*]])283; OPT-NEXT: ret void284;285; ABI-LABEL: @pass_dsc(286; ABI-NEXT: entry:287; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_DSC_VARARG:%.*]], align 16288; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])289; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0290; ABI-NEXT: store <4 x i32> [[X0:%.*]], ptr [[TMP0]], align 16291; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1292; ABI-NEXT: store i64 [[X1:%.*]], ptr [[TMP1]], align 8293; ABI-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 2294; ABI-NEXT: store i32 [[X2:%.*]], ptr [[TMP2]], align 4295; ABI-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 3296; ABI-NEXT: store i16 [[X3:%.*]], ptr [[TMP3]], align 2297; ABI-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 5298; ABI-NEXT: store i8 [[X4:%.*]], ptr [[TMP4]], align 1299; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])300; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])301; ABI-NEXT: ret void302;303entry:304 tail call void (...) @sink(<4 x i32> %x0, i64 %x1, i32 %x2, i16 %x3, i8 %x4)305 ret void306}307 308define void @pass_multiple(i32 %i, i8 %x1, i16 %x2, i32 %x3, i64 %x4, <4 x i32> %x5) {309; OPT-LABEL: @pass_multiple(310; OPT-NEXT: entry:311; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i16 [[X2:%.*]], i64 [[X4:%.*]])312; OPT-NEXT: tail call void (...) @sink(i32 [[I]], i8 [[X1:%.*]], i32 [[X3:%.*]], <4 x i32> [[X5:%.*]])313; OPT-NEXT: ret void314;315; ABI-LABEL: @pass_multiple(316; ABI-NEXT: entry:317; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_MULTIPLE_VARARG:%.*]], align 16318; ABI-NEXT: [[VARARG_BUFFER1:%.*]] = alloca [[PASS_MULTIPLE_VARARG_0:%.*]], align 16319; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER]])320; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0321; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4322; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1323; ABI-NEXT: store i16 [[X2:%.*]], ptr [[TMP1]], align 2324; ABI-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 3325; ABI-NEXT: store i64 [[X4:%.*]], ptr [[TMP2]], align 8326; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]])327; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER]])328; ABI-NEXT: call void @llvm.lifetime.start.p0(ptr [[VARARG_BUFFER1]])329; ABI-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG_0]], ptr [[VARARG_BUFFER1]], i32 0, i32 0330; ABI-NEXT: store i32 [[I]], ptr [[TMP3]], align 4331; ABI-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG_0]], ptr [[VARARG_BUFFER1]], i32 0, i32 1332; ABI-NEXT: store i8 [[X1:%.*]], ptr [[TMP4]], align 1333; ABI-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG_0]], ptr [[VARARG_BUFFER1]], i32 0, i32 3334; ABI-NEXT: store i32 [[X3:%.*]], ptr [[TMP5]], align 4335; ABI-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG_0]], ptr [[VARARG_BUFFER1]], i32 0, i32 5336; ABI-NEXT: store <4 x i32> [[X5:%.*]], ptr [[TMP6]], align 16337; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER1]])338; ABI-NEXT: call void @llvm.lifetime.end.p0(ptr [[VARARG_BUFFER1]])339; ABI-NEXT: ret void340;341entry:342 tail call void (...) @sink(i32 %i, i16 %x2, i64 %x4)343 tail call void (...) @sink(i32 %i, i8 %x1, i32 %x3, <4 x i32> %x5)344 ret void345}346