// 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]], // 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]], // 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]], // 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]], // 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 { half, half }, ptr [[CF16]], i64 0, i32 1 // CLFINITEONLY-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2 // CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i64 0, i32 1 // 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 { half, half }, ptr [[CF16]], i64 0, i32 1 // CLFINITEONLY-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2 // CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[INDIRECT_ARG_TEMP]], i64 0, i32 1 // 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); }