| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -mtriple=wasm32-unknown-unknown -S --passes=expand-variadics --expand-variadics-override=optimize < %s | FileCheck %s -check-prefixes=OPT |
| ; RUN: opt -mtriple=wasm32-unknown-unknown -S --passes=expand-variadics --expand-variadics-override=lowering < %s | FileCheck %s -check-prefixes=ABI |
| ; REQUIRES: webassembly-registered-target |
| |
| ; Wasm passes struct {char} as an i8 so can check the varargs passing works on integers smaller than the slot size |
| |
| declare void @sink(...) |
| |
| |
| define void @pass_nothing() { |
| ; OPT-LABEL: @pass_nothing( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink() |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_nothing( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_NOTHING_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 1, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 1, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink() |
| ret void |
| } |
| |
| define void @pass_s1(i8 %x) { |
| ; OPT-LABEL: @pass_s1( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i8 [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_s1( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S1_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 1, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S1_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i8 [[X:%.*]], ptr [[TMP0]], align 1 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 1, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i8 %x) |
| ret void |
| } |
| |
| define void @pass_s2(i16 %x) { |
| ; OPT-LABEL: @pass_s2( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i16 [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_s2( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S2_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 2, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S2_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i16 [[X:%.*]], ptr [[TMP0]], align 2 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 2, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i16 %x) |
| ret void |
| } |
| |
| define void @pass_s3(i32 %x) { |
| ; OPT-LABEL: @pass_s3( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i32 [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_s3( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S3_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S3_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i32 [[X:%.*]], ptr [[TMP0]], align 4 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i32 %x) |
| ret void |
| } |
| |
| define void @pass_s4(i64 %x) { |
| ; OPT-LABEL: @pass_s4( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i64 [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_s4( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S4_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S4_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i64 [[X:%.*]], ptr [[TMP0]], align 8 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i64 %x) |
| ret void |
| } |
| |
| define void @pass_s5(<4 x i32> %x) { |
| ; OPT-LABEL: @pass_s5( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(<4 x i32> [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_s5( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_S5_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_S5_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store <4 x i32> [[X:%.*]], ptr [[TMP0]], align 16 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(<4 x i32> %x) |
| ret void |
| } |
| |
| define void @pass_int_s1(i32 %i, i8 %x) { |
| ; OPT-LABEL: @pass_int_s1( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i8 [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_int_s1( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S1_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 5, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S1_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4 |
| ; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S1_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1 |
| ; ABI-NEXT: store i8 [[X:%.*]], ptr [[TMP1]], align 1 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 5, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i32 %i, i8 %x) |
| ret void |
| } |
| |
| define void @pass_int_s2(i32 %i, i16 %x) { |
| ; OPT-LABEL: @pass_int_s2( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i16 [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_int_s2( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S2_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 6, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S2_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4 |
| ; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S2_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1 |
| ; ABI-NEXT: store i16 [[X:%.*]], ptr [[TMP1]], align 2 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 6, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i32 %i, i16 %x) |
| ret void |
| } |
| |
| define void @pass_int_s3(i32 %i, i32 %x) { |
| ; OPT-LABEL: @pass_int_s3( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i32 [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_int_s3( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S3_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S3_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4 |
| ; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S3_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1 |
| ; ABI-NEXT: store i32 [[X:%.*]], ptr [[TMP1]], align 4 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i32 %i, i32 %x) |
| ret void |
| } |
| |
| define void @pass_int_s4(i32 %i, i64 %x) { |
| ; OPT-LABEL: @pass_int_s4( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i64 [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_int_s4( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S4_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S4_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4 |
| ; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S4_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 2 |
| ; ABI-NEXT: store i64 [[X:%.*]], ptr [[TMP1]], align 8 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i32 %i, i64 %x) |
| ret void |
| } |
| |
| define void @pass_int_s5(i32 %i, <4 x i32> %x) { |
| ; OPT-LABEL: @pass_int_s5( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], <4 x i32> [[X:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_int_s5( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_INT_S5_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_INT_S5_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4 |
| ; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_INT_S5_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 2 |
| ; ABI-NEXT: store <4 x i32> [[X:%.*]], ptr [[TMP1]], align 16 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i32 %i, <4 x i32> %x) |
| ret void |
| } |
| |
| define void @pass_asc(i8 %x1, i16 %x2, i32 %x3, i64 %x4, <4 x i32> %x5) { |
| ; OPT-LABEL: @pass_asc( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i8 [[X1:%.*]], i16 [[X2:%.*]], i32 [[X3:%.*]], i64 [[X4:%.*]], <4 x i32> [[X5:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_asc( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_ASC_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 48, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i8 [[X1:%.*]], ptr [[TMP0]], align 1 |
| ; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 2 |
| ; ABI-NEXT: store i16 [[X2:%.*]], ptr [[TMP1]], align 2 |
| ; ABI-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 4 |
| ; ABI-NEXT: store i32 [[X3:%.*]], ptr [[TMP2]], align 4 |
| ; ABI-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 6 |
| ; ABI-NEXT: store i64 [[X4:%.*]], ptr [[TMP3]], align 8 |
| ; ABI-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[PASS_ASC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 8 |
| ; ABI-NEXT: store <4 x i32> [[X5:%.*]], ptr [[TMP4]], align 16 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 48, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i8 %x1, i16 %x2, i32 %x3, i64 %x4, <4 x i32> %x5) |
| ret void |
| } |
| |
| define void @pass_dsc(<4 x i32> %x0, i64 %x1, i32 %x2, i16 %x3, i8 %x4) { |
| ; OPT-LABEL: @pass_dsc( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(<4 x i32> [[X0:%.*]], i64 [[X1:%.*]], i32 [[X2:%.*]], i16 [[X3:%.*]], i8 [[X4:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_dsc( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_DSC_VARARG:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 33, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store <4 x i32> [[X0:%.*]], ptr [[TMP0]], align 16 |
| ; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1 |
| ; ABI-NEXT: store i64 [[X1:%.*]], ptr [[TMP1]], align 8 |
| ; ABI-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 2 |
| ; ABI-NEXT: store i32 [[X2:%.*]], ptr [[TMP2]], align 4 |
| ; ABI-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 3 |
| ; ABI-NEXT: store i16 [[X3:%.*]], ptr [[TMP3]], align 2 |
| ; ABI-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[PASS_DSC_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 5 |
| ; ABI-NEXT: store i8 [[X4:%.*]], ptr [[TMP4]], align 1 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 33, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(<4 x i32> %x0, i64 %x1, i32 %x2, i16 %x3, i8 %x4) |
| ret void |
| } |
| |
| define void @pass_multiple(i32 %i, i8 %x1, i16 %x2, i32 %x3, i64 %x4, <4 x i32> %x5) { |
| ; OPT-LABEL: @pass_multiple( |
| ; OPT-NEXT: entry: |
| ; OPT-NEXT: tail call void (...) @sink(i32 [[I:%.*]], i16 [[X2:%.*]], i64 [[X4:%.*]]) |
| ; OPT-NEXT: tail call void (...) @sink(i32 [[I]], i8 [[X1:%.*]], i32 [[X3:%.*]], <4 x i32> [[X5:%.*]]) |
| ; OPT-NEXT: ret void |
| ; |
| ; ABI-LABEL: @pass_multiple( |
| ; ABI-NEXT: entry: |
| ; ABI-NEXT: [[VARARG_BUFFER:%.*]] = alloca [[PASS_MULTIPLE_VARARG:%.*]], align 16 |
| ; ABI-NEXT: [[VARARG_BUFFER1:%.*]] = alloca [[PASS_MULTIPLE_VARARG_0:%.*]], align 16 |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 0 |
| ; ABI-NEXT: store i32 [[I:%.*]], ptr [[TMP0]], align 4 |
| ; ABI-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 1 |
| ; ABI-NEXT: store i16 [[X2:%.*]], ptr [[TMP1]], align 2 |
| ; ABI-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG]], ptr [[VARARG_BUFFER]], i32 0, i32 3 |
| ; ABI-NEXT: store i64 [[X4:%.*]], ptr [[TMP2]], align 8 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr [[VARARG_BUFFER]]) |
| ; ABI-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr [[VARARG_BUFFER1]]) |
| ; ABI-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG_0]], ptr [[VARARG_BUFFER1]], i32 0, i32 0 |
| ; ABI-NEXT: store i32 [[I]], ptr [[TMP3]], align 4 |
| ; ABI-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG_0]], ptr [[VARARG_BUFFER1]], i32 0, i32 1 |
| ; ABI-NEXT: store i8 [[X1:%.*]], ptr [[TMP4]], align 1 |
| ; ABI-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG_0]], ptr [[VARARG_BUFFER1]], i32 0, i32 3 |
| ; ABI-NEXT: store i32 [[X3:%.*]], ptr [[TMP5]], align 4 |
| ; ABI-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[PASS_MULTIPLE_VARARG_0]], ptr [[VARARG_BUFFER1]], i32 0, i32 5 |
| ; ABI-NEXT: store <4 x i32> [[X5:%.*]], ptr [[TMP6]], align 16 |
| ; ABI-NEXT: call void @sink(ptr [[VARARG_BUFFER1]]) |
| ; ABI-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr [[VARARG_BUFFER1]]) |
| ; ABI-NEXT: ret void |
| ; |
| entry: |
| tail call void (...) @sink(i32 %i, i16 %x2, i64 %x4) |
| tail call void (...) @sink(i32 %i, i8 %x1, i32 %x3, <4 x i32> %x5) |
| ret void |
| } |