Files
clang-p2996/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments.ll
Alex Richardson e39f6c1844 [opt] Infer DataLayout from triple if not specified
There are many tests that specify a target triple/CPU flags but no
DataLayout which can lead to IR being generated that has unusual
behaviour. This commit attempts to use the default DataLayout based
on the relevant flags if there is no explicit override on the command
line or in the IR file.

One thing that is not currently possible to differentiate from a missing
datalayout `target datalayout = ""` in the IR file since the current
APIs don't allow detecting this case. If it is considered useful to
support this case (instead of passing "-data-layout=" on the command
line), I can change IR parsers to track whether they have seen such a
directive and change the callback type.

Differential Revision: https://reviews.llvm.org/D141060
2023-10-26 12:07:37 -07:00

1156 lines
50 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-rewrite-out-arguments < %s | FileCheck %s
define void @no_ret_blocks() #0 {
unreachable
}
define void @void_one_out_arg_i32_no_use(ptr addrspace(5) %val) #0 {
ret void
}
define void @skip_byval_arg(ptr addrspace(5) byval(i32) %val) #0 {
store i32 0, ptr addrspace(5) %val
ret void
}
define void @skip_optnone(ptr addrspace(5) byval(i32) %val) #1 {
store i32 0, ptr addrspace(5) %val
ret void
}
define void @skip_volatile(ptr addrspace(5) byval(i32) %val) #0 {
store volatile i32 0, ptr addrspace(5) %val
ret void
}
define void @skip_atomic(ptr addrspace(5) byval(i32) %val) #0 {
store atomic i32 0, ptr addrspace(5) %val seq_cst, align 4
ret void
}
define void @skip_store_pointer_val(ptr addrspace(5) %val) #0 {
store ptr addrspace(5) %val, ptr poison
ret void
}
define void @skip_store_gep(ptr addrspace(5) %val) #0 {
%gep = getelementptr inbounds i32, ptr addrspace(5) %val, i32 1
store i32 0, ptr addrspace(5) %gep
ret void
}
define void @skip_sret(ptr addrspace(5) sret(i32) %sret, ptr addrspace(5) %out) #0 {
store i32 1, ptr addrspace(5) %sret
store i32 0, ptr addrspace(5) %out
ret void
}
define void @void_one_out_arg_i32_1_use(ptr addrspace(5) %val) #0 {
store i32 0, ptr addrspace(5) %val
ret void
}
define void @void_one_out_arg_i32_1_use_align(ptr addrspace(5) align 8 %val) #0 {
store i32 0, ptr addrspace(5) %val, align 8
ret void
}
define void @void_one_out_arg_i32_2_use(i1 %arg0, ptr addrspace(5) %val) #0 {
br i1 %arg0, label %ret0, label %ret1
ret0:
store i32 0, ptr addrspace(5) %val
ret void
ret1:
store i32 9, ptr addrspace(5) %val
ret void
}
declare void @may.clobber()
define void @void_one_out_arg_i32_2_stores(ptr addrspace(5) %val) #0 {
store i32 0, ptr addrspace(5) %val
store i32 1, ptr addrspace(5) %val
ret void
}
define void @void_one_out_arg_i32_2_stores_clobber(ptr addrspace(5) %val) #0 {
store i32 0, ptr addrspace(5) %val
call void @may.clobber()
store i32 1, ptr addrspace(5) %val
ret void
}
define void @void_one_out_arg_i32_call_may_clobber(ptr addrspace(5) %val) #0 {
store i32 0, ptr addrspace(5) %val
call void @may.clobber()
ret void
}
define void @void_one_out_arg_i32_pre_call_may_clobber(ptr addrspace(5) %val) #0 {
call void @may.clobber()
store i32 0, ptr addrspace(5) %val
ret void
}
define void @void_one_out_arg_i32_reload(ptr addrspace(5) %val) #0 {
store i32 0, ptr addrspace(5) %val
%load = load i32, ptr addrspace(5) %val, align 4
ret void
}
define void @void_one_out_arg_i32_store_in_different_block(ptr addrspace(5) %out) #0 {
%load = load i32, ptr addrspace(1) poison
store i32 0, ptr addrspace(5) %out
br label %ret
ret:
ret void
}
define void @unused_out_arg_one_branch(i1 %arg0, ptr addrspace(5) %val) #0 {
br i1 %arg0, label %ret0, label %ret1
ret0:
ret void
ret1:
store i32 9, ptr addrspace(5) %val
ret void
}
define void @void_one_out_arg_v2i32_1_use(ptr addrspace(5) %val) #0 {
store <2 x i32> <i32 17, i32 9>, ptr addrspace(5) %val
ret void
}
%struct = type { i32, i8, float }
; Normally this is split into element accesses which we don't handle.
define void @void_one_out_arg_struct_1_use(ptr addrspace(5) %out) #0 {
store %struct { i32 9, i8 99, float 4.0 }, ptr addrspace(5) %out
ret void
}
define i32 @i32_one_out_arg_i32_1_use(ptr addrspace(5) %val) #0 {
store i32 24, ptr addrspace(5) %val
ret i32 9
}
define void @unused_different_type(ptr addrspace(5) %arg0, ptr addrspace(5) nocapture %arg1) #0 {
store float 4.0, ptr addrspace(5) %arg1, align 4
ret void
}
define void @multiple_same_return_noalias(ptr addrspace(5) noalias %out0, ptr addrspace(5) noalias %out1) #0 {
store i32 1, ptr addrspace(5) %out0, align 4
store i32 2, ptr addrspace(5) %out1, align 4
ret void
}
define void @multiple_same_return_mayalias(ptr addrspace(5) %out0, ptr addrspace(5) %out1) #0 {
store i32 1, ptr addrspace(5) %out0, align 4
store i32 2, ptr addrspace(5) %out1, align 4
ret void
}
define void @multiple_same_return_mayalias_order(ptr addrspace(5) %out0, ptr addrspace(5) %out1) #0 {
store i32 2, ptr addrspace(5) %out1, align 4
store i32 1, ptr addrspace(5) %out0, align 4
ret void
}
; Currently this fails to convert because the store won't be found if
; it isn't in the same block as the return.
define i32 @store_in_entry_block(i1 %arg0, ptr addrspace(5) %out) #0 {
entry:
%val0 = load i32, ptr addrspace(1) poison
store i32 %val0, ptr addrspace(5) %out
br i1 %arg0, label %if, label %endif
if:
%val1 = load i32, ptr addrspace(1) poison
br label %endif
endif:
%phi = phi i32 [ 0, %entry ], [ %val1, %if ]
ret i32 %phi
}
define i1 @i1_one_out_arg_i32_1_use(ptr addrspace(5) %val) #0 {
store i32 24, ptr addrspace(5) %val
ret i1 true
}
; Make sure we don't leave around return attributes that are
; incompatible with struct return types.
define zeroext i1 @i1_zeroext_one_out_arg_i32_1_use(ptr addrspace(5) %val) #0 {
store i32 24, ptr addrspace(5) %val
ret i1 true
}
define signext i1 @i1_signext_one_out_arg_i32_1_use(ptr addrspace(5) %val) #0 {
store i32 24, ptr addrspace(5) %val
ret i1 true
}
define noalias ptr addrspace(1) @p1i32_noalias_one_out_arg_i32_1_use(ptr addrspace(5) %val) #0 {
store i32 24, ptr addrspace(5) %val
ret ptr addrspace(1) null
}
define void @void_one_out_non_private_arg_i32_1_use(ptr addrspace(1) %val) #0 {
store i32 0, ptr addrspace(1) %val
ret void
}
define void @func_ptr_type(ptr addrspace(5) %out) #0 {
%func = load ptr, ptr poison
store ptr %func, ptr addrspace(5) %out
ret void
}
define void @bitcast_func_ptr_type(ptr addrspace(5) %out) #0 {
%func = load ptr, ptr poison
store ptr %func, ptr addrspace(5) %out
ret void
}
define void @out_arg_small_array(ptr addrspace(5) %val) #0 {
store [4 x i32] [i32 0, i32 1, i32 2, i32 3], ptr addrspace(5) %val
ret void
}
define void @out_arg_large_array(ptr addrspace(5) %val) #0 {
store [17 x i32] zeroinitializer, ptr addrspace(5) %val
ret void
}
define <16 x i32> @num_regs_return_limit(ptr addrspace(5) %out, i32 %val) #0 {
%load = load volatile <16 x i32>, ptr addrspace(1) poison
store i32 %val, ptr addrspace(5) %out
ret <16 x i32> %load
}
define [15 x i32] @num_regs_reach_limit(ptr addrspace(5) %out, i32 %val) #0 {
%load = load volatile [15 x i32], ptr addrspace(1) poison
store i32 %val, ptr addrspace(5) %out
ret [15 x i32] %load
}
define [15 x i32] @num_regs_reach_limit_leftover(ptr addrspace(5) %out0, ptr addrspace(5) %out1, i32 %val0) #0 {
%load0 = load volatile [15 x i32], ptr addrspace(1) poison
%load1 = load volatile i32, ptr addrspace(1) poison
store i32 %val0, ptr addrspace(5) %out0
store i32 %load1, ptr addrspace(5) %out1
ret [15 x i32] %load0
}
define void @preserve_debug_info(i32 %arg0, ptr addrspace(5) %val) #0 !dbg !5 {
call void @may.clobber(), !dbg !10
store i32 %arg0, ptr addrspace(5) %val, !dbg !11
ret void, !dbg !12
}
define void @preserve_metadata(i32 %arg0, ptr addrspace(5) %val) #0 !kernel_arg_access_qual !13 {
call void @may.clobber()
store i32 %arg0, ptr addrspace(5) %val
ret void
}
; Clang emits this pattern for 3-vectors for some reason.
define void @bitcast_pointer_v4i32_v3i32(ptr addrspace(5) %out) #0 {
%load = load volatile <4 x i32>, ptr addrspace(1) poison
store <4 x i32> %load, ptr addrspace(5) %out
ret void
}
define void @bitcast_pointer_v4i32_v3f32(ptr addrspace(5) %out) #0 {
%load = load volatile <4 x i32>, ptr addrspace(1) poison
store <4 x i32> %load, ptr addrspace(5) %out
ret void
}
; Try different element and bitwidths which could produce broken
; casts.
define void @bitcast_pointer_i32_f32(ptr addrspace(5) %out) #0 {
%load = load volatile i32, ptr addrspace(1) poison
store i32 %load, ptr addrspace(5) %out
ret void
}
define void @bitcast_pointer_i32_f16(ptr addrspace(5) %out) #0 {
%load = load volatile i32, ptr addrspace(1) poison
store i32 %load, ptr addrspace(5) %out
ret void
}
define void @bitcast_pointer_f16_i32(ptr addrspace(5) %out) #0 {
%load = load volatile half, ptr addrspace(1) poison
store half %load, ptr addrspace(5) %out
ret void
}
%struct.i128 = type { i128 }
%struct.v2f32 = type { <2 x float> }
%struct.v3f32 = type { <3 x float> }
%struct.v3f32.f32 = type { <3 x float>, float }
%struct.v4f32 = type { <4 x float> }
define void @bitcast_struct_v3f32_v3f32(ptr addrspace(5) %out, <3 x float> %value) #0 {
%extractVec = shufflevector <3 x float> %value, <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
store <4 x float> %extractVec, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_struct_v3f32_v3i32(ptr addrspace(5) %out, <3 x i32> %value) #0 {
%extractVec = shufflevector <3 x i32> %value, <3 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
store <4 x i32> %extractVec, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_struct_v4f32_v4f32(ptr addrspace(5) %out, <4 x float> %value) #0 {
store <4 x float> %value, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_struct_v3f32_v4i32(ptr addrspace(5) %out, <4 x i32> %value) #0 {
store <4 x i32> %value, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_struct_v4f32_v3f32(ptr addrspace(5) %out, <3 x float> %value) #0 {
%extractVec = shufflevector <3 x float> %value, <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
store <4 x float> %extractVec, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_struct_v3f32_v2f32(ptr addrspace(5) %out, <2 x float> %value) #0 {
store <2 x float> %value, ptr addrspace(5) %out, align 8
ret void
}
define void @bitcast_struct_v3f32_f32_v3f32(ptr addrspace(5) %out, <3 x float> %value) #0 {
%extractVec = shufflevector <3 x float> %value, <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
store <4 x float> %extractVec, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_struct_v3f32_f32_v4f32(ptr addrspace(5) %out, <4 x float> %value) #0 {
store <4 x float> %value, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_struct_i128_v4f32(ptr addrspace(5) %out, <4 x float> %value) #0 {
store <4 x float> %value, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_array_v4i32_v4f32(ptr addrspace(5) %out, [4 x float] %value) #0 {
store [4 x float] %value, ptr addrspace(5) %out, align 4
ret void
}
define void @multi_return_bitcast_struct_v3f32_v3f32(i1 %cond, ptr addrspace(5) %out, <3 x float> %value) #0 {
entry:
br i1 %cond, label %ret0, label %ret1
ret0:
%extractVec = shufflevector <3 x float> %value, <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
store <4 x float> %extractVec, ptr addrspace(5) %out, align 16
ret void
ret1:
%load = load <4 x float>, ptr addrspace(1) poison
store <4 x float> %load, ptr addrspace(5) %out, align 16
ret void
}
define void @bitcast_v3f32_struct_v3f32(ptr addrspace(5) %out, %struct.v3f32 %value) #0 {
store %struct.v3f32 %value, ptr addrspace(5) %out, align 4
ret void
}
attributes #0 = { nounwind }
attributes #1 = { nounwind noinline optnone }
attributes #2 = { alwaysinline nounwind }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 5.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "code-object-metadata-kernel-debug-props.cl", directory: "/some/random/directory")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 2}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, type: !6, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
!6 = !DISubroutineType(types: !7)
!7 = !{null, !8}
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64)
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!10 = !DILocation(line: 2, column: 3, scope: !5)
!11 = !DILocation(line: 2, column: 8, scope: !5)
!12 = !DILocation(line: 3, column: 3, scope: !5)
!13 = !{!"none"}
; CHECK-LABEL: define {{[^@]+}}@no_ret_blocks
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: unreachable
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_no_use
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@skip_byval_arg
; CHECK-SAME: (ptr addrspace(5) byval(i32) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@skip_optnone
; CHECK-SAME: (ptr addrspace(5) byval(i32) [[VAL:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@skip_volatile
; CHECK-SAME: (ptr addrspace(5) byval(i32) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store volatile i32 0, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@skip_atomic
; CHECK-SAME: (ptr addrspace(5) byval(i32) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store atomic i32 0, ptr addrspace(5) [[VAL]] seq_cst, align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@skip_store_pointer_val
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store ptr addrspace(5) [[VAL]], ptr poison, align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@skip_store_gep
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr addrspace(5) [[VAL]], i32 1
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[GEP]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@skip_sret
; CHECK-SAME: (ptr addrspace(5) sret(i32) [[SRET:%.*]], ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store i32 1, ptr addrspace(5) [[SRET]], align 4
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_1_use.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_I32_1_USE:%.*]] zeroinitializer
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_1_use
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[VOID_ONE_OUT_ARG_I32_1_USE:%.*]] @void_one_out_arg_i32_1_use.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[VOID_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 0
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_1_use_align.body
; CHECK-SAME: (ptr addrspace(5) align 8 [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_I32_1_USE_ALIGN:%.*]] zeroinitializer
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_1_use_align
; CHECK-SAME: (ptr addrspace(5) align 8 [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[VOID_ONE_OUT_ARG_I32_1_USE_ALIGN:%.*]] @void_one_out_arg_i32_1_use_align.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[VOID_ONE_OUT_ARG_I32_1_USE_ALIGN]] [[TMP2]], 0
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 8
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_2_use.body
; CHECK-SAME: (i1 [[ARG0:%.*]], ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: br i1 [[ARG0]], label [[RET0:%.*]], label [[RET1:%.*]]
; CHECK: ret0:
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_I32_2_USE:%.*]] zeroinitializer
; CHECK: ret1:
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_I32_2_USE]] { i32 9 }
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_2_use
; CHECK-SAME: (i1 [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[VOID_ONE_OUT_ARG_I32_2_USE:%.*]] @void_one_out_arg_i32_2_use.body(i1 [[TMP0]], ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[VOID_ONE_OUT_ARG_I32_2_USE]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP1]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_2_stores.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_I32_2_STORES:%.*]] { i32 1 }
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_2_stores
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[VOID_ONE_OUT_ARG_I32_2_STORES:%.*]] @void_one_out_arg_i32_2_stores.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[VOID_ONE_OUT_ARG_I32_2_STORES]] [[TMP2]], 0
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_2_stores_clobber.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: call void @may.clobber()
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_I32_2_STORES_CLOBBER:%.*]] { i32 1 }
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_2_stores_clobber
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[VOID_ONE_OUT_ARG_I32_2_STORES_CLOBBER:%.*]] @void_one_out_arg_i32_2_stores_clobber.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[VOID_ONE_OUT_ARG_I32_2_STORES_CLOBBER]] [[TMP2]], 0
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_call_may_clobber
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: call void @may.clobber()
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_pre_call_may_clobber.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: call void @may.clobber()
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_I32_PRE_CALL_MAY_CLOBBER:%.*]] zeroinitializer
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_pre_call_may_clobber
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[VOID_ONE_OUT_ARG_I32_PRE_CALL_MAY_CLOBBER:%.*]] @void_one_out_arg_i32_pre_call_may_clobber.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[VOID_ONE_OUT_ARG_I32_PRE_CALL_MAY_CLOBBER]] [[TMP2]], 0
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_reload
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_i32_store_in_different_block
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(1) poison, align 4
; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: br label [[RET:%.*]]
; CHECK: ret:
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@unused_out_arg_one_branch
; CHECK-SAME: (i1 [[ARG0:%.*]], ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: br i1 [[ARG0]], label [[RET0:%.*]], label [[RET1:%.*]]
; CHECK: ret0:
; CHECK-NEXT: ret void
; CHECK: ret1:
; CHECK-NEXT: store i32 9, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_v2i32_1_use.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_V2I32_1_USE:%.*]] { <2 x i32> <i32 17, i32 9> }
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_v2i32_1_use
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[VOID_ONE_OUT_ARG_V2I32_1_USE:%.*]] @void_one_out_arg_v2i32_1_use.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[VOID_ONE_OUT_ARG_V2I32_1_USE]] [[TMP2]], 0
; CHECK-NEXT: store <2 x i32> [[TMP3]], ptr addrspace(5) [[TMP0]], align 8
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_struct_1_use.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[VOID_ONE_OUT_ARG_STRUCT_1_USE:%.*]] { [[STRUCT:%.*]] { i32 9, i8 99, float 4.000000e+00 } }
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_arg_struct_1_use
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[VOID_ONE_OUT_ARG_STRUCT_1_USE:%.*]] @void_one_out_arg_struct_1_use.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[VOID_ONE_OUT_ARG_STRUCT_1_USE]] [[TMP2]], 0
; CHECK-NEXT: store [[STRUCT:%.*]] [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@i32_one_out_arg_i32_1_use.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[I32_ONE_OUT_ARG_I32_1_USE:%.*]] { i32 9, i32 24 }
;
;
; CHECK-LABEL: define {{[^@]+}}@i32_one_out_arg_i32_1_use
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[I32_ONE_OUT_ARG_I32_1_USE:%.*]] @i32_one_out_arg_i32_1_use.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[I32_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 1
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[I32_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 0
; CHECK-NEXT: ret i32 [[TMP4]]
;
;
; CHECK-LABEL: define {{[^@]+}}@unused_different_type.body
; CHECK-SAME: (ptr addrspace(5) [[ARG0:%.*]], ptr addrspace(5) nocapture [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[UNUSED_DIFFERENT_TYPE:%.*]] { float 4.000000e+00 }
;
;
; CHECK-LABEL: define {{[^@]+}}@unused_different_type
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) nocapture [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[UNUSED_DIFFERENT_TYPE:%.*]] @unused_different_type.body(ptr addrspace(5) [[TMP0]], ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[UNUSED_DIFFERENT_TYPE]] [[TMP3]], 0
; CHECK-NEXT: store float [[TMP4]], ptr addrspace(5) [[TMP1]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@multiple_same_return_noalias.body
; CHECK-SAME: (ptr addrspace(5) noalias [[OUT0:%.*]], ptr addrspace(5) noalias [[OUT1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[MULTIPLE_SAME_RETURN_NOALIAS:%.*]] { i32 1, i32 2 }
;
;
; CHECK-LABEL: define {{[^@]+}}@multiple_same_return_noalias
; CHECK-SAME: (ptr addrspace(5) noalias [[TMP0:%.*]], ptr addrspace(5) noalias [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[MULTIPLE_SAME_RETURN_NOALIAS:%.*]] @multiple_same_return_noalias.body(ptr addrspace(5) poison, ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[MULTIPLE_SAME_RETURN_NOALIAS]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[MULTIPLE_SAME_RETURN_NOALIAS]] [[TMP3]], 1
; CHECK-NEXT: store i32 [[TMP5]], ptr addrspace(5) [[TMP1]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@multiple_same_return_mayalias.body
; CHECK-SAME: (ptr addrspace(5) [[OUT0:%.*]], ptr addrspace(5) [[OUT1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[MULTIPLE_SAME_RETURN_MAYALIAS:%.*]] { i32 2, i32 1 }
;
;
; CHECK-LABEL: define {{[^@]+}}@multiple_same_return_mayalias
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[MULTIPLE_SAME_RETURN_MAYALIAS:%.*]] @multiple_same_return_mayalias.body(ptr addrspace(5) poison, ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[MULTIPLE_SAME_RETURN_MAYALIAS]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[MULTIPLE_SAME_RETURN_MAYALIAS]] [[TMP3]], 1
; CHECK-NEXT: store i32 [[TMP5]], ptr addrspace(5) [[TMP1]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@multiple_same_return_mayalias_order.body
; CHECK-SAME: (ptr addrspace(5) [[OUT0:%.*]], ptr addrspace(5) [[OUT1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[MULTIPLE_SAME_RETURN_MAYALIAS_ORDER:%.*]] { i32 1, i32 2 }
;
;
; CHECK-LABEL: define {{[^@]+}}@multiple_same_return_mayalias_order
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[MULTIPLE_SAME_RETURN_MAYALIAS_ORDER:%.*]] @multiple_same_return_mayalias_order.body(ptr addrspace(5) poison, ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[MULTIPLE_SAME_RETURN_MAYALIAS_ORDER]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[MULTIPLE_SAME_RETURN_MAYALIAS_ORDER]] [[TMP3]], 1
; CHECK-NEXT: store i32 [[TMP5]], ptr addrspace(5) [[TMP1]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@store_in_entry_block
; CHECK-SAME: (i1 [[ARG0:%.*]], ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[VAL0:%.*]] = load i32, ptr addrspace(1) poison, align 4
; CHECK-NEXT: store i32 [[VAL0]], ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: br i1 [[ARG0]], label [[IF:%.*]], label [[ENDIF:%.*]]
; CHECK: if:
; CHECK-NEXT: [[VAL1:%.*]] = load i32, ptr addrspace(1) poison, align 4
; CHECK-NEXT: br label [[ENDIF]]
; CHECK: endif:
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[VAL1]], [[IF]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
;
; CHECK-LABEL: define {{[^@]+}}@i1_one_out_arg_i32_1_use.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[I1_ONE_OUT_ARG_I32_1_USE:%.*]] { i1 true, i32 24 }
;
;
; CHECK-LABEL: define {{[^@]+}}@i1_one_out_arg_i32_1_use
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[I1_ONE_OUT_ARG_I32_1_USE:%.*]] @i1_one_out_arg_i32_1_use.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[I1_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 1
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[I1_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 0
; CHECK-NEXT: ret i1 [[TMP4]]
;
;
; CHECK-LABEL: define {{[^@]+}}@i1_zeroext_one_out_arg_i32_1_use.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[I1_ZEROEXT_ONE_OUT_ARG_I32_1_USE:%.*]] { i1 true, i32 24 }
;
;
; CHECK-LABEL: define {{[^@]+}}@i1_zeroext_one_out_arg_i32_1_use
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[I1_ZEROEXT_ONE_OUT_ARG_I32_1_USE:%.*]] @i1_zeroext_one_out_arg_i32_1_use.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[I1_ZEROEXT_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 1
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[I1_ZEROEXT_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 0
; CHECK-NEXT: ret i1 [[TMP4]]
;
;
; CHECK-LABEL: define {{[^@]+}}@i1_signext_one_out_arg_i32_1_use.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[I1_SIGNEXT_ONE_OUT_ARG_I32_1_USE:%.*]] { i1 true, i32 24 }
;
;
; CHECK-LABEL: define {{[^@]+}}@i1_signext_one_out_arg_i32_1_use
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[I1_SIGNEXT_ONE_OUT_ARG_I32_1_USE:%.*]] @i1_signext_one_out_arg_i32_1_use.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[I1_SIGNEXT_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 1
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[I1_SIGNEXT_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 0
; CHECK-NEXT: ret i1 [[TMP4]]
;
;
; CHECK-LABEL: define {{[^@]+}}@p1i32_noalias_one_out_arg_i32_1_use.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[P1I32_NOALIAS_ONE_OUT_ARG_I32_1_USE:%.*]] { ptr addrspace(1) null, i32 24 }
;
;
; CHECK-LABEL: define {{[^@]+}}@p1i32_noalias_one_out_arg_i32_1_use
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[P1I32_NOALIAS_ONE_OUT_ARG_I32_1_USE:%.*]] @p1i32_noalias_one_out_arg_i32_1_use.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[P1I32_NOALIAS_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 1
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[P1I32_NOALIAS_ONE_OUT_ARG_I32_1_USE]] [[TMP2]], 0
; CHECK-NEXT: ret ptr addrspace(1) [[TMP4]]
;
;
; CHECK-LABEL: define {{[^@]+}}@void_one_out_non_private_arg_i32_1_use
; CHECK-SAME: (ptr addrspace(1) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store i32 0, ptr addrspace(1) [[VAL]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@func_ptr_type.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FUNC:%.*]] = load ptr, ptr poison, align 8
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[FUNC_PTR_TYPE:%.*]] poison, ptr [[FUNC]], 0
; CHECK-NEXT: ret [[FUNC_PTR_TYPE]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@func_ptr_type
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[FUNC_PTR_TYPE:%.*]] @func_ptr_type.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[FUNC_PTR_TYPE]] [[TMP2]], 0
; CHECK-NEXT: store ptr [[TMP3]], ptr addrspace(5) [[TMP0]], align 8
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_func_ptr_type.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FUNC:%.*]] = load ptr, ptr poison, align 8
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_FUNC_PTR_TYPE:%.*]] poison, ptr [[FUNC]], 0
; CHECK-NEXT: ret [[BITCAST_FUNC_PTR_TYPE]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_func_ptr_type
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[BITCAST_FUNC_PTR_TYPE:%.*]] @bitcast_func_ptr_type.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[BITCAST_FUNC_PTR_TYPE]] [[TMP2]], 0
; CHECK-NEXT: store ptr [[TMP3]], ptr addrspace(5) [[TMP0]], align 8
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@out_arg_small_array.body
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: ret [[OUT_ARG_SMALL_ARRAY:%.*]] { [4 x i32] [i32 0, i32 1, i32 2, i32 3] }
;
;
; CHECK-LABEL: define {{[^@]+}}@out_arg_small_array
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[OUT_ARG_SMALL_ARRAY:%.*]] @out_arg_small_array.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[OUT_ARG_SMALL_ARRAY]] [[TMP2]], 0
; CHECK-NEXT: store [4 x i32] [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@out_arg_large_array
; CHECK-SAME: (ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: store [17 x i32] zeroinitializer, ptr addrspace(5) [[VAL]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@num_regs_return_limit
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD:%.*]] = load volatile <16 x i32>, ptr addrspace(1) poison, align 64
; CHECK-NEXT: store i32 [[VAL]], ptr addrspace(5) [[OUT]], align 4
; CHECK-NEXT: ret <16 x i32> [[LOAD]]
;
;
; CHECK-LABEL: define {{[^@]+}}@num_regs_reach_limit.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD:%.*]] = load volatile [15 x i32], ptr addrspace(1) poison, align 4
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[NUM_REGS_REACH_LIMIT:%.*]] poison, [15 x i32] [[LOAD]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[NUM_REGS_REACH_LIMIT]] [[TMP1]], i32 [[VAL]], 1
; CHECK-NEXT: ret [[NUM_REGS_REACH_LIMIT]] [[TMP2]]
;
;
; CHECK-LABEL: define {{[^@]+}}@num_regs_reach_limit
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[NUM_REGS_REACH_LIMIT:%.*]] @num_regs_reach_limit.body(ptr addrspace(5) poison, i32 [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[NUM_REGS_REACH_LIMIT]] [[TMP3]], 1
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[NUM_REGS_REACH_LIMIT]] [[TMP3]], 0
; CHECK-NEXT: ret [15 x i32] [[TMP5]]
;
;
; CHECK-LABEL: define {{[^@]+}}@num_regs_reach_limit_leftover.body
; CHECK-SAME: (ptr addrspace(5) [[OUT0:%.*]], ptr addrspace(5) [[OUT1:%.*]], i32 [[VAL0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD0:%.*]] = load volatile [15 x i32], ptr addrspace(1) poison, align 4
; CHECK-NEXT: [[LOAD1:%.*]] = load volatile i32, ptr addrspace(1) poison, align 4
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[NUM_REGS_REACH_LIMIT_LEFTOVER:%.*]] poison, [15 x i32] [[LOAD0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[NUM_REGS_REACH_LIMIT_LEFTOVER]] [[TMP1]], i32 [[LOAD1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = insertvalue [[NUM_REGS_REACH_LIMIT_LEFTOVER]] [[TMP2]], i32 [[VAL0]], 2
; CHECK-NEXT: ret [[NUM_REGS_REACH_LIMIT_LEFTOVER]] [[TMP3]]
;
;
; CHECK-LABEL: define {{[^@]+}}@num_regs_reach_limit_leftover
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]], i32 [[TMP2:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP4:%.*]] = call [[NUM_REGS_REACH_LIMIT_LEFTOVER:%.*]] @num_regs_reach_limit_leftover.body(ptr addrspace(5) poison, ptr addrspace(5) poison, i32 [[TMP2]])
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[NUM_REGS_REACH_LIMIT_LEFTOVER]] [[TMP4]], 1
; CHECK-NEXT: store i32 [[TMP5]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: [[TMP6:%.*]] = extractvalue [[NUM_REGS_REACH_LIMIT_LEFTOVER]] [[TMP4]], 2
; CHECK-NEXT: store i32 [[TMP6]], ptr addrspace(5) [[TMP1]], align 4
; CHECK-NEXT: [[TMP7:%.*]] = extractvalue [[NUM_REGS_REACH_LIMIT_LEFTOVER]] [[TMP4]], 0
; CHECK-NEXT: ret [15 x i32] [[TMP7]]
;
;
; CHECK-LABEL: define {{[^@]+}}@preserve_debug_info.body
; CHECK-SAME: (i32 [[ARG0:%.*]], ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: call void @may.clobber(), !dbg [[DBG5:![0-9]+]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[PRESERVE_DEBUG_INFO:%.*]] poison, i32 [[ARG0]], 0, !dbg [[DBG11:![0-9]+]]
; CHECK-NEXT: ret [[PRESERVE_DEBUG_INFO]] [[TMP1]], !dbg [[DBG11]]
;
;
; CHECK-LABEL: define {{[^@]+}}@preserve_debug_info
; CHECK-SAME: (i32 [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR2]] !dbg [[DBG6:![0-9]+]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[PRESERVE_DEBUG_INFO:%.*]] @preserve_debug_info.body(i32 [[TMP0]], ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[PRESERVE_DEBUG_INFO]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP1]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@preserve_metadata.body
; CHECK-SAME: (i32 [[ARG0:%.*]], ptr addrspace(5) [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: call void @may.clobber()
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[PRESERVE_METADATA:%.*]] poison, i32 [[ARG0]], 0
; CHECK-NEXT: ret [[PRESERVE_METADATA]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@preserve_metadata
; CHECK-SAME: (i32 [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR2]] !kernel_arg_access_qual !12 {
; CHECK-NEXT: [[TMP3:%.*]] = call [[PRESERVE_METADATA:%.*]] @preserve_metadata.body(i32 [[TMP0]], ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[PRESERVE_METADATA]] [[TMP3]], 0
; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP1]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_v4i32_v3i32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD:%.*]] = load volatile <4 x i32>, ptr addrspace(1) poison, align 16
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_POINTER_V4I32_V3I32:%.*]] poison, <4 x i32> [[LOAD]], 0
; CHECK-NEXT: ret [[BITCAST_POINTER_V4I32_V3I32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_v4i32_v3i32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[BITCAST_POINTER_V4I32_V3I32:%.*]] @bitcast_pointer_v4i32_v3i32.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[BITCAST_POINTER_V4I32_V3I32]] [[TMP2]], 0
; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_v4i32_v3f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD:%.*]] = load volatile <4 x i32>, ptr addrspace(1) poison, align 16
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_POINTER_V4I32_V3F32:%.*]] poison, <4 x i32> [[LOAD]], 0
; CHECK-NEXT: ret [[BITCAST_POINTER_V4I32_V3F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_v4i32_v3f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[BITCAST_POINTER_V4I32_V3F32:%.*]] @bitcast_pointer_v4i32_v3f32.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[BITCAST_POINTER_V4I32_V3F32]] [[TMP2]], 0
; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_i32_f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(1) poison, align 4
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_POINTER_I32_F32:%.*]] poison, i32 [[LOAD]], 0
; CHECK-NEXT: ret [[BITCAST_POINTER_I32_F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_i32_f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[BITCAST_POINTER_I32_F32:%.*]] @bitcast_pointer_i32_f32.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[BITCAST_POINTER_I32_F32]] [[TMP2]], 0
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_i32_f16.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(1) poison, align 4
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_POINTER_I32_F16:%.*]] poison, i32 [[LOAD]], 0
; CHECK-NEXT: ret [[BITCAST_POINTER_I32_F16]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_i32_f16
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[BITCAST_POINTER_I32_F16:%.*]] @bitcast_pointer_i32_f16.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[BITCAST_POINTER_I32_F16]] [[TMP2]], 0
; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_f16_i32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[LOAD:%.*]] = load volatile half, ptr addrspace(1) poison, align 2
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_POINTER_F16_I32:%.*]] poison, half [[LOAD]], 0
; CHECK-NEXT: ret [[BITCAST_POINTER_F16_I32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_pointer_f16_i32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP2:%.*]] = call [[BITCAST_POINTER_F16_I32:%.*]] @bitcast_pointer_f16_i32.body(ptr addrspace(5) poison)
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[BITCAST_POINTER_F16_I32]] [[TMP2]], 0
; CHECK-NEXT: store half [[TMP3]], ptr addrspace(5) [[TMP0]], align 2
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_v3f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <3 x float> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x float> [[VALUE]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_V3F32_V3F32:%.*]] poison, <4 x float> [[EXTRACTVEC]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_V3F32_V3F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_v3f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <3 x float> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_V3F32_V3F32:%.*]] @bitcast_struct_v3f32_v3f32.body(ptr addrspace(5) poison, <3 x float> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_V3F32_V3F32]] [[TMP3]], 0
; CHECK-NEXT: store <4 x float> [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_v3i32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <3 x i32> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i32> [[VALUE]], <3 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_V3F32_V3I32:%.*]] poison, <4 x i32> [[EXTRACTVEC]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_V3F32_V3I32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_v3i32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <3 x i32> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_V3F32_V3I32:%.*]] @bitcast_struct_v3f32_v3i32.body(ptr addrspace(5) poison, <3 x i32> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_V3F32_V3I32]] [[TMP3]], 0
; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v4f32_v4f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <4 x float> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_V4F32_V4F32:%.*]] poison, <4 x float> [[VALUE]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_V4F32_V4F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v4f32_v4f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <4 x float> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_V4F32_V4F32:%.*]] @bitcast_struct_v4f32_v4f32.body(ptr addrspace(5) poison, <4 x float> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_V4F32_V4F32]] [[TMP3]], 0
; CHECK-NEXT: store <4 x float> [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_v4i32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <4 x i32> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_V3F32_V4I32:%.*]] poison, <4 x i32> [[VALUE]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_V3F32_V4I32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_v4i32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <4 x i32> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_V3F32_V4I32:%.*]] @bitcast_struct_v3f32_v4i32.body(ptr addrspace(5) poison, <4 x i32> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_V3F32_V4I32]] [[TMP3]], 0
; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v4f32_v3f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <3 x float> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x float> [[VALUE]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_V4F32_V3F32:%.*]] poison, <4 x float> [[EXTRACTVEC]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_V4F32_V3F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v4f32_v3f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <3 x float> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_V4F32_V3F32:%.*]] @bitcast_struct_v4f32_v3f32.body(ptr addrspace(5) poison, <3 x float> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_V4F32_V3F32]] [[TMP3]], 0
; CHECK-NEXT: store <4 x float> [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_v2f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <2 x float> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_V3F32_V2F32:%.*]] poison, <2 x float> [[VALUE]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_V3F32_V2F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_v2f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <2 x float> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_V3F32_V2F32:%.*]] @bitcast_struct_v3f32_v2f32.body(ptr addrspace(5) poison, <2 x float> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_V3F32_V2F32]] [[TMP3]], 0
; CHECK-NEXT: store <2 x float> [[TMP4]], ptr addrspace(5) [[TMP0]], align 8
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_f32_v3f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <3 x float> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x float> [[VALUE]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_V3F32_F32_V3F32:%.*]] poison, <4 x float> [[EXTRACTVEC]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_V3F32_F32_V3F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_f32_v3f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <3 x float> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_V3F32_F32_V3F32:%.*]] @bitcast_struct_v3f32_f32_v3f32.body(ptr addrspace(5) poison, <3 x float> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_V3F32_F32_V3F32]] [[TMP3]], 0
; CHECK-NEXT: store <4 x float> [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_f32_v4f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <4 x float> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_V3F32_F32_V4F32:%.*]] poison, <4 x float> [[VALUE]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_V3F32_F32_V4F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_v3f32_f32_v4f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <4 x float> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_V3F32_F32_V4F32:%.*]] @bitcast_struct_v3f32_f32_v4f32.body(ptr addrspace(5) poison, <4 x float> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_V3F32_F32_V4F32]] [[TMP3]], 0
; CHECK-NEXT: store <4 x float> [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_i128_v4f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], <4 x float> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_STRUCT_I128_V4F32:%.*]] poison, <4 x float> [[VALUE]], 0
; CHECK-NEXT: ret [[BITCAST_STRUCT_I128_V4F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_struct_i128_v4f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], <4 x float> [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_STRUCT_I128_V4F32:%.*]] @bitcast_struct_i128_v4f32.body(ptr addrspace(5) poison, <4 x float> [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_STRUCT_I128_V4F32]] [[TMP3]], 0
; CHECK-NEXT: store <4 x float> [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_array_v4i32_v4f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], [4 x float] [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_ARRAY_V4I32_V4F32:%.*]] poison, [4 x float] [[VALUE]], 0
; CHECK-NEXT: ret [[BITCAST_ARRAY_V4I32_V4F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_array_v4i32_v4f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], [4 x float] [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_ARRAY_V4I32_V4F32:%.*]] @bitcast_array_v4i32_v4f32.body(ptr addrspace(5) poison, [4 x float] [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_ARRAY_V4I32_V4F32]] [[TMP3]], 0
; CHECK-NEXT: store [4 x float] [[TMP4]], ptr addrspace(5) [[TMP0]], align 4
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@multi_return_bitcast_struct_v3f32_v3f32.body
; CHECK-SAME: (i1 [[COND:%.*]], ptr addrspace(5) [[OUT:%.*]], <3 x float> [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[COND]], label [[RET0:%.*]], label [[RET1:%.*]]
; CHECK: ret0:
; CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x float> [[VALUE]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison>
; CHECK-NEXT: [[TMP0:%.*]] = insertvalue [[MULTI_RETURN_BITCAST_STRUCT_V3F32_V3F32:%.*]] poison, <4 x float> [[EXTRACTVEC]], 0
; CHECK-NEXT: ret [[MULTI_RETURN_BITCAST_STRUCT_V3F32_V3F32]] [[TMP0]]
; CHECK: ret1:
; CHECK-NEXT: [[LOAD:%.*]] = load <4 x float>, ptr addrspace(1) poison, align 16
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[MULTI_RETURN_BITCAST_STRUCT_V3F32_V3F32]] poison, <4 x float> [[LOAD]], 0
; CHECK-NEXT: ret [[MULTI_RETURN_BITCAST_STRUCT_V3F32_V3F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@multi_return_bitcast_struct_v3f32_v3f32
; CHECK-SAME: (i1 [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]], <3 x float> [[TMP2:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP4:%.*]] = call [[MULTI_RETURN_BITCAST_STRUCT_V3F32_V3F32:%.*]] @multi_return_bitcast_struct_v3f32_v3f32.body(i1 [[TMP0]], ptr addrspace(5) poison, <3 x float> [[TMP2]])
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[MULTI_RETURN_BITCAST_STRUCT_V3F32_V3F32]] [[TMP4]], 0
; CHECK-NEXT: store <4 x float> [[TMP5]], ptr addrspace(5) [[TMP1]], align 16
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_v3f32_struct_v3f32.body
; CHECK-SAME: (ptr addrspace(5) [[OUT:%.*]], [[STRUCT_V3F32:%.*]] [[VALUE:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[BITCAST_V3F32_STRUCT_V3F32:%.*]] poison, [[STRUCT_V3F32]] [[VALUE]], 0
; CHECK-NEXT: ret [[BITCAST_V3F32_STRUCT_V3F32]] [[TMP1]]
;
;
; CHECK-LABEL: define {{[^@]+}}@bitcast_v3f32_struct_v3f32
; CHECK-SAME: (ptr addrspace(5) [[TMP0:%.*]], [[STRUCT_V3F32:%.*]] [[TMP1:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[TMP3:%.*]] = call [[BITCAST_V3F32_STRUCT_V3F32:%.*]] @bitcast_v3f32_struct_v3f32.body(ptr addrspace(5) poison, [[STRUCT_V3F32]] [[TMP1]])
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[BITCAST_V3F32_STRUCT_V3F32]] [[TMP3]], 0
; CHECK-NEXT: store [[STRUCT_V3F32]] [[TMP4]], ptr addrspace(5) [[TMP0]], align 16
; CHECK-NEXT: ret void
;