Files
clang-p2996/clang/test/CodeGen/nofpclass.c
Nikita Popov 90ba33099c [InstCombine] Canonicalize constant GEPs to i8 source element type (#68882)
This patch canonicalizes getelementptr instructions with constant
indices to use the `i8` source element type. This makes it easier for
optimizations to recognize that two GEPs are identical, because they
don't need to see past many different ways to express the same offset.

This is a first step towards
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699.
This is limited to constant GEPs only for now, as they have a clear
canonical form, while we're not yet sure how exactly to deal with
variable indices.

The test llvm/test/Transforms/PhaseOrdering/switch_with_geps.ll gives
two representative examples of the kind of optimization improvement we
expect from this change. In the first test SimplifyCFG can now realize
that all switch branches are actually the same. In the second test it
can convert it into simple arithmetic. These are representative of
common optimization failures we see in Rust.

Fixes https://github.com/llvm/llvm-project/issues/69841.
2024-01-24 15:25:29 +01:00

1438 lines
118 KiB
C

// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 2
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -ffinite-math-only -emit-llvm -o - %s | FileCheck -check-prefixes=CFINITEONLY %s
// RUN: %clang_cc1 -x cl -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -cl-finite-math-only -emit-llvm -o - %s | FileCheck -check-prefixes=CLFINITEONLY %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-nans -emit-llvm -o - %s | FileCheck -check-prefixes=NONANS %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -menable-no-infs -emit-llvm -o - %s | FileCheck -check-prefixes=NOINFS %s
// XUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -fsignaling-nans -emit-llvm -o - %s | FileCheck -check-prefixes=SNANS %s
// XUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +avx -fenable-matrix -fno-signaling-nans -emit-llvm -o - %s | FileCheck -check-prefixes=NO-SNANS %s
#ifdef __OPENCL_C_VERSION__
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
#endif
typedef float float1 __attribute__((ext_vector_type(1)));
typedef float float2 __attribute__((ext_vector_type(2)));
typedef _Float16 half2 __attribute__((ext_vector_type(2)));
typedef double double2 __attribute__((ext_vector_type(2)));
typedef double dx5x5_t __attribute__((matrix_type(5, 5)));
extern float extern_func(float, double, _Float16);
extern float2 extern_func_vec(float2, double2, half2);
extern _Complex float extern_complex(_Complex float, _Complex double, _Complex _Float16);
extern float variadic(float, ...);
extern dx5x5_t extern_matrix(dx5x5_t);
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @defined_func_f32
// CFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[A:%.*]], float noundef nofpclass(nan inf) [[B:%.*]], float noundef nofpclass(nan inf) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// CFINITEONLY-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// CFINITEONLY-NEXT: [[C_ADDR:%.*]] = alloca float, align 4
// CFINITEONLY-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// CFINITEONLY-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// CFINITEONLY-NEXT: store float [[C]], ptr [[C_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP1:%.*]] = load float, ptr [[B_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP2:%.*]] = load float, ptr [[C_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP3:%.*]] = call nnan ninf float @llvm.fma.f32(float [[TMP0]], float [[TMP1]], float [[TMP2]])
// CFINITEONLY-NEXT: [[ADD:%.*]] = fadd nnan ninf float [[TMP3]], 4.000000e+00
// CFINITEONLY-NEXT: ret float [[ADD]]
//
// CLFINITEONLY: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @defined_func_f32
// CLFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[A:%.*]], float noundef nofpclass(nan inf) [[B:%.*]], float noundef nofpclass(nan inf) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf float @llvm.fma.f32(float [[A]], float [[B]], float [[C]])
// CLFINITEONLY-NEXT: [[ADD:%.*]] = fadd nnan ninf float [[TMP0]], 4.000000e+00
// CLFINITEONLY-NEXT: ret float [[ADD]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) float @defined_func_f32
// NONANS-SAME: (float noundef nofpclass(nan) [[A:%.*]], float noundef nofpclass(nan) [[B:%.*]], float noundef nofpclass(nan) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// NONANS-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// NONANS-NEXT: [[C_ADDR:%.*]] = alloca float, align 4
// NONANS-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// NONANS-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// NONANS-NEXT: store float [[C]], ptr [[C_ADDR]], align 4
// NONANS-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// NONANS-NEXT: [[TMP1:%.*]] = load float, ptr [[B_ADDR]], align 4
// NONANS-NEXT: [[TMP2:%.*]] = load float, ptr [[C_ADDR]], align 4
// NONANS-NEXT: [[TMP3:%.*]] = call nnan float @llvm.fma.f32(float [[TMP0]], float [[TMP1]], float [[TMP2]])
// NONANS-NEXT: [[ADD:%.*]] = fadd nnan float [[TMP3]], 4.000000e+00
// NONANS-NEXT: ret float [[ADD]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) float @defined_func_f32
// NOINFS-SAME: (float noundef nofpclass(inf) [[A:%.*]], float noundef nofpclass(inf) [[B:%.*]], float noundef nofpclass(inf) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// NOINFS-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// NOINFS-NEXT: [[C_ADDR:%.*]] = alloca float, align 4
// NOINFS-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// NOINFS-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// NOINFS-NEXT: store float [[C]], ptr [[C_ADDR]], align 4
// NOINFS-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// NOINFS-NEXT: [[TMP1:%.*]] = load float, ptr [[B_ADDR]], align 4
// NOINFS-NEXT: [[TMP2:%.*]] = load float, ptr [[C_ADDR]], align 4
// NOINFS-NEXT: [[TMP3:%.*]] = call ninf float @llvm.fma.f32(float [[TMP0]], float [[TMP1]], float [[TMP2]])
// NOINFS-NEXT: [[ADD:%.*]] = fadd ninf float [[TMP3]], 4.000000e+00
// NOINFS-NEXT: ret float [[ADD]]
//
float defined_func_f32(float a, float b, float c) {
return __builtin_fmaf(a, b, c) + 4.0f;
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <2 x double> @defined_func_v2f64
// CFINITEONLY-SAME: (<2 x double> noundef nofpclass(nan inf) [[A:%.*]], <2 x double> noundef nofpclass(nan inf) [[B:%.*]], <2 x double> noundef nofpclass(nan inf) [[C:%.*]]) #[[ATTR2:[0-9]+]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[A_ADDR:%.*]] = alloca <2 x double>, align 16
// CFINITEONLY-NEXT: [[B_ADDR:%.*]] = alloca <2 x double>, align 16
// CFINITEONLY-NEXT: [[C_ADDR:%.*]] = alloca <2 x double>, align 16
// CFINITEONLY-NEXT: store <2 x double> [[A]], ptr [[A_ADDR]], align 16
// CFINITEONLY-NEXT: store <2 x double> [[B]], ptr [[B_ADDR]], align 16
// CFINITEONLY-NEXT: store <2 x double> [[C]], ptr [[C_ADDR]], align 16
// CFINITEONLY-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[A_ADDR]], align 16
// CFINITEONLY-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[B_ADDR]], align 16
// CFINITEONLY-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[C_ADDR]], align 16
// CFINITEONLY-NEXT: [[TMP3:%.*]] = call nnan ninf <2 x double> @llvm.fma.v2f64(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]])
// CFINITEONLY-NEXT: [[ADD:%.*]] = fadd nnan ninf <2 x double> [[TMP3]], <double 4.000000e+00, double 4.000000e+00>
// CFINITEONLY-NEXT: ret <2 x double> [[ADD]]
//
// CLFINITEONLY: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <2 x double> @defined_func_v2f64
// CLFINITEONLY-SAME: (<2 x double> noundef nofpclass(nan inf) [[A:%.*]], <2 x double> noundef nofpclass(nan inf) [[B:%.*]], <2 x double> noundef nofpclass(nan inf) [[C:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[TMP0:%.*]] = tail call nnan ninf <2 x double> @llvm.fma.v2f64(<2 x double> [[A]], <2 x double> [[B]], <2 x double> [[C]])
// CLFINITEONLY-NEXT: [[ADD:%.*]] = fadd nnan ninf <2 x double> [[TMP0]], <double 4.000000e+00, double 4.000000e+00>
// CLFINITEONLY-NEXT: ret <2 x double> [[ADD]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) <2 x double> @defined_func_v2f64
// NONANS-SAME: (<2 x double> noundef nofpclass(nan) [[A:%.*]], <2 x double> noundef nofpclass(nan) [[B:%.*]], <2 x double> noundef nofpclass(nan) [[C:%.*]]) #[[ATTR2:[0-9]+]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[A_ADDR:%.*]] = alloca <2 x double>, align 16
// NONANS-NEXT: [[B_ADDR:%.*]] = alloca <2 x double>, align 16
// NONANS-NEXT: [[C_ADDR:%.*]] = alloca <2 x double>, align 16
// NONANS-NEXT: store <2 x double> [[A]], ptr [[A_ADDR]], align 16
// NONANS-NEXT: store <2 x double> [[B]], ptr [[B_ADDR]], align 16
// NONANS-NEXT: store <2 x double> [[C]], ptr [[C_ADDR]], align 16
// NONANS-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[A_ADDR]], align 16
// NONANS-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[B_ADDR]], align 16
// NONANS-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[C_ADDR]], align 16
// NONANS-NEXT: [[TMP3:%.*]] = call nnan <2 x double> @llvm.fma.v2f64(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]])
// NONANS-NEXT: [[ADD:%.*]] = fadd nnan <2 x double> [[TMP3]], <double 4.000000e+00, double 4.000000e+00>
// NONANS-NEXT: ret <2 x double> [[ADD]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) <2 x double> @defined_func_v2f64
// NOINFS-SAME: (<2 x double> noundef nofpclass(inf) [[A:%.*]], <2 x double> noundef nofpclass(inf) [[B:%.*]], <2 x double> noundef nofpclass(inf) [[C:%.*]]) #[[ATTR2:[0-9]+]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[A_ADDR:%.*]] = alloca <2 x double>, align 16
// NOINFS-NEXT: [[B_ADDR:%.*]] = alloca <2 x double>, align 16
// NOINFS-NEXT: [[C_ADDR:%.*]] = alloca <2 x double>, align 16
// NOINFS-NEXT: store <2 x double> [[A]], ptr [[A_ADDR]], align 16
// NOINFS-NEXT: store <2 x double> [[B]], ptr [[B_ADDR]], align 16
// NOINFS-NEXT: store <2 x double> [[C]], ptr [[C_ADDR]], align 16
// NOINFS-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[A_ADDR]], align 16
// NOINFS-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[B_ADDR]], align 16
// NOINFS-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[C_ADDR]], align 16
// NOINFS-NEXT: [[TMP3:%.*]] = call ninf <2 x double> @llvm.fma.v2f64(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]])
// NOINFS-NEXT: [[ADD:%.*]] = fadd ninf <2 x double> [[TMP3]], <double 4.000000e+00, double 4.000000e+00>
// NOINFS-NEXT: ret <2 x double> [[ADD]]
//
double2 defined_func_v2f64(double2 a, double2 b, double2 c) {
return __builtin_elementwise_fma(a, b, c) + 4.0;
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_extern_func
// CFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[A:%.*]], double noundef nofpclass(nan inf) [[B:%.*]], half noundef nofpclass(nan inf) [[C:%.*]]) #[[ATTR0]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// CFINITEONLY-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// CFINITEONLY-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
// CFINITEONLY-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// CFINITEONLY-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// CFINITEONLY-NEXT: store half [[C]], ptr [[C_ADDR]], align 2
// CFINITEONLY-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP1:%.*]] = load double, ptr [[B_ADDR]], align 8
// CFINITEONLY-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2
// CFINITEONLY-NEXT: [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) float @extern_func(float noundef nofpclass(nan inf) [[TMP0]], double noundef nofpclass(nan inf) [[TMP1]], half noundef nofpclass(nan inf) [[TMP2]])
// CFINITEONLY-NEXT: ret float [[CALL]]
//
// CLFINITEONLY: Function Attrs: convergent norecurse nounwind
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_extern_func
// CLFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[A:%.*]], double noundef nofpclass(nan inf) [[B:%.*]], half noundef nofpclass(nan inf) [[C:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float @extern_func(float noundef nofpclass(nan inf) [[A]], double noundef nofpclass(nan inf) [[B]], half noundef nofpclass(nan inf) [[C]]) #[[ATTR10:[0-9]+]]
// CLFINITEONLY-NEXT: ret float [[CALL]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) float @call_extern_func
// NONANS-SAME: (float noundef nofpclass(nan) [[A:%.*]], double noundef nofpclass(nan) [[B:%.*]], half noundef nofpclass(nan) [[C:%.*]]) #[[ATTR0]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// NONANS-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// NONANS-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
// NONANS-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// NONANS-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// NONANS-NEXT: store half [[C]], ptr [[C_ADDR]], align 2
// NONANS-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// NONANS-NEXT: [[TMP1:%.*]] = load double, ptr [[B_ADDR]], align 8
// NONANS-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2
// NONANS-NEXT: [[CALL:%.*]] = call nnan nofpclass(nan) float @extern_func(float noundef nofpclass(nan) [[TMP0]], double noundef nofpclass(nan) [[TMP1]], half noundef nofpclass(nan) [[TMP2]])
// NONANS-NEXT: ret float [[CALL]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) float @call_extern_func
// NOINFS-SAME: (float noundef nofpclass(inf) [[A:%.*]], double noundef nofpclass(inf) [[B:%.*]], half noundef nofpclass(inf) [[C:%.*]]) #[[ATTR0]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// NOINFS-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// NOINFS-NEXT: [[C_ADDR:%.*]] = alloca half, align 2
// NOINFS-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// NOINFS-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// NOINFS-NEXT: store half [[C]], ptr [[C_ADDR]], align 2
// NOINFS-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// NOINFS-NEXT: [[TMP1:%.*]] = load double, ptr [[B_ADDR]], align 8
// NOINFS-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2
// NOINFS-NEXT: [[CALL:%.*]] = call ninf nofpclass(inf) float @extern_func(float noundef nofpclass(inf) [[TMP0]], double noundef nofpclass(inf) [[TMP1]], half noundef nofpclass(inf) [[TMP2]])
// NOINFS-NEXT: ret float [[CALL]]
//
float call_extern_func(float a, double b, _Float16 c) {
return extern_func(a, b, c);
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) double @call_extern_func_vec
// CFINITEONLY-SAME: (double noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) #[[ATTR2]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[RETVAL:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[A:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[C:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[A_ADDR:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[B_ADDR:%.*]] = alloca <2 x double>, align 16
// CFINITEONLY-NEXT: [[C_ADDR:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[COERCE4:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: store double [[A_COERCE]], ptr [[A]], align 8
// CFINITEONLY-NEXT: [[A1:%.*]] = load <2 x float>, ptr [[A]], align 8
// CFINITEONLY-NEXT: store i32 [[C_COERCE]], ptr [[C]], align 4
// CFINITEONLY-NEXT: [[C2:%.*]] = load <2 x half>, ptr [[C]], align 4
// CFINITEONLY-NEXT: store <2 x float> [[A1]], ptr [[A_ADDR]], align 8
// CFINITEONLY-NEXT: store <2 x double> [[B]], ptr [[B_ADDR]], align 16
// CFINITEONLY-NEXT: store <2 x half> [[C2]], ptr [[C_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[A_ADDR]], align 8
// CFINITEONLY-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[B_ADDR]], align 16
// CFINITEONLY-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[C_ADDR]], align 4
// CFINITEONLY-NEXT: store <2 x float> [[TMP0]], ptr [[COERCE]], align 8
// CFINITEONLY-NEXT: [[TMP3:%.*]] = load double, ptr [[COERCE]], align 8
// CFINITEONLY-NEXT: store <2 x half> [[TMP2]], ptr [[COERCE3]], align 4
// CFINITEONLY-NEXT: [[TMP4:%.*]] = load i32, ptr [[COERCE3]], align 4
// CFINITEONLY-NEXT: [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) double @extern_func_vec(double noundef nofpclass(nan inf) [[TMP3]], <2 x double> noundef nofpclass(nan inf) [[TMP1]], i32 noundef [[TMP4]])
// CFINITEONLY-NEXT: store double [[CALL]], ptr [[COERCE4]], align 8
// CFINITEONLY-NEXT: [[TMP5:%.*]] = load <2 x float>, ptr [[COERCE4]], align 8
// CFINITEONLY-NEXT: store <2 x float> [[TMP5]], ptr [[RETVAL]], align 8
// CFINITEONLY-NEXT: [[TMP6:%.*]] = load double, ptr [[RETVAL]], align 8
// CFINITEONLY-NEXT: ret double [[TMP6]]
//
// CLFINITEONLY: Function Attrs: convergent norecurse nounwind
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) double @call_extern_func_vec
// CLFINITEONLY-SAME: (double noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) double @extern_func_vec(double noundef nofpclass(nan inf) [[A_COERCE]], <2 x double> noundef nofpclass(nan inf) [[B]], i32 noundef [[C_COERCE]]) #[[ATTR10]]
// CLFINITEONLY-NEXT: ret double [[CALL]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) double @call_extern_func_vec
// NONANS-SAME: (double noundef nofpclass(nan) [[A_COERCE:%.*]], <2 x double> noundef nofpclass(nan) [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) #[[ATTR2]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[RETVAL:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[A:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[C:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[A_ADDR:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[B_ADDR:%.*]] = alloca <2 x double>, align 16
// NONANS-NEXT: [[C_ADDR:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[COERCE4:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: store double [[A_COERCE]], ptr [[A]], align 8
// NONANS-NEXT: [[A1:%.*]] = load <2 x float>, ptr [[A]], align 8
// NONANS-NEXT: store i32 [[C_COERCE]], ptr [[C]], align 4
// NONANS-NEXT: [[C2:%.*]] = load <2 x half>, ptr [[C]], align 4
// NONANS-NEXT: store <2 x float> [[A1]], ptr [[A_ADDR]], align 8
// NONANS-NEXT: store <2 x double> [[B]], ptr [[B_ADDR]], align 16
// NONANS-NEXT: store <2 x half> [[C2]], ptr [[C_ADDR]], align 4
// NONANS-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[A_ADDR]], align 8
// NONANS-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[B_ADDR]], align 16
// NONANS-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[C_ADDR]], align 4
// NONANS-NEXT: store <2 x float> [[TMP0]], ptr [[COERCE]], align 8
// NONANS-NEXT: [[TMP3:%.*]] = load double, ptr [[COERCE]], align 8
// NONANS-NEXT: store <2 x half> [[TMP2]], ptr [[COERCE3]], align 4
// NONANS-NEXT: [[TMP4:%.*]] = load i32, ptr [[COERCE3]], align 4
// NONANS-NEXT: [[CALL:%.*]] = call nnan nofpclass(nan) double @extern_func_vec(double noundef nofpclass(nan) [[TMP3]], <2 x double> noundef nofpclass(nan) [[TMP1]], i32 noundef [[TMP4]])
// NONANS-NEXT: store double [[CALL]], ptr [[COERCE4]], align 8
// NONANS-NEXT: [[TMP5:%.*]] = load <2 x float>, ptr [[COERCE4]], align 8
// NONANS-NEXT: store <2 x float> [[TMP5]], ptr [[RETVAL]], align 8
// NONANS-NEXT: [[TMP6:%.*]] = load double, ptr [[RETVAL]], align 8
// NONANS-NEXT: ret double [[TMP6]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) double @call_extern_func_vec
// NOINFS-SAME: (double noundef nofpclass(inf) [[A_COERCE:%.*]], <2 x double> noundef nofpclass(inf) [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) #[[ATTR2]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[RETVAL:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[A:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[C:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[A_ADDR:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[B_ADDR:%.*]] = alloca <2 x double>, align 16
// NOINFS-NEXT: [[C_ADDR:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[COERCE4:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: store double [[A_COERCE]], ptr [[A]], align 8
// NOINFS-NEXT: [[A1:%.*]] = load <2 x float>, ptr [[A]], align 8
// NOINFS-NEXT: store i32 [[C_COERCE]], ptr [[C]], align 4
// NOINFS-NEXT: [[C2:%.*]] = load <2 x half>, ptr [[C]], align 4
// NOINFS-NEXT: store <2 x float> [[A1]], ptr [[A_ADDR]], align 8
// NOINFS-NEXT: store <2 x double> [[B]], ptr [[B_ADDR]], align 16
// NOINFS-NEXT: store <2 x half> [[C2]], ptr [[C_ADDR]], align 4
// NOINFS-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[A_ADDR]], align 8
// NOINFS-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[B_ADDR]], align 16
// NOINFS-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[C_ADDR]], align 4
// NOINFS-NEXT: store <2 x float> [[TMP0]], ptr [[COERCE]], align 8
// NOINFS-NEXT: [[TMP3:%.*]] = load double, ptr [[COERCE]], align 8
// NOINFS-NEXT: store <2 x half> [[TMP2]], ptr [[COERCE3]], align 4
// NOINFS-NEXT: [[TMP4:%.*]] = load i32, ptr [[COERCE3]], align 4
// NOINFS-NEXT: [[CALL:%.*]] = call ninf nofpclass(inf) double @extern_func_vec(double noundef nofpclass(inf) [[TMP3]], <2 x double> noundef nofpclass(inf) [[TMP1]], i32 noundef [[TMP4]])
// NOINFS-NEXT: store double [[CALL]], ptr [[COERCE4]], align 8
// NOINFS-NEXT: [[TMP5:%.*]] = load <2 x float>, ptr [[COERCE4]], align 8
// NOINFS-NEXT: store <2 x float> [[TMP5]], ptr [[RETVAL]], align 8
// NOINFS-NEXT: [[TMP6:%.*]] = load double, ptr [[RETVAL]], align 8
// NOINFS-NEXT: ret double [[TMP6]]
//
float2 call_extern_func_vec(float2 a, double2 b, half2 c) {
return extern_func_vec(a, b, c);
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <2 x float> @defined_complex_func
// CFINITEONLY-SAME: (<2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR4:[0-9]+]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: [[B:%.*]] = alloca { double, double }, align 8
// CFINITEONLY-NEXT: [[C:%.*]] = alloca { half, half }, align 2
// CFINITEONLY-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: [[COERCE1:%.*]] = alloca { double, double }, align 8
// CFINITEONLY-NEXT: [[COERCE2:%.*]] = alloca { half, half }, align 2
// CFINITEONLY-NEXT: [[COERCE3:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// CFINITEONLY-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0
// CFINITEONLY-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
// CFINITEONLY-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1
// CFINITEONLY-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
// CFINITEONLY-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2
// CFINITEONLY-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0
// CFINITEONLY-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// CFINITEONLY-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1
// CFINITEONLY-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// CFINITEONLY-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0
// CFINITEONLY-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
// CFINITEONLY-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1
// CFINITEONLY-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
// CFINITEONLY-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// CFINITEONLY-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
// CFINITEONLY-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// CFINITEONLY-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
// CFINITEONLY-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1
// CFINITEONLY-NEXT: store float [[A_REAL]], ptr [[COERCE_REALP]], align 4
// CFINITEONLY-NEXT: store float [[A_IMAG]], ptr [[COERCE_IMAGP]], align 4
// CFINITEONLY-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr [[COERCE]], align 4
// CFINITEONLY-NEXT: [[COERCE1_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE1_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 1
// CFINITEONLY-NEXT: store double [[B_REAL]], ptr [[COERCE1_REALP]], align 8
// CFINITEONLY-NEXT: store double [[B_IMAG]], ptr [[COERCE1_IMAGP]], align 8
// CFINITEONLY-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 0
// CFINITEONLY-NEXT: [[TMP4:%.*]] = load double, ptr [[TMP3]], align 8
// CFINITEONLY-NEXT: [[TMP5:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 1
// CFINITEONLY-NEXT: [[TMP6:%.*]] = load double, ptr [[TMP5]], align 8
// CFINITEONLY-NEXT: [[COERCE2_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE2]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE2_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE2]], i32 0, i32 1
// CFINITEONLY-NEXT: store half [[C_REAL]], ptr [[COERCE2_REALP]], align 2
// CFINITEONLY-NEXT: store half [[C_IMAG]], ptr [[COERCE2_IMAGP]], align 2
// CFINITEONLY-NEXT: [[TMP7:%.*]] = load <2 x half>, ptr [[COERCE2]], align 2
// CFINITEONLY-NEXT: [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) <2 x float> @extern_complex(<2 x float> noundef nofpclass(nan inf) [[TMP2]], double noundef nofpclass(nan inf) [[TMP4]], double noundef nofpclass(nan inf) [[TMP6]], <2 x half> noundef nofpclass(nan inf) [[TMP7]])
// CFINITEONLY-NEXT: store <2 x float> [[CALL]], ptr [[COERCE3]], align 4
// CFINITEONLY-NEXT: [[COERCE3_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE3]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE3_REAL:%.*]] = load float, ptr [[COERCE3_REALP]], align 4
// CFINITEONLY-NEXT: [[COERCE3_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE3]], i32 0, i32 1
// CFINITEONLY-NEXT: [[COERCE3_IMAG:%.*]] = load float, ptr [[COERCE3_IMAGP]], align 4
// CFINITEONLY-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0
// CFINITEONLY-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1
// CFINITEONLY-NEXT: store float [[COERCE3_REAL]], ptr [[RETVAL_REALP]], align 4
// CFINITEONLY-NEXT: store float [[COERCE3_IMAG]], ptr [[RETVAL_IMAGP]], align 4
// CFINITEONLY-NEXT: [[TMP8:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// CFINITEONLY-NEXT: ret <2 x float> [[TMP8]]
//
// CLFINITEONLY: Function Attrs: convergent norecurse nounwind
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <2 x float> @defined_complex_func
// CLFINITEONLY-SAME: (<2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) local_unnamed_addr #[[ATTR6:[0-9]+]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <2 x float> @extern_complex(<2 x float> noundef nofpclass(nan inf) [[A_COERCE]], double noundef nofpclass(nan inf) [[B_COERCE0]], double noundef nofpclass(nan inf) [[B_COERCE1]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE]]) #[[ATTR10]]
// CLFINITEONLY-NEXT: ret <2 x float> [[CALL]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) <2 x float> @defined_complex_func
// NONANS-SAME: (<2 x float> noundef nofpclass(nan) [[A_COERCE:%.*]], double noundef nofpclass(nan) [[B_COERCE0:%.*]], double noundef nofpclass(nan) [[B_COERCE1:%.*]], <2 x half> noundef nofpclass(nan) [[C_COERCE:%.*]]) #[[ATTR4:[0-9]+]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: [[B:%.*]] = alloca { double, double }, align 8
// NONANS-NEXT: [[C:%.*]] = alloca { half, half }, align 2
// NONANS-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: [[COERCE1:%.*]] = alloca { double, double }, align 8
// NONANS-NEXT: [[COERCE2:%.*]] = alloca { half, half }, align 2
// NONANS-NEXT: [[COERCE3:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// NONANS-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0
// NONANS-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
// NONANS-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1
// NONANS-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
// NONANS-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2
// NONANS-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0
// NONANS-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// NONANS-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1
// NONANS-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// NONANS-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0
// NONANS-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
// NONANS-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1
// NONANS-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
// NONANS-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// NONANS-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
// NONANS-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// NONANS-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
// NONANS-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0
// NONANS-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1
// NONANS-NEXT: store float [[A_REAL]], ptr [[COERCE_REALP]], align 4
// NONANS-NEXT: store float [[A_IMAG]], ptr [[COERCE_IMAGP]], align 4
// NONANS-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr [[COERCE]], align 4
// NONANS-NEXT: [[COERCE1_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 0
// NONANS-NEXT: [[COERCE1_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 1
// NONANS-NEXT: store double [[B_REAL]], ptr [[COERCE1_REALP]], align 8
// NONANS-NEXT: store double [[B_IMAG]], ptr [[COERCE1_IMAGP]], align 8
// NONANS-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 0
// NONANS-NEXT: [[TMP4:%.*]] = load double, ptr [[TMP3]], align 8
// NONANS-NEXT: [[TMP5:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 1
// NONANS-NEXT: [[TMP6:%.*]] = load double, ptr [[TMP5]], align 8
// NONANS-NEXT: [[COERCE2_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE2]], i32 0, i32 0
// NONANS-NEXT: [[COERCE2_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE2]], i32 0, i32 1
// NONANS-NEXT: store half [[C_REAL]], ptr [[COERCE2_REALP]], align 2
// NONANS-NEXT: store half [[C_IMAG]], ptr [[COERCE2_IMAGP]], align 2
// NONANS-NEXT: [[TMP7:%.*]] = load <2 x half>, ptr [[COERCE2]], align 2
// NONANS-NEXT: [[CALL:%.*]] = call nnan nofpclass(nan) <2 x float> @extern_complex(<2 x float> noundef nofpclass(nan) [[TMP2]], double noundef nofpclass(nan) [[TMP4]], double noundef nofpclass(nan) [[TMP6]], <2 x half> noundef nofpclass(nan) [[TMP7]])
// NONANS-NEXT: store <2 x float> [[CALL]], ptr [[COERCE3]], align 4
// NONANS-NEXT: [[COERCE3_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE3]], i32 0, i32 0
// NONANS-NEXT: [[COERCE3_REAL:%.*]] = load float, ptr [[COERCE3_REALP]], align 4
// NONANS-NEXT: [[COERCE3_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE3]], i32 0, i32 1
// NONANS-NEXT: [[COERCE3_IMAG:%.*]] = load float, ptr [[COERCE3_IMAGP]], align 4
// NONANS-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0
// NONANS-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1
// NONANS-NEXT: store float [[COERCE3_REAL]], ptr [[RETVAL_REALP]], align 4
// NONANS-NEXT: store float [[COERCE3_IMAG]], ptr [[RETVAL_IMAGP]], align 4
// NONANS-NEXT: [[TMP8:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// NONANS-NEXT: ret <2 x float> [[TMP8]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) <2 x float> @defined_complex_func
// NOINFS-SAME: (<2 x float> noundef nofpclass(inf) [[A_COERCE:%.*]], double noundef nofpclass(inf) [[B_COERCE0:%.*]], double noundef nofpclass(inf) [[B_COERCE1:%.*]], <2 x half> noundef nofpclass(inf) [[C_COERCE:%.*]]) #[[ATTR4:[0-9]+]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: [[B:%.*]] = alloca { double, double }, align 8
// NOINFS-NEXT: [[C:%.*]] = alloca { half, half }, align 2
// NOINFS-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: [[COERCE1:%.*]] = alloca { double, double }, align 8
// NOINFS-NEXT: [[COERCE2:%.*]] = alloca { half, half }, align 2
// NOINFS-NEXT: [[COERCE3:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// NOINFS-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0
// NOINFS-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
// NOINFS-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1
// NOINFS-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
// NOINFS-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2
// NOINFS-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0
// NOINFS-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// NOINFS-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1
// NOINFS-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// NOINFS-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 0
// NOINFS-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
// NOINFS-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[B]], i32 0, i32 1
// NOINFS-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
// NOINFS-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// NOINFS-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
// NOINFS-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// NOINFS-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
// NOINFS-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1
// NOINFS-NEXT: store float [[A_REAL]], ptr [[COERCE_REALP]], align 4
// NOINFS-NEXT: store float [[A_IMAG]], ptr [[COERCE_IMAGP]], align 4
// NOINFS-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr [[COERCE]], align 4
// NOINFS-NEXT: [[COERCE1_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE1_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 1
// NOINFS-NEXT: store double [[B_REAL]], ptr [[COERCE1_REALP]], align 8
// NOINFS-NEXT: store double [[B_IMAG]], ptr [[COERCE1_IMAGP]], align 8
// NOINFS-NEXT: [[TMP3:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 0
// NOINFS-NEXT: [[TMP4:%.*]] = load double, ptr [[TMP3]], align 8
// NOINFS-NEXT: [[TMP5:%.*]] = getelementptr inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 1
// NOINFS-NEXT: [[TMP6:%.*]] = load double, ptr [[TMP5]], align 8
// NOINFS-NEXT: [[COERCE2_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE2]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE2_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE2]], i32 0, i32 1
// NOINFS-NEXT: store half [[C_REAL]], ptr [[COERCE2_REALP]], align 2
// NOINFS-NEXT: store half [[C_IMAG]], ptr [[COERCE2_IMAGP]], align 2
// NOINFS-NEXT: [[TMP7:%.*]] = load <2 x half>, ptr [[COERCE2]], align 2
// NOINFS-NEXT: [[CALL:%.*]] = call ninf nofpclass(inf) <2 x float> @extern_complex(<2 x float> noundef nofpclass(inf) [[TMP2]], double noundef nofpclass(inf) [[TMP4]], double noundef nofpclass(inf) [[TMP6]], <2 x half> noundef nofpclass(inf) [[TMP7]])
// NOINFS-NEXT: store <2 x float> [[CALL]], ptr [[COERCE3]], align 4
// NOINFS-NEXT: [[COERCE3_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE3]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE3_REAL:%.*]] = load float, ptr [[COERCE3_REALP]], align 4
// NOINFS-NEXT: [[COERCE3_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE3]], i32 0, i32 1
// NOINFS-NEXT: [[COERCE3_IMAG:%.*]] = load float, ptr [[COERCE3_IMAGP]], align 4
// NOINFS-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0
// NOINFS-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1
// NOINFS-NEXT: store float [[COERCE3_REAL]], ptr [[RETVAL_REALP]], align 4
// NOINFS-NEXT: store float [[COERCE3_IMAG]], ptr [[RETVAL_IMAGP]], align 4
// NOINFS-NEXT: [[TMP8:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// NOINFS-NEXT: ret <2 x float> [[TMP8]]
//
_Complex float defined_complex_func(_Complex float a, _Complex double b, _Complex _Float16 c) {
return extern_complex(a, b, c);
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local { double, double } @defined_complex_func_f64_ret
// CFINITEONLY-SAME: (double noundef nofpclass(nan inf) [[C_COERCE0:%.*]], double noundef nofpclass(nan inf) [[C_COERCE1:%.*]]) #[[ATTR0]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// CFINITEONLY-NEXT: [[C:%.*]] = alloca { double, double }, align 8
// CFINITEONLY-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// CFINITEONLY-NEXT: store double [[C_COERCE0]], ptr [[TMP0]], align 8
// CFINITEONLY-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// CFINITEONLY-NEXT: store double [[C_COERCE1]], ptr [[TMP1]], align 8
// CFINITEONLY-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// CFINITEONLY-NEXT: [[C_REAL:%.*]] = load double, ptr [[C_REALP]], align 8
// CFINITEONLY-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// CFINITEONLY-NEXT: [[C_IMAG:%.*]] = load double, ptr [[C_IMAGP]], align 8
// CFINITEONLY-NEXT: [[C_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// CFINITEONLY-NEXT: [[C_REAL2:%.*]] = load double, ptr [[C_REALP1]], align 8
// CFINITEONLY-NEXT: [[C_IMAGP3:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// CFINITEONLY-NEXT: [[C_IMAG4:%.*]] = load double, ptr [[C_IMAGP3]], align 8
// CFINITEONLY-NEXT: [[MUL_AC:%.*]] = fmul nnan ninf double [[C_REAL]], [[C_REAL2]]
// CFINITEONLY-NEXT: [[MUL_BD:%.*]] = fmul nnan ninf double [[C_IMAG]], [[C_IMAG4]]
// CFINITEONLY-NEXT: [[MUL_AD:%.*]] = fmul nnan ninf double [[C_REAL]], [[C_IMAG4]]
// CFINITEONLY-NEXT: [[MUL_BC:%.*]] = fmul nnan ninf double [[C_IMAG]], [[C_REAL2]]
// CFINITEONLY-NEXT: [[MUL_R:%.*]] = fsub nnan ninf double [[MUL_AC]], [[MUL_BD]]
// CFINITEONLY-NEXT: [[MUL_I:%.*]] = fadd nnan ninf double [[MUL_AD]], [[MUL_BC]]
// CFINITEONLY-NEXT: [[ISNAN_CMP:%.*]] = fcmp nnan ninf uno double [[MUL_R]], [[MUL_R]]
// CFINITEONLY-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]]
// CFINITEONLY: complex_mul_imag_nan:
// CFINITEONLY-NEXT: [[ISNAN_CMP5:%.*]] = fcmp nnan ninf uno double [[MUL_I]], [[MUL_I]]
// CFINITEONLY-NEXT: br i1 [[ISNAN_CMP5]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
// CFINITEONLY: complex_mul_libcall:
// CFINITEONLY-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef nofpclass(nan inf) [[C_REAL]], double noundef nofpclass(nan inf) [[C_IMAG]], double noundef nofpclass(nan inf) [[C_REAL2]], double noundef nofpclass(nan inf) [[C_IMAG4]]) #[[ATTR7:[0-9]+]]
// CFINITEONLY-NEXT: [[TMP2:%.*]] = extractvalue { double, double } [[CALL]], 0
// CFINITEONLY-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL]], 1
// CFINITEONLY-NEXT: br label [[COMPLEX_MUL_CONT]]
// CFINITEONLY: complex_mul_cont:
// CFINITEONLY-NEXT: [[REAL_MUL_PHI:%.*]] = phi nnan ninf double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP2]], [[COMPLEX_MUL_LIBCALL]] ]
// CFINITEONLY-NEXT: [[IMAG_MUL_PHI:%.*]] = phi nnan ninf double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP3]], [[COMPLEX_MUL_LIBCALL]] ]
// CFINITEONLY-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0
// CFINITEONLY-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1
// CFINITEONLY-NEXT: store double [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 8
// CFINITEONLY-NEXT: store double [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 8
// CFINITEONLY-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
// CFINITEONLY-NEXT: ret { double, double } [[TMP4]]
//
// CLFINITEONLY: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
// CLFINITEONLY-LABEL: define dso_local { double, double } @defined_complex_func_f64_ret
// CLFINITEONLY-SAME: (double noundef nofpclass(nan inf) [[C_COERCE0:%.*]], double noundef nofpclass(nan inf) [[C_COERCE1:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[MUL_AD:%.*]] = fmul nnan ninf double [[C_COERCE0]], [[C_COERCE1]]
// CLFINITEONLY-NEXT: [[MUL_I:%.*]] = fadd nnan ninf double [[MUL_AD]], [[MUL_AD]]
// CLFINITEONLY-NEXT: [[MUL_AC:%.*]] = fmul nnan ninf double [[C_COERCE0]], [[C_COERCE0]]
// CLFINITEONLY-NEXT: [[MUL_BD:%.*]] = fmul nnan ninf double [[C_COERCE1]], [[C_COERCE1]]
// CLFINITEONLY-NEXT: [[MUL_R:%.*]] = fsub nnan ninf double [[MUL_AC]], [[MUL_BD]]
// CLFINITEONLY-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { double, double } poison, double [[MUL_R]], 0
// CLFINITEONLY-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { double, double } [[DOTFCA_0_INSERT]], double [[MUL_I]], 1
// CLFINITEONLY-NEXT: ret { double, double } [[DOTFCA_1_INSERT]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local { double, double } @defined_complex_func_f64_ret
// NONANS-SAME: (double noundef nofpclass(nan) [[C_COERCE0:%.*]], double noundef nofpclass(nan) [[C_COERCE1:%.*]]) #[[ATTR0]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// NONANS-NEXT: [[C:%.*]] = alloca { double, double }, align 8
// NONANS-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// NONANS-NEXT: store double [[C_COERCE0]], ptr [[TMP0]], align 8
// NONANS-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// NONANS-NEXT: store double [[C_COERCE1]], ptr [[TMP1]], align 8
// NONANS-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// NONANS-NEXT: [[C_REAL:%.*]] = load double, ptr [[C_REALP]], align 8
// NONANS-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// NONANS-NEXT: [[C_IMAG:%.*]] = load double, ptr [[C_IMAGP]], align 8
// NONANS-NEXT: [[C_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// NONANS-NEXT: [[C_REAL2:%.*]] = load double, ptr [[C_REALP1]], align 8
// NONANS-NEXT: [[C_IMAGP3:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// NONANS-NEXT: [[C_IMAG4:%.*]] = load double, ptr [[C_IMAGP3]], align 8
// NONANS-NEXT: [[MUL_AC:%.*]] = fmul nnan double [[C_REAL]], [[C_REAL2]]
// NONANS-NEXT: [[MUL_BD:%.*]] = fmul nnan double [[C_IMAG]], [[C_IMAG4]]
// NONANS-NEXT: [[MUL_AD:%.*]] = fmul nnan double [[C_REAL]], [[C_IMAG4]]
// NONANS-NEXT: [[MUL_BC:%.*]] = fmul nnan double [[C_IMAG]], [[C_REAL2]]
// NONANS-NEXT: [[MUL_R:%.*]] = fsub nnan double [[MUL_AC]], [[MUL_BD]]
// NONANS-NEXT: [[MUL_I:%.*]] = fadd nnan double [[MUL_AD]], [[MUL_BC]]
// NONANS-NEXT: [[ISNAN_CMP:%.*]] = fcmp nnan uno double [[MUL_R]], [[MUL_R]]
// NONANS-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]]
// NONANS: complex_mul_imag_nan:
// NONANS-NEXT: [[ISNAN_CMP5:%.*]] = fcmp nnan uno double [[MUL_I]], [[MUL_I]]
// NONANS-NEXT: br i1 [[ISNAN_CMP5]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
// NONANS: complex_mul_libcall:
// NONANS-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef nofpclass(nan) [[C_REAL]], double noundef nofpclass(nan) [[C_IMAG]], double noundef nofpclass(nan) [[C_REAL2]], double noundef nofpclass(nan) [[C_IMAG4]]) #[[ATTR7:[0-9]+]]
// NONANS-NEXT: [[TMP2:%.*]] = extractvalue { double, double } [[CALL]], 0
// NONANS-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL]], 1
// NONANS-NEXT: br label [[COMPLEX_MUL_CONT]]
// NONANS: complex_mul_cont:
// NONANS-NEXT: [[REAL_MUL_PHI:%.*]] = phi nnan double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP2]], [[COMPLEX_MUL_LIBCALL]] ]
// NONANS-NEXT: [[IMAG_MUL_PHI:%.*]] = phi nnan double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP3]], [[COMPLEX_MUL_LIBCALL]] ]
// NONANS-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0
// NONANS-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1
// NONANS-NEXT: store double [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 8
// NONANS-NEXT: store double [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 8
// NONANS-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
// NONANS-NEXT: ret { double, double } [[TMP4]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local { double, double } @defined_complex_func_f64_ret
// NOINFS-SAME: (double noundef nofpclass(inf) [[C_COERCE0:%.*]], double noundef nofpclass(inf) [[C_COERCE1:%.*]]) #[[ATTR0]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// NOINFS-NEXT: [[C:%.*]] = alloca { double, double }, align 8
// NOINFS-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// NOINFS-NEXT: store double [[C_COERCE0]], ptr [[TMP0]], align 8
// NOINFS-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// NOINFS-NEXT: store double [[C_COERCE1]], ptr [[TMP1]], align 8
// NOINFS-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// NOINFS-NEXT: [[C_REAL:%.*]] = load double, ptr [[C_REALP]], align 8
// NOINFS-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// NOINFS-NEXT: [[C_IMAG:%.*]] = load double, ptr [[C_IMAGP]], align 8
// NOINFS-NEXT: [[C_REALP1:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 0
// NOINFS-NEXT: [[C_REAL2:%.*]] = load double, ptr [[C_REALP1]], align 8
// NOINFS-NEXT: [[C_IMAGP3:%.*]] = getelementptr inbounds { double, double }, ptr [[C]], i32 0, i32 1
// NOINFS-NEXT: [[C_IMAG4:%.*]] = load double, ptr [[C_IMAGP3]], align 8
// NOINFS-NEXT: [[MUL_AC:%.*]] = fmul ninf double [[C_REAL]], [[C_REAL2]]
// NOINFS-NEXT: [[MUL_BD:%.*]] = fmul ninf double [[C_IMAG]], [[C_IMAG4]]
// NOINFS-NEXT: [[MUL_AD:%.*]] = fmul ninf double [[C_REAL]], [[C_IMAG4]]
// NOINFS-NEXT: [[MUL_BC:%.*]] = fmul ninf double [[C_IMAG]], [[C_REAL2]]
// NOINFS-NEXT: [[MUL_R:%.*]] = fsub ninf double [[MUL_AC]], [[MUL_BD]]
// NOINFS-NEXT: [[MUL_I:%.*]] = fadd ninf double [[MUL_AD]], [[MUL_BC]]
// NOINFS-NEXT: [[ISNAN_CMP:%.*]] = fcmp ninf uno double [[MUL_R]], [[MUL_R]]
// NOINFS-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]]
// NOINFS: complex_mul_imag_nan:
// NOINFS-NEXT: [[ISNAN_CMP5:%.*]] = fcmp ninf uno double [[MUL_I]], [[MUL_I]]
// NOINFS-NEXT: br i1 [[ISNAN_CMP5]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
// NOINFS: complex_mul_libcall:
// NOINFS-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef nofpclass(inf) [[C_REAL]], double noundef nofpclass(inf) [[C_IMAG]], double noundef nofpclass(inf) [[C_REAL2]], double noundef nofpclass(inf) [[C_IMAG4]]) #[[ATTR7:[0-9]+]]
// NOINFS-NEXT: [[TMP2:%.*]] = extractvalue { double, double } [[CALL]], 0
// NOINFS-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL]], 1
// NOINFS-NEXT: br label [[COMPLEX_MUL_CONT]]
// NOINFS: complex_mul_cont:
// NOINFS-NEXT: [[REAL_MUL_PHI:%.*]] = phi ninf double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP2]], [[COMPLEX_MUL_LIBCALL]] ]
// NOINFS-NEXT: [[IMAG_MUL_PHI:%.*]] = phi ninf double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP3]], [[COMPLEX_MUL_LIBCALL]] ]
// NOINFS-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 0
// NOINFS-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[RETVAL]], i32 0, i32 1
// NOINFS-NEXT: store double [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 8
// NOINFS-NEXT: store double [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 8
// NOINFS-NEXT: [[TMP4:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
// NOINFS-NEXT: ret { double, double } [[TMP4]]
//
_Complex double defined_complex_func_f64_ret(_Complex double c) {
return c * c;
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <2 x half> @defined_complex_func_f16_ret
// CFINITEONLY-SAME: (<2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR4]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
// CFINITEONLY-NEXT: [[C:%.*]] = alloca { half, half }, align 2
// CFINITEONLY-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2
// CFINITEONLY-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// CFINITEONLY-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
// CFINITEONLY-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// CFINITEONLY-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
// CFINITEONLY-NEXT: [[EXT:%.*]] = fpext half [[C_REAL]] to float
// CFINITEONLY-NEXT: [[EXT1:%.*]] = fpext half [[C_IMAG]] to float
// CFINITEONLY-NEXT: [[C_REALP2:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// CFINITEONLY-NEXT: [[C_REAL3:%.*]] = load half, ptr [[C_REALP2]], align 2
// CFINITEONLY-NEXT: [[C_IMAGP4:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// CFINITEONLY-NEXT: [[C_IMAG5:%.*]] = load half, ptr [[C_IMAGP4]], align 2
// CFINITEONLY-NEXT: [[EXT6:%.*]] = fpext half [[C_REAL3]] to float
// CFINITEONLY-NEXT: [[EXT7:%.*]] = fpext half [[C_IMAG5]] to float
// CFINITEONLY-NEXT: [[MUL_AC:%.*]] = fmul nnan ninf float [[EXT]], [[EXT6]]
// CFINITEONLY-NEXT: [[MUL_BD:%.*]] = fmul nnan ninf float [[EXT1]], [[EXT7]]
// CFINITEONLY-NEXT: [[MUL_AD:%.*]] = fmul nnan ninf float [[EXT]], [[EXT7]]
// CFINITEONLY-NEXT: [[MUL_BC:%.*]] = fmul nnan ninf float [[EXT1]], [[EXT6]]
// CFINITEONLY-NEXT: [[MUL_R:%.*]] = fsub nnan ninf float [[MUL_AC]], [[MUL_BD]]
// CFINITEONLY-NEXT: [[MUL_I:%.*]] = fadd nnan ninf float [[MUL_AD]], [[MUL_BC]]
// CFINITEONLY-NEXT: [[ISNAN_CMP:%.*]] = fcmp nnan ninf uno float [[MUL_R]], [[MUL_R]]
// CFINITEONLY-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
// CFINITEONLY: complex_mul_imag_nan:
// CFINITEONLY-NEXT: [[ISNAN_CMP8:%.*]] = fcmp nnan ninf uno float [[MUL_I]], [[MUL_I]]
// CFINITEONLY-NEXT: br i1 [[ISNAN_CMP8]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
// CFINITEONLY: complex_mul_libcall:
// CFINITEONLY-NEXT: [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) <2 x float> @__mulsc3(float noundef nofpclass(nan inf) [[EXT]], float noundef nofpclass(nan inf) [[EXT1]], float noundef nofpclass(nan inf) [[EXT6]], float noundef nofpclass(nan inf) [[EXT7]]) #[[ATTR7]]
// CFINITEONLY-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4
// CFINITEONLY-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4
// CFINITEONLY-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1
// CFINITEONLY-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4
// CFINITEONLY-NEXT: br label [[COMPLEX_MUL_CONT]]
// CFINITEONLY: complex_mul_cont:
// CFINITEONLY-NEXT: [[REAL_MUL_PHI:%.*]] = phi nnan ninf float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ]
// CFINITEONLY-NEXT: [[IMAG_MUL_PHI:%.*]] = phi nnan ninf float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ]
// CFINITEONLY-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[REAL_MUL_PHI]] to half
// CFINITEONLY-NEXT: [[UNPROMOTION9:%.*]] = fptrunc float [[IMAG_MUL_PHI]] to half
// CFINITEONLY-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0
// CFINITEONLY-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1
// CFINITEONLY-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
// CFINITEONLY-NEXT: store half [[UNPROMOTION9]], ptr [[RETVAL_IMAGP]], align 2
// CFINITEONLY-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
// CFINITEONLY-NEXT: ret <2 x half> [[TMP0]]
//
// CLFINITEONLY: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <2 x half> @defined_complex_func_f16_ret
// CLFINITEONLY-SAME: (<2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[C_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x half> [[C_COERCE]], i64 0
// CLFINITEONLY-NEXT: [[EXT:%.*]] = fpext half [[C_SROA_0_0_VEC_EXTRACT]] to float
// CLFINITEONLY-NEXT: [[C_SROA_0_2_VEC_EXTRACT:%.*]] = extractelement <2 x half> [[C_COERCE]], i64 1
// CLFINITEONLY-NEXT: [[EXT1:%.*]] = fpext half [[C_SROA_0_2_VEC_EXTRACT]] to float
// CLFINITEONLY-NEXT: [[MUL_AD:%.*]] = fmul nnan ninf float [[EXT]], [[EXT1]]
// CLFINITEONLY-NEXT: [[MUL_I:%.*]] = fadd nnan ninf float [[MUL_AD]], [[MUL_AD]]
// CLFINITEONLY-NEXT: [[MUL_AC:%.*]] = fmul nnan ninf float [[EXT]], [[EXT]]
// CLFINITEONLY-NEXT: [[MUL_BD:%.*]] = fmul nnan ninf float [[EXT1]], [[EXT1]]
// CLFINITEONLY-NEXT: [[MUL_R:%.*]] = fsub nnan ninf float [[MUL_AC]], [[MUL_BD]]
// CLFINITEONLY-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half
// CLFINITEONLY-NEXT: [[UNPROMOTION9:%.*]] = fptrunc float [[MUL_I]] to half
// CLFINITEONLY-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> poison, half [[UNPROMOTION]], i64 0
// CLFINITEONLY-NEXT: [[RETVAL_SROA_0_2_VEC_INSERT:%.*]] = insertelement <2 x half> [[RETVAL_SROA_0_0_VEC_INSERT]], half [[UNPROMOTION9]], i64 1
// CLFINITEONLY-NEXT: ret <2 x half> [[RETVAL_SROA_0_2_VEC_INSERT]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) <2 x half> @defined_complex_func_f16_ret
// NONANS-SAME: (<2 x half> noundef nofpclass(nan) [[C_COERCE:%.*]]) #[[ATTR4]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
// NONANS-NEXT: [[C:%.*]] = alloca { half, half }, align 2
// NONANS-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2
// NONANS-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// NONANS-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
// NONANS-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// NONANS-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
// NONANS-NEXT: [[EXT:%.*]] = fpext half [[C_REAL]] to float
// NONANS-NEXT: [[EXT1:%.*]] = fpext half [[C_IMAG]] to float
// NONANS-NEXT: [[C_REALP2:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// NONANS-NEXT: [[C_REAL3:%.*]] = load half, ptr [[C_REALP2]], align 2
// NONANS-NEXT: [[C_IMAGP4:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// NONANS-NEXT: [[C_IMAG5:%.*]] = load half, ptr [[C_IMAGP4]], align 2
// NONANS-NEXT: [[EXT6:%.*]] = fpext half [[C_REAL3]] to float
// NONANS-NEXT: [[EXT7:%.*]] = fpext half [[C_IMAG5]] to float
// NONANS-NEXT: [[MUL_AC:%.*]] = fmul nnan float [[EXT]], [[EXT6]]
// NONANS-NEXT: [[MUL_BD:%.*]] = fmul nnan float [[EXT1]], [[EXT7]]
// NONANS-NEXT: [[MUL_AD:%.*]] = fmul nnan float [[EXT]], [[EXT7]]
// NONANS-NEXT: [[MUL_BC:%.*]] = fmul nnan float [[EXT1]], [[EXT6]]
// NONANS-NEXT: [[MUL_R:%.*]] = fsub nnan float [[MUL_AC]], [[MUL_BD]]
// NONANS-NEXT: [[MUL_I:%.*]] = fadd nnan float [[MUL_AD]], [[MUL_BC]]
// NONANS-NEXT: [[ISNAN_CMP:%.*]] = fcmp nnan uno float [[MUL_R]], [[MUL_R]]
// NONANS-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
// NONANS: complex_mul_imag_nan:
// NONANS-NEXT: [[ISNAN_CMP8:%.*]] = fcmp nnan uno float [[MUL_I]], [[MUL_I]]
// NONANS-NEXT: br i1 [[ISNAN_CMP8]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
// NONANS: complex_mul_libcall:
// NONANS-NEXT: [[CALL:%.*]] = call nnan nofpclass(nan) <2 x float> @__mulsc3(float noundef nofpclass(nan) [[EXT]], float noundef nofpclass(nan) [[EXT1]], float noundef nofpclass(nan) [[EXT6]], float noundef nofpclass(nan) [[EXT7]]) #[[ATTR7]]
// NONANS-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4
// NONANS-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0
// NONANS-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4
// NONANS-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1
// NONANS-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4
// NONANS-NEXT: br label [[COMPLEX_MUL_CONT]]
// NONANS: complex_mul_cont:
// NONANS-NEXT: [[REAL_MUL_PHI:%.*]] = phi nnan float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ]
// NONANS-NEXT: [[IMAG_MUL_PHI:%.*]] = phi nnan float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ]
// NONANS-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[REAL_MUL_PHI]] to half
// NONANS-NEXT: [[UNPROMOTION9:%.*]] = fptrunc float [[IMAG_MUL_PHI]] to half
// NONANS-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0
// NONANS-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1
// NONANS-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
// NONANS-NEXT: store half [[UNPROMOTION9]], ptr [[RETVAL_IMAGP]], align 2
// NONANS-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
// NONANS-NEXT: ret <2 x half> [[TMP0]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) <2 x half> @defined_complex_func_f16_ret
// NOINFS-SAME: (<2 x half> noundef nofpclass(inf) [[C_COERCE:%.*]]) #[[ATTR4]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2
// NOINFS-NEXT: [[C:%.*]] = alloca { half, half }, align 2
// NOINFS-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2
// NOINFS-NEXT: [[C_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// NOINFS-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2
// NOINFS-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// NOINFS-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2
// NOINFS-NEXT: [[EXT:%.*]] = fpext half [[C_REAL]] to float
// NOINFS-NEXT: [[EXT1:%.*]] = fpext half [[C_IMAG]] to float
// NOINFS-NEXT: [[C_REALP2:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 0
// NOINFS-NEXT: [[C_REAL3:%.*]] = load half, ptr [[C_REALP2]], align 2
// NOINFS-NEXT: [[C_IMAGP4:%.*]] = getelementptr inbounds { half, half }, ptr [[C]], i32 0, i32 1
// NOINFS-NEXT: [[C_IMAG5:%.*]] = load half, ptr [[C_IMAGP4]], align 2
// NOINFS-NEXT: [[EXT6:%.*]] = fpext half [[C_REAL3]] to float
// NOINFS-NEXT: [[EXT7:%.*]] = fpext half [[C_IMAG5]] to float
// NOINFS-NEXT: [[MUL_AC:%.*]] = fmul ninf float [[EXT]], [[EXT6]]
// NOINFS-NEXT: [[MUL_BD:%.*]] = fmul ninf float [[EXT1]], [[EXT7]]
// NOINFS-NEXT: [[MUL_AD:%.*]] = fmul ninf float [[EXT]], [[EXT7]]
// NOINFS-NEXT: [[MUL_BC:%.*]] = fmul ninf float [[EXT1]], [[EXT6]]
// NOINFS-NEXT: [[MUL_R:%.*]] = fsub ninf float [[MUL_AC]], [[MUL_BD]]
// NOINFS-NEXT: [[MUL_I:%.*]] = fadd ninf float [[MUL_AD]], [[MUL_BC]]
// NOINFS-NEXT: [[ISNAN_CMP:%.*]] = fcmp ninf uno float [[MUL_R]], [[MUL_R]]
// NOINFS-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
// NOINFS: complex_mul_imag_nan:
// NOINFS-NEXT: [[ISNAN_CMP8:%.*]] = fcmp ninf uno float [[MUL_I]], [[MUL_I]]
// NOINFS-NEXT: br i1 [[ISNAN_CMP8]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
// NOINFS: complex_mul_libcall:
// NOINFS-NEXT: [[CALL:%.*]] = call ninf nofpclass(inf) <2 x float> @__mulsc3(float noundef nofpclass(inf) [[EXT]], float noundef nofpclass(inf) [[EXT1]], float noundef nofpclass(inf) [[EXT6]], float noundef nofpclass(inf) [[EXT7]]) #[[ATTR7]]
// NOINFS-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4
// NOINFS-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4
// NOINFS-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE]], i32 0, i32 1
// NOINFS-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4
// NOINFS-NEXT: br label [[COMPLEX_MUL_CONT]]
// NOINFS: complex_mul_cont:
// NOINFS-NEXT: [[REAL_MUL_PHI:%.*]] = phi ninf float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ]
// NOINFS-NEXT: [[IMAG_MUL_PHI:%.*]] = phi ninf float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ]
// NOINFS-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[REAL_MUL_PHI]] to half
// NOINFS-NEXT: [[UNPROMOTION9:%.*]] = fptrunc float [[IMAG_MUL_PHI]] to half
// NOINFS-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 0
// NOINFS-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[RETVAL]], i32 0, i32 1
// NOINFS-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2
// NOINFS-NEXT: store half [[UNPROMOTION9]], ptr [[RETVAL_IMAGP]], align 2
// NOINFS-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2
// NOINFS-NEXT: ret <2 x half> [[TMP0]]
//
_Complex _Float16 defined_complex_func_f16_ret(_Complex _Float16 c) {
return c * c;
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_variadic
// CFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[F32:%.*]], double noundef nofpclass(nan inf) [[F64:%.*]], half noundef nofpclass(nan inf) [[F16:%.*]], double noundef nofpclass(nan inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE1:%.*]], ptr noundef byval({ half, half }) align 8 [[CF16:%.*]]) #[[ATTR2]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[V2F32:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[V2F16:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[CF32:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: [[CF64:%.*]] = alloca { double, double }, align 8
// CFINITEONLY-NEXT: [[F32_ADDR:%.*]] = alloca float, align 4
// CFINITEONLY-NEXT: [[F64_ADDR:%.*]] = alloca double, align 8
// CFINITEONLY-NEXT: [[F16_ADDR:%.*]] = alloca half, align 2
// CFINITEONLY-NEXT: [[V2F32_ADDR:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[V2F64_ADDR:%.*]] = alloca <2 x double>, align 16
// CFINITEONLY-NEXT: [[V2F16_ADDR:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[COERCE4:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca { double, double }, align 8
// CFINITEONLY-NEXT: [[COERCE5:%.*]] = alloca { half, half }, align 2
// CFINITEONLY-NEXT: store double [[V2F32_COERCE]], ptr [[V2F32]], align 8
// CFINITEONLY-NEXT: [[V2F321:%.*]] = load <2 x float>, ptr [[V2F32]], align 8
// CFINITEONLY-NEXT: store i32 [[V2F16_COERCE]], ptr [[V2F16]], align 4
// CFINITEONLY-NEXT: [[V2F162:%.*]] = load <2 x half>, ptr [[V2F16]], align 4
// CFINITEONLY-NEXT: store <2 x float> [[CF32_COERCE]], ptr [[CF32]], align 4
// CFINITEONLY-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// CFINITEONLY-NEXT: store double [[CF64_COERCE0]], ptr [[TMP0]], align 8
// CFINITEONLY-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// CFINITEONLY-NEXT: store double [[CF64_COERCE1]], ptr [[TMP1]], align 8
// CFINITEONLY-NEXT: store float [[F32]], ptr [[F32_ADDR]], align 4
// CFINITEONLY-NEXT: store double [[F64]], ptr [[F64_ADDR]], align 8
// CFINITEONLY-NEXT: store half [[F16]], ptr [[F16_ADDR]], align 2
// CFINITEONLY-NEXT: store <2 x float> [[V2F321]], ptr [[V2F32_ADDR]], align 8
// CFINITEONLY-NEXT: store <2 x double> [[V2F64]], ptr [[V2F64_ADDR]], align 16
// CFINITEONLY-NEXT: store <2 x half> [[V2F162]], ptr [[V2F16_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP2:%.*]] = load float, ptr [[F32_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP3:%.*]] = load float, ptr [[F32_ADDR]], align 4
// CFINITEONLY-NEXT: [[CONV:%.*]] = fpext float [[TMP3]] to double
// CFINITEONLY-NEXT: [[TMP4:%.*]] = load double, ptr [[F64_ADDR]], align 8
// CFINITEONLY-NEXT: [[TMP5:%.*]] = load half, ptr [[F16_ADDR]], align 2
// CFINITEONLY-NEXT: [[TMP6:%.*]] = load <2 x float>, ptr [[V2F32_ADDR]], align 8
// CFINITEONLY-NEXT: [[TMP7:%.*]] = load <2 x double>, ptr [[V2F64_ADDR]], align 16
// CFINITEONLY-NEXT: [[TMP8:%.*]] = load <2 x half>, ptr [[V2F16_ADDR]], align 4
// CFINITEONLY-NEXT: [[CF32_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 0
// CFINITEONLY-NEXT: [[CF32_REAL:%.*]] = load float, ptr [[CF32_REALP]], align 4
// CFINITEONLY-NEXT: [[CF32_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 1
// CFINITEONLY-NEXT: [[CF32_IMAG:%.*]] = load float, ptr [[CF32_IMAGP]], align 4
// CFINITEONLY-NEXT: [[CF64_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// CFINITEONLY-NEXT: [[CF64_REAL:%.*]] = load double, ptr [[CF64_REALP]], align 8
// CFINITEONLY-NEXT: [[CF64_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// CFINITEONLY-NEXT: [[CF64_IMAG:%.*]] = load double, ptr [[CF64_IMAGP]], align 8
// CFINITEONLY-NEXT: [[CF16_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 0
// CFINITEONLY-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16_REALP]], align 8
// CFINITEONLY-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 1
// CFINITEONLY-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2
// CFINITEONLY-NEXT: store <2 x float> [[TMP6]], ptr [[COERCE]], align 8
// CFINITEONLY-NEXT: [[TMP9:%.*]] = load double, ptr [[COERCE]], align 8
// CFINITEONLY-NEXT: store <2 x half> [[TMP8]], ptr [[COERCE3]], align 4
// CFINITEONLY-NEXT: [[TMP10:%.*]] = load i32, ptr [[COERCE3]], align 4
// CFINITEONLY-NEXT: [[COERCE4_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE4_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 1
// CFINITEONLY-NEXT: store float [[CF32_REAL]], ptr [[COERCE4_REALP]], align 4
// CFINITEONLY-NEXT: store float [[CF32_IMAG]], ptr [[COERCE4_IMAGP]], align 4
// CFINITEONLY-NEXT: [[TMP11:%.*]] = load <2 x float>, ptr [[COERCE4]], align 4
// CFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 0
// CFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 1
// CFINITEONLY-NEXT: store double [[CF64_REAL]], ptr [[INDIRECT_ARG_TEMP_REALP]], align 8
// CFINITEONLY-NEXT: store double [[CF64_IMAG]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8
// CFINITEONLY-NEXT: [[COERCE5_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE5_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 1
// CFINITEONLY-NEXT: store half [[CF16_REAL]], ptr [[COERCE5_REALP]], align 2
// CFINITEONLY-NEXT: store half [[CF16_IMAG]], ptr [[COERCE5_IMAGP]], align 2
// CFINITEONLY-NEXT: [[TMP12:%.*]] = load <2 x half>, ptr [[COERCE5]], align 2
// CFINITEONLY-NEXT: [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) float (float, ...) @variadic(float noundef nofpclass(nan inf) [[TMP2]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[TMP4]], half noundef nofpclass(nan inf) [[TMP5]], double noundef nofpclass(nan inf) [[TMP9]], <2 x double> noundef nofpclass(nan inf) [[TMP7]], i32 noundef [[TMP10]], <2 x float> noundef nofpclass(nan inf) [[TMP11]], ptr noundef byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[TMP12]])
// CFINITEONLY-NEXT: ret float [[CALL]]
//
// CLFINITEONLY: Function Attrs: convergent norecurse nounwind
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_variadic
// CLFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[F32:%.*]], double noundef nofpclass(nan inf) [[F64:%.*]], half noundef nofpclass(nan inf) [[F16:%.*]], double noundef nofpclass(nan inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE1:%.*]], ptr nocapture noundef readonly byval({ half, half }) align 8 [[CF16:%.*]]) local_unnamed_addr #[[ATTR5]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca { double, double }, align 8
// CLFINITEONLY-NEXT: [[CONV:%.*]] = fpext float [[F32]] to double
// CLFINITEONLY-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16]], align 8
// CLFINITEONLY-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds i8, ptr [[CF16]], i64 2
// CLFINITEONLY-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2
// CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds i8, ptr [[INDIRECT_ARG_TEMP]], i64 8
// CLFINITEONLY-NEXT: store double [[CF64_COERCE0]], ptr [[INDIRECT_ARG_TEMP]], align 8
// CLFINITEONLY-NEXT: store double [[CF64_COERCE1]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8
// CLFINITEONLY-NEXT: [[COERCE5_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> poison, half [[CF16_REAL]], i64 0
// CLFINITEONLY-NEXT: [[COERCE5_SROA_0_2_VEC_INSERT:%.*]] = insertelement <2 x half> [[COERCE5_SROA_0_0_VEC_INSERT]], half [[CF16_IMAG]], i64 1
// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float (float, ...) @variadic(float noundef nofpclass(nan inf) [[F32]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[F64]], half noundef nofpclass(nan inf) [[F16]], double noundef nofpclass(nan inf) [[V2F32_COERCE]], <2 x double> noundef nofpclass(nan inf) [[V2F64]], i32 noundef [[V2F16_COERCE]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE]], ptr noundef nonnull byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[COERCE5_SROA_0_2_VEC_INSERT]]) #[[ATTR10]]
// CLFINITEONLY-NEXT: ret float [[CALL]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) float @call_variadic
// NONANS-SAME: (float noundef nofpclass(nan) [[F32:%.*]], double noundef nofpclass(nan) [[F64:%.*]], half noundef nofpclass(nan) [[F16:%.*]], double noundef nofpclass(nan) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan) [[CF32_COERCE:%.*]], double noundef nofpclass(nan) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan) [[CF64_COERCE1:%.*]], ptr noundef byval({ half, half }) align 8 [[CF16:%.*]]) #[[ATTR2]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[V2F32:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[V2F16:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[CF32:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: [[CF64:%.*]] = alloca { double, double }, align 8
// NONANS-NEXT: [[F32_ADDR:%.*]] = alloca float, align 4
// NONANS-NEXT: [[F64_ADDR:%.*]] = alloca double, align 8
// NONANS-NEXT: [[F16_ADDR:%.*]] = alloca half, align 2
// NONANS-NEXT: [[V2F32_ADDR:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[V2F64_ADDR:%.*]] = alloca <2 x double>, align 16
// NONANS-NEXT: [[V2F16_ADDR:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[COERCE4:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca { double, double }, align 8
// NONANS-NEXT: [[COERCE5:%.*]] = alloca { half, half }, align 2
// NONANS-NEXT: store double [[V2F32_COERCE]], ptr [[V2F32]], align 8
// NONANS-NEXT: [[V2F321:%.*]] = load <2 x float>, ptr [[V2F32]], align 8
// NONANS-NEXT: store i32 [[V2F16_COERCE]], ptr [[V2F16]], align 4
// NONANS-NEXT: [[V2F162:%.*]] = load <2 x half>, ptr [[V2F16]], align 4
// NONANS-NEXT: store <2 x float> [[CF32_COERCE]], ptr [[CF32]], align 4
// NONANS-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// NONANS-NEXT: store double [[CF64_COERCE0]], ptr [[TMP0]], align 8
// NONANS-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// NONANS-NEXT: store double [[CF64_COERCE1]], ptr [[TMP1]], align 8
// NONANS-NEXT: store float [[F32]], ptr [[F32_ADDR]], align 4
// NONANS-NEXT: store double [[F64]], ptr [[F64_ADDR]], align 8
// NONANS-NEXT: store half [[F16]], ptr [[F16_ADDR]], align 2
// NONANS-NEXT: store <2 x float> [[V2F321]], ptr [[V2F32_ADDR]], align 8
// NONANS-NEXT: store <2 x double> [[V2F64]], ptr [[V2F64_ADDR]], align 16
// NONANS-NEXT: store <2 x half> [[V2F162]], ptr [[V2F16_ADDR]], align 4
// NONANS-NEXT: [[TMP2:%.*]] = load float, ptr [[F32_ADDR]], align 4
// NONANS-NEXT: [[TMP3:%.*]] = load float, ptr [[F32_ADDR]], align 4
// NONANS-NEXT: [[CONV:%.*]] = fpext float [[TMP3]] to double
// NONANS-NEXT: [[TMP4:%.*]] = load double, ptr [[F64_ADDR]], align 8
// NONANS-NEXT: [[TMP5:%.*]] = load half, ptr [[F16_ADDR]], align 2
// NONANS-NEXT: [[TMP6:%.*]] = load <2 x float>, ptr [[V2F32_ADDR]], align 8
// NONANS-NEXT: [[TMP7:%.*]] = load <2 x double>, ptr [[V2F64_ADDR]], align 16
// NONANS-NEXT: [[TMP8:%.*]] = load <2 x half>, ptr [[V2F16_ADDR]], align 4
// NONANS-NEXT: [[CF32_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 0
// NONANS-NEXT: [[CF32_REAL:%.*]] = load float, ptr [[CF32_REALP]], align 4
// NONANS-NEXT: [[CF32_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 1
// NONANS-NEXT: [[CF32_IMAG:%.*]] = load float, ptr [[CF32_IMAGP]], align 4
// NONANS-NEXT: [[CF64_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// NONANS-NEXT: [[CF64_REAL:%.*]] = load double, ptr [[CF64_REALP]], align 8
// NONANS-NEXT: [[CF64_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// NONANS-NEXT: [[CF64_IMAG:%.*]] = load double, ptr [[CF64_IMAGP]], align 8
// NONANS-NEXT: [[CF16_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 0
// NONANS-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16_REALP]], align 8
// NONANS-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 1
// NONANS-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2
// NONANS-NEXT: store <2 x float> [[TMP6]], ptr [[COERCE]], align 8
// NONANS-NEXT: [[TMP9:%.*]] = load double, ptr [[COERCE]], align 8
// NONANS-NEXT: store <2 x half> [[TMP8]], ptr [[COERCE3]], align 4
// NONANS-NEXT: [[TMP10:%.*]] = load i32, ptr [[COERCE3]], align 4
// NONANS-NEXT: [[COERCE4_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 0
// NONANS-NEXT: [[COERCE4_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 1
// NONANS-NEXT: store float [[CF32_REAL]], ptr [[COERCE4_REALP]], align 4
// NONANS-NEXT: store float [[CF32_IMAG]], ptr [[COERCE4_IMAGP]], align 4
// NONANS-NEXT: [[TMP11:%.*]] = load <2 x float>, ptr [[COERCE4]], align 4
// NONANS-NEXT: [[INDIRECT_ARG_TEMP_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 0
// NONANS-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 1
// NONANS-NEXT: store double [[CF64_REAL]], ptr [[INDIRECT_ARG_TEMP_REALP]], align 8
// NONANS-NEXT: store double [[CF64_IMAG]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8
// NONANS-NEXT: [[COERCE5_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 0
// NONANS-NEXT: [[COERCE5_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 1
// NONANS-NEXT: store half [[CF16_REAL]], ptr [[COERCE5_REALP]], align 2
// NONANS-NEXT: store half [[CF16_IMAG]], ptr [[COERCE5_IMAGP]], align 2
// NONANS-NEXT: [[TMP12:%.*]] = load <2 x half>, ptr [[COERCE5]], align 2
// NONANS-NEXT: [[CALL:%.*]] = call nnan nofpclass(nan) float (float, ...) @variadic(float noundef nofpclass(nan) [[TMP2]], double noundef nofpclass(nan) [[CONV]], double noundef nofpclass(nan) [[TMP4]], half noundef nofpclass(nan) [[TMP5]], double noundef nofpclass(nan) [[TMP9]], <2 x double> noundef nofpclass(nan) [[TMP7]], i32 noundef [[TMP10]], <2 x float> noundef nofpclass(nan) [[TMP11]], ptr noundef byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan) [[TMP12]])
// NONANS-NEXT: ret float [[CALL]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) float @call_variadic
// NOINFS-SAME: (float noundef nofpclass(inf) [[F32:%.*]], double noundef nofpclass(inf) [[F64:%.*]], half noundef nofpclass(inf) [[F16:%.*]], double noundef nofpclass(inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(inf) [[CF32_COERCE:%.*]], double noundef nofpclass(inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(inf) [[CF64_COERCE1:%.*]], ptr noundef byval({ half, half }) align 8 [[CF16:%.*]]) #[[ATTR2]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[V2F32:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[V2F16:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[CF32:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: [[CF64:%.*]] = alloca { double, double }, align 8
// NOINFS-NEXT: [[F32_ADDR:%.*]] = alloca float, align 4
// NOINFS-NEXT: [[F64_ADDR:%.*]] = alloca double, align 8
// NOINFS-NEXT: [[F16_ADDR:%.*]] = alloca half, align 2
// NOINFS-NEXT: [[V2F32_ADDR:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[V2F64_ADDR:%.*]] = alloca <2 x double>, align 16
// NOINFS-NEXT: [[V2F16_ADDR:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[COERCE4:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca { double, double }, align 8
// NOINFS-NEXT: [[COERCE5:%.*]] = alloca { half, half }, align 2
// NOINFS-NEXT: store double [[V2F32_COERCE]], ptr [[V2F32]], align 8
// NOINFS-NEXT: [[V2F321:%.*]] = load <2 x float>, ptr [[V2F32]], align 8
// NOINFS-NEXT: store i32 [[V2F16_COERCE]], ptr [[V2F16]], align 4
// NOINFS-NEXT: [[V2F162:%.*]] = load <2 x half>, ptr [[V2F16]], align 4
// NOINFS-NEXT: store <2 x float> [[CF32_COERCE]], ptr [[CF32]], align 4
// NOINFS-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// NOINFS-NEXT: store double [[CF64_COERCE0]], ptr [[TMP0]], align 8
// NOINFS-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// NOINFS-NEXT: store double [[CF64_COERCE1]], ptr [[TMP1]], align 8
// NOINFS-NEXT: store float [[F32]], ptr [[F32_ADDR]], align 4
// NOINFS-NEXT: store double [[F64]], ptr [[F64_ADDR]], align 8
// NOINFS-NEXT: store half [[F16]], ptr [[F16_ADDR]], align 2
// NOINFS-NEXT: store <2 x float> [[V2F321]], ptr [[V2F32_ADDR]], align 8
// NOINFS-NEXT: store <2 x double> [[V2F64]], ptr [[V2F64_ADDR]], align 16
// NOINFS-NEXT: store <2 x half> [[V2F162]], ptr [[V2F16_ADDR]], align 4
// NOINFS-NEXT: [[TMP2:%.*]] = load float, ptr [[F32_ADDR]], align 4
// NOINFS-NEXT: [[TMP3:%.*]] = load float, ptr [[F32_ADDR]], align 4
// NOINFS-NEXT: [[CONV:%.*]] = fpext float [[TMP3]] to double
// NOINFS-NEXT: [[TMP4:%.*]] = load double, ptr [[F64_ADDR]], align 8
// NOINFS-NEXT: [[TMP5:%.*]] = load half, ptr [[F16_ADDR]], align 2
// NOINFS-NEXT: [[TMP6:%.*]] = load <2 x float>, ptr [[V2F32_ADDR]], align 8
// NOINFS-NEXT: [[TMP7:%.*]] = load <2 x double>, ptr [[V2F64_ADDR]], align 16
// NOINFS-NEXT: [[TMP8:%.*]] = load <2 x half>, ptr [[V2F16_ADDR]], align 4
// NOINFS-NEXT: [[CF32_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 0
// NOINFS-NEXT: [[CF32_REAL:%.*]] = load float, ptr [[CF32_REALP]], align 4
// NOINFS-NEXT: [[CF32_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 1
// NOINFS-NEXT: [[CF32_IMAG:%.*]] = load float, ptr [[CF32_IMAGP]], align 4
// NOINFS-NEXT: [[CF64_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// NOINFS-NEXT: [[CF64_REAL:%.*]] = load double, ptr [[CF64_REALP]], align 8
// NOINFS-NEXT: [[CF64_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// NOINFS-NEXT: [[CF64_IMAG:%.*]] = load double, ptr [[CF64_IMAGP]], align 8
// NOINFS-NEXT: [[CF16_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 0
// NOINFS-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16_REALP]], align 8
// NOINFS-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 1
// NOINFS-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2
// NOINFS-NEXT: store <2 x float> [[TMP6]], ptr [[COERCE]], align 8
// NOINFS-NEXT: [[TMP9:%.*]] = load double, ptr [[COERCE]], align 8
// NOINFS-NEXT: store <2 x half> [[TMP8]], ptr [[COERCE3]], align 4
// NOINFS-NEXT: [[TMP10:%.*]] = load i32, ptr [[COERCE3]], align 4
// NOINFS-NEXT: [[COERCE4_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE4_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 1
// NOINFS-NEXT: store float [[CF32_REAL]], ptr [[COERCE4_REALP]], align 4
// NOINFS-NEXT: store float [[CF32_IMAG]], ptr [[COERCE4_IMAGP]], align 4
// NOINFS-NEXT: [[TMP11:%.*]] = load <2 x float>, ptr [[COERCE4]], align 4
// NOINFS-NEXT: [[INDIRECT_ARG_TEMP_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 0
// NOINFS-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 1
// NOINFS-NEXT: store double [[CF64_REAL]], ptr [[INDIRECT_ARG_TEMP_REALP]], align 8
// NOINFS-NEXT: store double [[CF64_IMAG]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8
// NOINFS-NEXT: [[COERCE5_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE5_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 1
// NOINFS-NEXT: store half [[CF16_REAL]], ptr [[COERCE5_REALP]], align 2
// NOINFS-NEXT: store half [[CF16_IMAG]], ptr [[COERCE5_IMAGP]], align 2
// NOINFS-NEXT: [[TMP12:%.*]] = load <2 x half>, ptr [[COERCE5]], align 2
// NOINFS-NEXT: [[CALL:%.*]] = call ninf nofpclass(inf) float (float, ...) @variadic(float noundef nofpclass(inf) [[TMP2]], double noundef nofpclass(inf) [[CONV]], double noundef nofpclass(inf) [[TMP4]], half noundef nofpclass(inf) [[TMP5]], double noundef nofpclass(inf) [[TMP9]], <2 x double> noundef nofpclass(inf) [[TMP7]], i32 noundef [[TMP10]], <2 x float> noundef nofpclass(inf) [[TMP11]], ptr noundef byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(inf) [[TMP12]])
// NOINFS-NEXT: ret float [[CALL]]
//
float call_variadic(float f32, double f64, _Float16 f16,
float2 v2f32, double2 v2f64, half2 v2f16,
_Complex float cf32, _Complex double cf64, _Complex _Float16 cf16) {
return variadic(f32, f32, f64, f16, v2f32, v2f64, v2f16, cf32, cf64, cf16);
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_variadic_indirect
// CFINITEONLY-SAME: (ptr noundef [[FPTR:%.*]], float noundef nofpclass(nan inf) [[F32:%.*]], double noundef nofpclass(nan inf) [[F64:%.*]], half noundef nofpclass(nan inf) [[F16:%.*]], double noundef nofpclass(nan inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE1:%.*]], ptr noundef byval({ half, half }) align 8 [[CF16:%.*]]) #[[ATTR2]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[V2F32:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[V2F16:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[CF32:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: [[CF64:%.*]] = alloca { double, double }, align 8
// CFINITEONLY-NEXT: [[FPTR_ADDR:%.*]] = alloca ptr, align 8
// CFINITEONLY-NEXT: [[F32_ADDR:%.*]] = alloca float, align 4
// CFINITEONLY-NEXT: [[F64_ADDR:%.*]] = alloca double, align 8
// CFINITEONLY-NEXT: [[F16_ADDR:%.*]] = alloca half, align 2
// CFINITEONLY-NEXT: [[V2F32_ADDR:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[V2F64_ADDR:%.*]] = alloca <2 x double>, align 16
// CFINITEONLY-NEXT: [[V2F16_ADDR:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// CFINITEONLY-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// CFINITEONLY-NEXT: [[COERCE4:%.*]] = alloca { float, float }, align 4
// CFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca { double, double }, align 8
// CFINITEONLY-NEXT: [[COERCE5:%.*]] = alloca { half, half }, align 2
// CFINITEONLY-NEXT: store double [[V2F32_COERCE]], ptr [[V2F32]], align 8
// CFINITEONLY-NEXT: [[V2F321:%.*]] = load <2 x float>, ptr [[V2F32]], align 8
// CFINITEONLY-NEXT: store i32 [[V2F16_COERCE]], ptr [[V2F16]], align 4
// CFINITEONLY-NEXT: [[V2F162:%.*]] = load <2 x half>, ptr [[V2F16]], align 4
// CFINITEONLY-NEXT: store <2 x float> [[CF32_COERCE]], ptr [[CF32]], align 4
// CFINITEONLY-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// CFINITEONLY-NEXT: store double [[CF64_COERCE0]], ptr [[TMP0]], align 8
// CFINITEONLY-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// CFINITEONLY-NEXT: store double [[CF64_COERCE1]], ptr [[TMP1]], align 8
// CFINITEONLY-NEXT: store ptr [[FPTR]], ptr [[FPTR_ADDR]], align 8
// CFINITEONLY-NEXT: store float [[F32]], ptr [[F32_ADDR]], align 4
// CFINITEONLY-NEXT: store double [[F64]], ptr [[F64_ADDR]], align 8
// CFINITEONLY-NEXT: store half [[F16]], ptr [[F16_ADDR]], align 2
// CFINITEONLY-NEXT: store <2 x float> [[V2F321]], ptr [[V2F32_ADDR]], align 8
// CFINITEONLY-NEXT: store <2 x double> [[V2F64]], ptr [[V2F64_ADDR]], align 16
// CFINITEONLY-NEXT: store <2 x half> [[V2F162]], ptr [[V2F16_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FPTR_ADDR]], align 8
// CFINITEONLY-NEXT: [[TMP3:%.*]] = load float, ptr [[F32_ADDR]], align 4
// CFINITEONLY-NEXT: [[TMP4:%.*]] = load float, ptr [[F32_ADDR]], align 4
// CFINITEONLY-NEXT: [[CONV:%.*]] = fpext float [[TMP4]] to double
// CFINITEONLY-NEXT: [[TMP5:%.*]] = load double, ptr [[F64_ADDR]], align 8
// CFINITEONLY-NEXT: [[TMP6:%.*]] = load half, ptr [[F16_ADDR]], align 2
// CFINITEONLY-NEXT: [[TMP7:%.*]] = load <2 x float>, ptr [[V2F32_ADDR]], align 8
// CFINITEONLY-NEXT: [[TMP8:%.*]] = load <2 x double>, ptr [[V2F64_ADDR]], align 16
// CFINITEONLY-NEXT: [[TMP9:%.*]] = load <2 x half>, ptr [[V2F16_ADDR]], align 4
// CFINITEONLY-NEXT: [[CF32_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 0
// CFINITEONLY-NEXT: [[CF32_REAL:%.*]] = load float, ptr [[CF32_REALP]], align 4
// CFINITEONLY-NEXT: [[CF32_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 1
// CFINITEONLY-NEXT: [[CF32_IMAG:%.*]] = load float, ptr [[CF32_IMAGP]], align 4
// CFINITEONLY-NEXT: [[CF64_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// CFINITEONLY-NEXT: [[CF64_REAL:%.*]] = load double, ptr [[CF64_REALP]], align 8
// CFINITEONLY-NEXT: [[CF64_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// CFINITEONLY-NEXT: [[CF64_IMAG:%.*]] = load double, ptr [[CF64_IMAGP]], align 8
// CFINITEONLY-NEXT: [[CF16_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 0
// CFINITEONLY-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16_REALP]], align 8
// CFINITEONLY-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 1
// CFINITEONLY-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2
// CFINITEONLY-NEXT: store <2 x float> [[TMP7]], ptr [[COERCE]], align 8
// CFINITEONLY-NEXT: [[TMP10:%.*]] = load double, ptr [[COERCE]], align 8
// CFINITEONLY-NEXT: store <2 x half> [[TMP9]], ptr [[COERCE3]], align 4
// CFINITEONLY-NEXT: [[TMP11:%.*]] = load i32, ptr [[COERCE3]], align 4
// CFINITEONLY-NEXT: [[COERCE4_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE4_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 1
// CFINITEONLY-NEXT: store float [[CF32_REAL]], ptr [[COERCE4_REALP]], align 4
// CFINITEONLY-NEXT: store float [[CF32_IMAG]], ptr [[COERCE4_IMAGP]], align 4
// CFINITEONLY-NEXT: [[TMP12:%.*]] = load <2 x float>, ptr [[COERCE4]], align 4
// CFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 0
// CFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 1
// CFINITEONLY-NEXT: store double [[CF64_REAL]], ptr [[INDIRECT_ARG_TEMP_REALP]], align 8
// CFINITEONLY-NEXT: store double [[CF64_IMAG]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8
// CFINITEONLY-NEXT: [[COERCE5_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 0
// CFINITEONLY-NEXT: [[COERCE5_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 1
// CFINITEONLY-NEXT: store half [[CF16_REAL]], ptr [[COERCE5_REALP]], align 2
// CFINITEONLY-NEXT: store half [[CF16_IMAG]], ptr [[COERCE5_IMAGP]], align 2
// CFINITEONLY-NEXT: [[TMP13:%.*]] = load <2 x half>, ptr [[COERCE5]], align 2
// CFINITEONLY-NEXT: [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) float (float, ...) [[TMP2]](float noundef nofpclass(nan inf) [[TMP3]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[TMP5]], half noundef nofpclass(nan inf) [[TMP6]], double noundef nofpclass(nan inf) [[TMP10]], <2 x double> noundef nofpclass(nan inf) [[TMP8]], i32 noundef [[TMP11]], <2 x float> noundef nofpclass(nan inf) [[TMP12]], ptr noundef byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[TMP13]])
// CFINITEONLY-NEXT: ret float [[CALL]]
//
// CLFINITEONLY: Function Attrs: convergent norecurse nounwind
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_variadic_indirect
// CLFINITEONLY-SAME: (ptr nocapture noundef readonly [[FPTR:%.*]], float noundef nofpclass(nan inf) [[F32:%.*]], double noundef nofpclass(nan inf) [[F64:%.*]], half noundef nofpclass(nan inf) [[F16:%.*]], double noundef nofpclass(nan inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE1:%.*]], ptr nocapture noundef readonly byval({ half, half }) align 8 [[CF16:%.*]]) local_unnamed_addr #[[ATTR5]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca { double, double }, align 8
// CLFINITEONLY-NEXT: [[CONV:%.*]] = fpext float [[F32]] to double
// CLFINITEONLY-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16]], align 8
// CLFINITEONLY-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds i8, ptr [[CF16]], i64 2
// CLFINITEONLY-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2
// CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds i8, ptr [[INDIRECT_ARG_TEMP]], i64 8
// CLFINITEONLY-NEXT: store double [[CF64_COERCE0]], ptr [[INDIRECT_ARG_TEMP]], align 8
// CLFINITEONLY-NEXT: store double [[CF64_COERCE1]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8
// CLFINITEONLY-NEXT: [[COERCE5_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> poison, half [[CF16_REAL]], i64 0
// CLFINITEONLY-NEXT: [[COERCE5_SROA_0_2_VEC_INSERT:%.*]] = insertelement <2 x half> [[COERCE5_SROA_0_0_VEC_INSERT]], half [[CF16_IMAG]], i64 1
// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float (float, ...) [[FPTR]](float noundef nofpclass(nan inf) [[F32]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[F64]], half noundef nofpclass(nan inf) [[F16]], double noundef nofpclass(nan inf) [[V2F32_COERCE]], <2 x double> noundef nofpclass(nan inf) [[V2F64]], i32 noundef [[V2F16_COERCE]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE]], ptr noundef nonnull byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[COERCE5_SROA_0_2_VEC_INSERT]]) #[[ATTR10]]
// CLFINITEONLY-NEXT: ret float [[CALL]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) float @call_variadic_indirect
// NONANS-SAME: (ptr noundef [[FPTR:%.*]], float noundef nofpclass(nan) [[F32:%.*]], double noundef nofpclass(nan) [[F64:%.*]], half noundef nofpclass(nan) [[F16:%.*]], double noundef nofpclass(nan) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan) [[CF32_COERCE:%.*]], double noundef nofpclass(nan) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan) [[CF64_COERCE1:%.*]], ptr noundef byval({ half, half }) align 8 [[CF16:%.*]]) #[[ATTR2]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[V2F32:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[V2F16:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[CF32:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: [[CF64:%.*]] = alloca { double, double }, align 8
// NONANS-NEXT: [[FPTR_ADDR:%.*]] = alloca ptr, align 8
// NONANS-NEXT: [[F32_ADDR:%.*]] = alloca float, align 4
// NONANS-NEXT: [[F64_ADDR:%.*]] = alloca double, align 8
// NONANS-NEXT: [[F16_ADDR:%.*]] = alloca half, align 2
// NONANS-NEXT: [[V2F32_ADDR:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[V2F64_ADDR:%.*]] = alloca <2 x double>, align 16
// NONANS-NEXT: [[V2F16_ADDR:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// NONANS-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// NONANS-NEXT: [[COERCE4:%.*]] = alloca { float, float }, align 4
// NONANS-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca { double, double }, align 8
// NONANS-NEXT: [[COERCE5:%.*]] = alloca { half, half }, align 2
// NONANS-NEXT: store double [[V2F32_COERCE]], ptr [[V2F32]], align 8
// NONANS-NEXT: [[V2F321:%.*]] = load <2 x float>, ptr [[V2F32]], align 8
// NONANS-NEXT: store i32 [[V2F16_COERCE]], ptr [[V2F16]], align 4
// NONANS-NEXT: [[V2F162:%.*]] = load <2 x half>, ptr [[V2F16]], align 4
// NONANS-NEXT: store <2 x float> [[CF32_COERCE]], ptr [[CF32]], align 4
// NONANS-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// NONANS-NEXT: store double [[CF64_COERCE0]], ptr [[TMP0]], align 8
// NONANS-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// NONANS-NEXT: store double [[CF64_COERCE1]], ptr [[TMP1]], align 8
// NONANS-NEXT: store ptr [[FPTR]], ptr [[FPTR_ADDR]], align 8
// NONANS-NEXT: store float [[F32]], ptr [[F32_ADDR]], align 4
// NONANS-NEXT: store double [[F64]], ptr [[F64_ADDR]], align 8
// NONANS-NEXT: store half [[F16]], ptr [[F16_ADDR]], align 2
// NONANS-NEXT: store <2 x float> [[V2F321]], ptr [[V2F32_ADDR]], align 8
// NONANS-NEXT: store <2 x double> [[V2F64]], ptr [[V2F64_ADDR]], align 16
// NONANS-NEXT: store <2 x half> [[V2F162]], ptr [[V2F16_ADDR]], align 4
// NONANS-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FPTR_ADDR]], align 8
// NONANS-NEXT: [[TMP3:%.*]] = load float, ptr [[F32_ADDR]], align 4
// NONANS-NEXT: [[TMP4:%.*]] = load float, ptr [[F32_ADDR]], align 4
// NONANS-NEXT: [[CONV:%.*]] = fpext float [[TMP4]] to double
// NONANS-NEXT: [[TMP5:%.*]] = load double, ptr [[F64_ADDR]], align 8
// NONANS-NEXT: [[TMP6:%.*]] = load half, ptr [[F16_ADDR]], align 2
// NONANS-NEXT: [[TMP7:%.*]] = load <2 x float>, ptr [[V2F32_ADDR]], align 8
// NONANS-NEXT: [[TMP8:%.*]] = load <2 x double>, ptr [[V2F64_ADDR]], align 16
// NONANS-NEXT: [[TMP9:%.*]] = load <2 x half>, ptr [[V2F16_ADDR]], align 4
// NONANS-NEXT: [[CF32_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 0
// NONANS-NEXT: [[CF32_REAL:%.*]] = load float, ptr [[CF32_REALP]], align 4
// NONANS-NEXT: [[CF32_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 1
// NONANS-NEXT: [[CF32_IMAG:%.*]] = load float, ptr [[CF32_IMAGP]], align 4
// NONANS-NEXT: [[CF64_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// NONANS-NEXT: [[CF64_REAL:%.*]] = load double, ptr [[CF64_REALP]], align 8
// NONANS-NEXT: [[CF64_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// NONANS-NEXT: [[CF64_IMAG:%.*]] = load double, ptr [[CF64_IMAGP]], align 8
// NONANS-NEXT: [[CF16_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 0
// NONANS-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16_REALP]], align 8
// NONANS-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 1
// NONANS-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2
// NONANS-NEXT: store <2 x float> [[TMP7]], ptr [[COERCE]], align 8
// NONANS-NEXT: [[TMP10:%.*]] = load double, ptr [[COERCE]], align 8
// NONANS-NEXT: store <2 x half> [[TMP9]], ptr [[COERCE3]], align 4
// NONANS-NEXT: [[TMP11:%.*]] = load i32, ptr [[COERCE3]], align 4
// NONANS-NEXT: [[COERCE4_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 0
// NONANS-NEXT: [[COERCE4_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 1
// NONANS-NEXT: store float [[CF32_REAL]], ptr [[COERCE4_REALP]], align 4
// NONANS-NEXT: store float [[CF32_IMAG]], ptr [[COERCE4_IMAGP]], align 4
// NONANS-NEXT: [[TMP12:%.*]] = load <2 x float>, ptr [[COERCE4]], align 4
// NONANS-NEXT: [[INDIRECT_ARG_TEMP_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 0
// NONANS-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 1
// NONANS-NEXT: store double [[CF64_REAL]], ptr [[INDIRECT_ARG_TEMP_REALP]], align 8
// NONANS-NEXT: store double [[CF64_IMAG]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8
// NONANS-NEXT: [[COERCE5_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 0
// NONANS-NEXT: [[COERCE5_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 1
// NONANS-NEXT: store half [[CF16_REAL]], ptr [[COERCE5_REALP]], align 2
// NONANS-NEXT: store half [[CF16_IMAG]], ptr [[COERCE5_IMAGP]], align 2
// NONANS-NEXT: [[TMP13:%.*]] = load <2 x half>, ptr [[COERCE5]], align 2
// NONANS-NEXT: [[CALL:%.*]] = call nnan nofpclass(nan) float (float, ...) [[TMP2]](float noundef nofpclass(nan) [[TMP3]], double noundef nofpclass(nan) [[CONV]], double noundef nofpclass(nan) [[TMP5]], half noundef nofpclass(nan) [[TMP6]], double noundef nofpclass(nan) [[TMP10]], <2 x double> noundef nofpclass(nan) [[TMP8]], i32 noundef [[TMP11]], <2 x float> noundef nofpclass(nan) [[TMP12]], ptr noundef byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan) [[TMP13]])
// NONANS-NEXT: ret float [[CALL]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) float @call_variadic_indirect
// NOINFS-SAME: (ptr noundef [[FPTR:%.*]], float noundef nofpclass(inf) [[F32:%.*]], double noundef nofpclass(inf) [[F64:%.*]], half noundef nofpclass(inf) [[F16:%.*]], double noundef nofpclass(inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(inf) [[CF32_COERCE:%.*]], double noundef nofpclass(inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(inf) [[CF64_COERCE1:%.*]], ptr noundef byval({ half, half }) align 8 [[CF16:%.*]]) #[[ATTR2]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[V2F32:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[V2F16:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[CF32:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: [[CF64:%.*]] = alloca { double, double }, align 8
// NOINFS-NEXT: [[FPTR_ADDR:%.*]] = alloca ptr, align 8
// NOINFS-NEXT: [[F32_ADDR:%.*]] = alloca float, align 4
// NOINFS-NEXT: [[F64_ADDR:%.*]] = alloca double, align 8
// NOINFS-NEXT: [[F16_ADDR:%.*]] = alloca half, align 2
// NOINFS-NEXT: [[V2F32_ADDR:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[V2F64_ADDR:%.*]] = alloca <2 x double>, align 16
// NOINFS-NEXT: [[V2F16_ADDR:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[COERCE:%.*]] = alloca <2 x float>, align 8
// NOINFS-NEXT: [[COERCE3:%.*]] = alloca <2 x half>, align 4
// NOINFS-NEXT: [[COERCE4:%.*]] = alloca { float, float }, align 4
// NOINFS-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca { double, double }, align 8
// NOINFS-NEXT: [[COERCE5:%.*]] = alloca { half, half }, align 2
// NOINFS-NEXT: store double [[V2F32_COERCE]], ptr [[V2F32]], align 8
// NOINFS-NEXT: [[V2F321:%.*]] = load <2 x float>, ptr [[V2F32]], align 8
// NOINFS-NEXT: store i32 [[V2F16_COERCE]], ptr [[V2F16]], align 4
// NOINFS-NEXT: [[V2F162:%.*]] = load <2 x half>, ptr [[V2F16]], align 4
// NOINFS-NEXT: store <2 x float> [[CF32_COERCE]], ptr [[CF32]], align 4
// NOINFS-NEXT: [[TMP0:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// NOINFS-NEXT: store double [[CF64_COERCE0]], ptr [[TMP0]], align 8
// NOINFS-NEXT: [[TMP1:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// NOINFS-NEXT: store double [[CF64_COERCE1]], ptr [[TMP1]], align 8
// NOINFS-NEXT: store ptr [[FPTR]], ptr [[FPTR_ADDR]], align 8
// NOINFS-NEXT: store float [[F32]], ptr [[F32_ADDR]], align 4
// NOINFS-NEXT: store double [[F64]], ptr [[F64_ADDR]], align 8
// NOINFS-NEXT: store half [[F16]], ptr [[F16_ADDR]], align 2
// NOINFS-NEXT: store <2 x float> [[V2F321]], ptr [[V2F32_ADDR]], align 8
// NOINFS-NEXT: store <2 x double> [[V2F64]], ptr [[V2F64_ADDR]], align 16
// NOINFS-NEXT: store <2 x half> [[V2F162]], ptr [[V2F16_ADDR]], align 4
// NOINFS-NEXT: [[TMP2:%.*]] = load ptr, ptr [[FPTR_ADDR]], align 8
// NOINFS-NEXT: [[TMP3:%.*]] = load float, ptr [[F32_ADDR]], align 4
// NOINFS-NEXT: [[TMP4:%.*]] = load float, ptr [[F32_ADDR]], align 4
// NOINFS-NEXT: [[CONV:%.*]] = fpext float [[TMP4]] to double
// NOINFS-NEXT: [[TMP5:%.*]] = load double, ptr [[F64_ADDR]], align 8
// NOINFS-NEXT: [[TMP6:%.*]] = load half, ptr [[F16_ADDR]], align 2
// NOINFS-NEXT: [[TMP7:%.*]] = load <2 x float>, ptr [[V2F32_ADDR]], align 8
// NOINFS-NEXT: [[TMP8:%.*]] = load <2 x double>, ptr [[V2F64_ADDR]], align 16
// NOINFS-NEXT: [[TMP9:%.*]] = load <2 x half>, ptr [[V2F16_ADDR]], align 4
// NOINFS-NEXT: [[CF32_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 0
// NOINFS-NEXT: [[CF32_REAL:%.*]] = load float, ptr [[CF32_REALP]], align 4
// NOINFS-NEXT: [[CF32_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[CF32]], i32 0, i32 1
// NOINFS-NEXT: [[CF32_IMAG:%.*]] = load float, ptr [[CF32_IMAGP]], align 4
// NOINFS-NEXT: [[CF64_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 0
// NOINFS-NEXT: [[CF64_REAL:%.*]] = load double, ptr [[CF64_REALP]], align 8
// NOINFS-NEXT: [[CF64_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[CF64]], i32 0, i32 1
// NOINFS-NEXT: [[CF64_IMAG:%.*]] = load double, ptr [[CF64_IMAGP]], align 8
// NOINFS-NEXT: [[CF16_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 0
// NOINFS-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16_REALP]], align 8
// NOINFS-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[CF16]], i32 0, i32 1
// NOINFS-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2
// NOINFS-NEXT: store <2 x float> [[TMP7]], ptr [[COERCE]], align 8
// NOINFS-NEXT: [[TMP10:%.*]] = load double, ptr [[COERCE]], align 8
// NOINFS-NEXT: store <2 x half> [[TMP9]], ptr [[COERCE3]], align 4
// NOINFS-NEXT: [[TMP11:%.*]] = load i32, ptr [[COERCE3]], align 4
// NOINFS-NEXT: [[COERCE4_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE4_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[COERCE4]], i32 0, i32 1
// NOINFS-NEXT: store float [[CF32_REAL]], ptr [[COERCE4_REALP]], align 4
// NOINFS-NEXT: store float [[CF32_IMAG]], ptr [[COERCE4_IMAGP]], align 4
// NOINFS-NEXT: [[TMP12:%.*]] = load <2 x float>, ptr [[COERCE4]], align 4
// NOINFS-NEXT: [[INDIRECT_ARG_TEMP_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 0
// NOINFS-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i32 0, i32 1
// NOINFS-NEXT: store double [[CF64_REAL]], ptr [[INDIRECT_ARG_TEMP_REALP]], align 8
// NOINFS-NEXT: store double [[CF64_IMAG]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8
// NOINFS-NEXT: [[COERCE5_REALP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 0
// NOINFS-NEXT: [[COERCE5_IMAGP:%.*]] = getelementptr inbounds { half, half }, ptr [[COERCE5]], i32 0, i32 1
// NOINFS-NEXT: store half [[CF16_REAL]], ptr [[COERCE5_REALP]], align 2
// NOINFS-NEXT: store half [[CF16_IMAG]], ptr [[COERCE5_IMAGP]], align 2
// NOINFS-NEXT: [[TMP13:%.*]] = load <2 x half>, ptr [[COERCE5]], align 2
// NOINFS-NEXT: [[CALL:%.*]] = call ninf nofpclass(inf) float (float, ...) [[TMP2]](float noundef nofpclass(inf) [[TMP3]], double noundef nofpclass(inf) [[CONV]], double noundef nofpclass(inf) [[TMP5]], half noundef nofpclass(inf) [[TMP6]], double noundef nofpclass(inf) [[TMP10]], <2 x double> noundef nofpclass(inf) [[TMP8]], i32 noundef [[TMP11]], <2 x float> noundef nofpclass(inf) [[TMP12]], ptr noundef byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(inf) [[TMP13]])
// NOINFS-NEXT: ret float [[CALL]]
//
float call_variadic_indirect(float fptr(float, ...), float f32, double f64, _Float16 f16,
float2 v2f32, double2 v2f64, half2 v2f16,
_Complex float cf32, _Complex double cf64, _Complex _Float16 cf16) {
return (*fptr)(f32, f32, f64, f16, v2f32, v2f64, v2f16, cf32, cf64, cf16);
}
typedef __attribute__((__vector_size__(4 * sizeof(double)))) double __m256d;
extern __m256d extern_m256d(__m256d, ...);
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <4 x double> @call_m256d
// CFINITEONLY-SAME: (<4 x double> noundef nofpclass(nan inf) [[X:%.*]]) #[[ATTR5:[0-9]+]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[X_ADDR:%.*]] = alloca <4 x double>, align 32
// CFINITEONLY-NEXT: store <4 x double> [[X]], ptr [[X_ADDR]], align 32
// CFINITEONLY-NEXT: [[TMP0:%.*]] = load <4 x double>, ptr [[X_ADDR]], align 32
// CFINITEONLY-NEXT: [[TMP1:%.*]] = load <4 x double>, ptr [[X_ADDR]], align 32
// CFINITEONLY-NEXT: [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) <4 x double> (<4 x double>, ...) @extern_m256d(<4 x double> noundef nofpclass(nan inf) [[TMP0]], <4 x double> noundef nofpclass(nan inf) [[TMP1]])
// CFINITEONLY-NEXT: ret <4 x double> [[CALL]]
//
// CLFINITEONLY: Function Attrs: convergent norecurse nounwind
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <4 x double> @call_m256d
// CLFINITEONLY-SAME: (<4 x double> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <4 x double> (<4 x double>, ...) @extern_m256d(<4 x double> noundef nofpclass(nan inf) [[X]], <4 x double> noundef nofpclass(nan inf) [[X]]) #[[ATTR10]]
// CLFINITEONLY-NEXT: ret <4 x double> [[CALL]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) <4 x double> @call_m256d
// NONANS-SAME: (<4 x double> noundef nofpclass(nan) [[X:%.*]]) #[[ATTR5:[0-9]+]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[X_ADDR:%.*]] = alloca <4 x double>, align 32
// NONANS-NEXT: store <4 x double> [[X]], ptr [[X_ADDR]], align 32
// NONANS-NEXT: [[TMP0:%.*]] = load <4 x double>, ptr [[X_ADDR]], align 32
// NONANS-NEXT: [[TMP1:%.*]] = load <4 x double>, ptr [[X_ADDR]], align 32
// NONANS-NEXT: [[CALL:%.*]] = call nnan nofpclass(nan) <4 x double> (<4 x double>, ...) @extern_m256d(<4 x double> noundef nofpclass(nan) [[TMP0]], <4 x double> noundef nofpclass(nan) [[TMP1]])
// NONANS-NEXT: ret <4 x double> [[CALL]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) <4 x double> @call_m256d
// NOINFS-SAME: (<4 x double> noundef nofpclass(inf) [[X:%.*]]) #[[ATTR5:[0-9]+]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[X_ADDR:%.*]] = alloca <4 x double>, align 32
// NOINFS-NEXT: store <4 x double> [[X]], ptr [[X_ADDR]], align 32
// NOINFS-NEXT: [[TMP0:%.*]] = load <4 x double>, ptr [[X_ADDR]], align 32
// NOINFS-NEXT: [[TMP1:%.*]] = load <4 x double>, ptr [[X_ADDR]], align 32
// NOINFS-NEXT: [[CALL:%.*]] = call ninf nofpclass(inf) <4 x double> (<4 x double>, ...) @extern_m256d(<4 x double> noundef nofpclass(inf) [[TMP0]], <4 x double> noundef nofpclass(inf) [[TMP1]])
// NOINFS-NEXT: ret <4 x double> [[CALL]]
//
__m256d call_m256d(__m256d x) {
return extern_m256d(x, x);
}
// CFINITEONLY: Function Attrs: noinline nounwind optnone
// CFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <25 x double> @call_matrix
// CFINITEONLY-SAME: (<25 x double> noundef nofpclass(nan inf) [[X:%.*]]) #[[ATTR6:[0-9]+]] {
// CFINITEONLY-NEXT: entry:
// CFINITEONLY-NEXT: [[X_ADDR:%.*]] = alloca [25 x double], align 8
// CFINITEONLY-NEXT: store <25 x double> [[X]], ptr [[X_ADDR]], align 8
// CFINITEONLY-NEXT: [[TMP0:%.*]] = load <25 x double>, ptr [[X_ADDR]], align 8
// CFINITEONLY-NEXT: [[CALL:%.*]] = call nnan ninf nofpclass(nan inf) <25 x double> @extern_matrix(<25 x double> noundef nofpclass(nan inf) [[TMP0]])
// CFINITEONLY-NEXT: ret <25 x double> [[CALL]]
//
// CLFINITEONLY: Function Attrs: convergent norecurse nounwind
// CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <25 x double> @call_matrix
// CLFINITEONLY-SAME: (<25 x double> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR9:[0-9]+]] {
// CLFINITEONLY-NEXT: entry:
// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <25 x double> @extern_matrix(<25 x double> noundef nofpclass(nan inf) [[X]]) #[[ATTR10]]
// CLFINITEONLY-NEXT: ret <25 x double> [[CALL]]
//
// NONANS: Function Attrs: noinline nounwind optnone
// NONANS-LABEL: define dso_local nofpclass(nan) <25 x double> @call_matrix
// NONANS-SAME: (<25 x double> noundef nofpclass(nan) [[X:%.*]]) #[[ATTR6:[0-9]+]] {
// NONANS-NEXT: entry:
// NONANS-NEXT: [[X_ADDR:%.*]] = alloca [25 x double], align 8
// NONANS-NEXT: store <25 x double> [[X]], ptr [[X_ADDR]], align 8
// NONANS-NEXT: [[TMP0:%.*]] = load <25 x double>, ptr [[X_ADDR]], align 8
// NONANS-NEXT: [[CALL:%.*]] = call nnan nofpclass(nan) <25 x double> @extern_matrix(<25 x double> noundef nofpclass(nan) [[TMP0]])
// NONANS-NEXT: ret <25 x double> [[CALL]]
//
// NOINFS: Function Attrs: noinline nounwind optnone
// NOINFS-LABEL: define dso_local nofpclass(inf) <25 x double> @call_matrix
// NOINFS-SAME: (<25 x double> noundef nofpclass(inf) [[X:%.*]]) #[[ATTR6:[0-9]+]] {
// NOINFS-NEXT: entry:
// NOINFS-NEXT: [[X_ADDR:%.*]] = alloca [25 x double], align 8
// NOINFS-NEXT: store <25 x double> [[X]], ptr [[X_ADDR]], align 8
// NOINFS-NEXT: [[TMP0:%.*]] = load <25 x double>, ptr [[X_ADDR]], align 8
// NOINFS-NEXT: [[CALL:%.*]] = call ninf nofpclass(inf) <25 x double> @extern_matrix(<25 x double> noundef nofpclass(inf) [[TMP0]])
// NOINFS-NEXT: ret <25 x double> [[CALL]]
//
dx5x5_t call_matrix(dx5x5_t x) {
return extern_matrix(x);
}