| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 |
| // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ |
| // RUN: -o - | FileCheck %s --check-prefix=FULL |
| |
| // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ |
| // RUN: -complex-range=basic -o - | FileCheck %s --check-prefix=BASIC |
| |
| // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ |
| // RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL |
| |
| // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ |
| // RUN: -complex-range=improved -o - | FileCheck %s --check-prefix=IMPRVD |
| |
| // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ |
| // RUN: -complex-range=promoted -o - | FileCheck %s --check-prefix=PRMTD |
| |
| // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ |
| // RUN: -complex-range=full -o - | FileCheck %s --check-prefix=FULL |
| |
| // RUN: %clang_cc1 -triple x86_64-windows-pc -complex-range=promoted \ |
| // RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=X86WINPRMTD |
| |
| // Fast math |
| // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ |
| // RUN: -ffast-math -complex-range=basic -emit-llvm -o - %s \ |
| // RUN: | FileCheck %s --check-prefix=BASIC_FAST |
| |
| // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ |
| // RUN: -ffast-math -complex-range=full -emit-llvm -o - %s \ |
| // RUN: | FileCheck %s --check-prefix=FULL_FAST |
| |
| // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ |
| // RUN: -fno-cx-fortran-rules -o - | FileCheck %s --check-prefix=FULL |
| |
| // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ |
| // RUN: -ffast-math -complex-range=improved -emit-llvm -o - %s \ |
| // RUN: | FileCheck %s --check-prefix=IMPRVD_FAST |
| |
| // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \ |
| // RUN: -ffast-math -complex-range=promoted -emit-llvm -o - %s \ |
| // RUN: | FileCheck %s --check-prefix=PRMTD_FAST |
| |
| // FULL-LABEL: define dso_local <2 x half> @divf16( |
| // FULL-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // FULL-NEXT: entry: |
| // FULL-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 |
| // FULL-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // FULL-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // FULL-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // FULL-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // FULL-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // FULL-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // FULL-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // FULL-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // FULL-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // FULL-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // FULL-NEXT: [[CALL:%.*]] = call <2 x float> @__divsc3(float noundef [[EXT]], float noundef [[EXT1]], float noundef [[EXT2]], float noundef [[EXT3]]) #[[ATTR1:[0-9]+]] |
| // FULL-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 |
| // FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0 |
| // FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 |
| // FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1 |
| // FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 |
| // FULL-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[COERCE_REAL]] to half |
| // FULL-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[COERCE_IMAG]] to half |
| // FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // FULL-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // FULL-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // FULL-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // FULL-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // BASIC-LABEL: define dso_local <2 x half> @divf16( |
| // BASIC-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // BASIC-NEXT: entry: |
| // BASIC-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // BASIC-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // BASIC-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // BASIC-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // BASIC-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // BASIC-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // BASIC-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // BASIC-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // BASIC-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // BASIC-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // BASIC-NEXT: [[TMP0:%.*]] = fmul float [[EXT]], [[EXT2]] |
| // BASIC-NEXT: [[TMP1:%.*]] = fmul float [[EXT1]], [[EXT3]] |
| // BASIC-NEXT: [[TMP2:%.*]] = fadd float [[TMP0]], [[TMP1]] |
| // BASIC-NEXT: [[TMP3:%.*]] = fmul float [[EXT2]], [[EXT2]] |
| // BASIC-NEXT: [[TMP4:%.*]] = fmul float [[EXT3]], [[EXT3]] |
| // BASIC-NEXT: [[TMP5:%.*]] = fadd float [[TMP3]], [[TMP4]] |
| // BASIC-NEXT: [[TMP6:%.*]] = fmul float [[EXT1]], [[EXT2]] |
| // BASIC-NEXT: [[TMP7:%.*]] = fmul float [[EXT]], [[EXT3]] |
| // BASIC-NEXT: [[TMP8:%.*]] = fsub float [[TMP6]], [[TMP7]] |
| // BASIC-NEXT: [[TMP9:%.*]] = fdiv float [[TMP2]], [[TMP5]] |
| // BASIC-NEXT: [[TMP10:%.*]] = fdiv float [[TMP8]], [[TMP5]] |
| // BASIC-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP9]] to half |
| // BASIC-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP10]] to half |
| // BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // BASIC-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // BASIC-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // BASIC-NEXT: [[TMP11:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // BASIC-NEXT: ret <2 x half> [[TMP11]] |
| // |
| // IMPRVD-LABEL: define dso_local <2 x half> @divf16( |
| // IMPRVD-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // IMPRVD-NEXT: entry: |
| // IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // IMPRVD-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // IMPRVD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // IMPRVD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // IMPRVD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // IMPRVD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // IMPRVD-NEXT: [[TMP0:%.*]] = call float @llvm.fabs.f32(float [[EXT2]]) |
| // IMPRVD-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[EXT3]]) |
| // IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP0]], [[TMP1]] |
| // IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] |
| // IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: |
| // IMPRVD-NEXT: [[TMP2:%.*]] = fdiv float [[EXT3]], [[EXT2]] |
| // IMPRVD-NEXT: [[TMP3:%.*]] = fmul float [[TMP2]], [[EXT3]] |
| // IMPRVD-NEXT: [[TMP4:%.*]] = fadd float [[EXT2]], [[TMP3]] |
| // IMPRVD-NEXT: [[TMP5:%.*]] = fmul float [[EXT1]], [[TMP2]] |
| // IMPRVD-NEXT: [[TMP6:%.*]] = fadd float [[EXT]], [[TMP5]] |
| // IMPRVD-NEXT: [[TMP7:%.*]] = fdiv float [[TMP6]], [[TMP4]] |
| // IMPRVD-NEXT: [[TMP8:%.*]] = fmul float [[EXT]], [[TMP2]] |
| // IMPRVD-NEXT: [[TMP9:%.*]] = fsub float [[EXT1]], [[TMP8]] |
| // IMPRVD-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP4]] |
| // IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] |
| // IMPRVD: abs_rhsr_less_than_abs_rhsi: |
| // IMPRVD-NEXT: [[TMP11:%.*]] = fdiv float [[EXT2]], [[EXT3]] |
| // IMPRVD-NEXT: [[TMP12:%.*]] = fmul float [[TMP11]], [[EXT2]] |
| // IMPRVD-NEXT: [[TMP13:%.*]] = fadd float [[EXT3]], [[TMP12]] |
| // IMPRVD-NEXT: [[TMP14:%.*]] = fmul float [[EXT]], [[TMP11]] |
| // IMPRVD-NEXT: [[TMP15:%.*]] = fadd float [[TMP14]], [[EXT1]] |
| // IMPRVD-NEXT: [[TMP16:%.*]] = fdiv float [[TMP15]], [[TMP13]] |
| // IMPRVD-NEXT: [[TMP17:%.*]] = fmul float [[EXT1]], [[TMP11]] |
| // IMPRVD-NEXT: [[TMP18:%.*]] = fsub float [[TMP17]], [[EXT]] |
| // IMPRVD-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP13]] |
| // IMPRVD-NEXT: br label [[COMPLEX_DIV]] |
| // IMPRVD: complex_div: |
| // IMPRVD-NEXT: [[TMP20:%.*]] = phi float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // IMPRVD-NEXT: [[TMP21:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // IMPRVD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP20]] to half |
| // IMPRVD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP21]] to half |
| // IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // IMPRVD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // IMPRVD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[TMP22:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // IMPRVD-NEXT: ret <2 x half> [[TMP22]] |
| // |
| // PRMTD-LABEL: define dso_local <2 x half> @divf16( |
| // PRMTD-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // PRMTD-NEXT: entry: |
| // PRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // PRMTD-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // PRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // PRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // PRMTD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // PRMTD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // PRMTD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // PRMTD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // PRMTD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // PRMTD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // PRMTD-NEXT: [[TMP0:%.*]] = fmul float [[EXT]], [[EXT2]] |
| // PRMTD-NEXT: [[TMP1:%.*]] = fmul float [[EXT1]], [[EXT3]] |
| // PRMTD-NEXT: [[TMP2:%.*]] = fadd float [[TMP0]], [[TMP1]] |
| // PRMTD-NEXT: [[TMP3:%.*]] = fmul float [[EXT2]], [[EXT2]] |
| // PRMTD-NEXT: [[TMP4:%.*]] = fmul float [[EXT3]], [[EXT3]] |
| // PRMTD-NEXT: [[TMP5:%.*]] = fadd float [[TMP3]], [[TMP4]] |
| // PRMTD-NEXT: [[TMP6:%.*]] = fmul float [[EXT1]], [[EXT2]] |
| // PRMTD-NEXT: [[TMP7:%.*]] = fmul float [[EXT]], [[EXT3]] |
| // PRMTD-NEXT: [[TMP8:%.*]] = fsub float [[TMP6]], [[TMP7]] |
| // PRMTD-NEXT: [[TMP9:%.*]] = fdiv float [[TMP2]], [[TMP5]] |
| // PRMTD-NEXT: [[TMP10:%.*]] = fdiv float [[TMP8]], [[TMP5]] |
| // PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP9]] to half |
| // PRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP10]] to half |
| // PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // PRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // PRMTD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // PRMTD-NEXT: [[TMP11:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // PRMTD-NEXT: ret <2 x half> [[TMP11]] |
| // |
| // X86WINPRMTD-LABEL: define dso_local i32 @divf16( |
| // X86WINPRMTD-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // X86WINPRMTD-NEXT: entry: |
| // X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 2 |
| // X86WINPRMTD-NEXT: store i32 [[B_COERCE]], ptr [[B]], align 2 |
| // X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // X86WINPRMTD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // X86WINPRMTD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // X86WINPRMTD-NEXT: [[TMP0:%.*]] = fmul float [[EXT]], [[EXT2]] |
| // X86WINPRMTD-NEXT: [[TMP1:%.*]] = fmul float [[EXT1]], [[EXT3]] |
| // X86WINPRMTD-NEXT: [[TMP2:%.*]] = fadd float [[TMP0]], [[TMP1]] |
| // X86WINPRMTD-NEXT: [[TMP3:%.*]] = fmul float [[EXT2]], [[EXT2]] |
| // X86WINPRMTD-NEXT: [[TMP4:%.*]] = fmul float [[EXT3]], [[EXT3]] |
| // X86WINPRMTD-NEXT: [[TMP5:%.*]] = fadd float [[TMP3]], [[TMP4]] |
| // X86WINPRMTD-NEXT: [[TMP6:%.*]] = fmul float [[EXT1]], [[EXT2]] |
| // X86WINPRMTD-NEXT: [[TMP7:%.*]] = fmul float [[EXT]], [[EXT3]] |
| // X86WINPRMTD-NEXT: [[TMP8:%.*]] = fsub float [[TMP6]], [[TMP7]] |
| // X86WINPRMTD-NEXT: [[TMP9:%.*]] = fdiv float [[TMP2]], [[TMP5]] |
| // X86WINPRMTD-NEXT: [[TMP10:%.*]] = fdiv float [[TMP8]], [[TMP5]] |
| // X86WINPRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP9]] to half |
| // X86WINPRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[TMP10]] to half |
| // X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // X86WINPRMTD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[TMP11:%.*]] = load i32, ptr [[RETVAL]], align 2 |
| // X86WINPRMTD-NEXT: ret i32 [[TMP11]] |
| // |
| // BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @divf16( |
| // BASIC_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // BASIC_FAST-NEXT: entry: |
| // BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // BASIC_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // BASIC_FAST-NEXT: [[EXT1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[EXT2:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_REAL]] to float |
| // BASIC_FAST-NEXT: [[EXT3:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_IMAG]] to float |
| // BASIC_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] |
| // BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] |
| // BASIC_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP0]], [[TMP1]] |
| // BASIC_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT2]], [[EXT2]] |
| // BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT3]], [[EXT3]] |
| // BASIC_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP3]], [[TMP4]] |
| // BASIC_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] |
| // BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] |
| // BASIC_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP6]], [[TMP7]] |
| // BASIC_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP2]], [[TMP5]] |
| // BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP8]], [[TMP5]] |
| // BASIC_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP9]] to half |
| // BASIC_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP10]] to half |
| // BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // BASIC_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[TMP11:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // BASIC_FAST-NEXT: ret <2 x half> [[TMP11]] |
| // |
| // FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @divf16( |
| // FULL_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // FULL_FAST-NEXT: entry: |
| // FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 |
| // FULL_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // FULL_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // FULL_FAST-NEXT: [[EXT1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[EXT2:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_REAL]] to float |
| // FULL_FAST-NEXT: [[EXT3:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_IMAG]] to float |
| // FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__divsc3(float noundef nofpclass(nan inf) [[EXT]], float noundef nofpclass(nan inf) [[EXT1]], float noundef nofpclass(nan inf) [[EXT2]], float noundef nofpclass(nan inf) [[EXT3]]) #[[ATTR1:[0-9]+]] |
| // FULL_FAST-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 |
| // FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 |
| // FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 |
| // FULL_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[COERCE_REAL]] to half |
| // FULL_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[COERCE_IMAG]] to half |
| // FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // FULL_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // FULL_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // FULL_FAST-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @divf16( |
| // IMPRVD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // IMPRVD_FAST-NEXT: entry: |
| // IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // IMPRVD_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // IMPRVD_FAST-NEXT: [[EXT1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[EXT2:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_REAL]] to float |
| // IMPRVD_FAST-NEXT: [[EXT3:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_IMAG]] to float |
| // IMPRVD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[EXT2]]) |
| // IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[EXT3]]) |
| // IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt float [[TMP0]], [[TMP1]] |
| // IMPRVD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] |
| // IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: |
| // IMPRVD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[EXT3]], [[EXT2]] |
| // IMPRVD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP2]], [[EXT3]] |
| // IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT2]], [[TMP3]] |
| // IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[TMP2]] |
| // IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP5]] |
| // IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP6]], [[TMP4]] |
| // IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP2]] |
| // IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[EXT1]], [[TMP8]] |
| // IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP9]], [[TMP4]] |
| // IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] |
| // IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi: |
| // IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[EXT2]], [[EXT3]] |
| // IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP11]], [[EXT2]] |
| // IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT3]], [[TMP12]] |
| // IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP11]] |
| // IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP14]], [[EXT1]] |
| // IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP15]], [[TMP13]] |
| // IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[TMP11]] |
| // IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP17]], [[EXT]] |
| // IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP18]], [[TMP13]] |
| // IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]] |
| // IMPRVD_FAST: complex_div: |
| // IMPRVD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // IMPRVD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP20]] to half |
| // IMPRVD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP21]] to half |
| // IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[TMP22:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // IMPRVD_FAST-NEXT: ret <2 x half> [[TMP22]] |
| // |
| // PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @divf16( |
| // PRMTD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { |
| // PRMTD_FAST-NEXT: entry: |
| // PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // PRMTD_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // PRMTD_FAST-NEXT: [[EXT1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[EXT2:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_REAL]] to float |
| // PRMTD_FAST-NEXT: [[EXT3:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_IMAG]] to float |
| // PRMTD_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] |
| // PRMTD_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] |
| // PRMTD_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP0]], [[TMP1]] |
| // PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT2]], [[EXT2]] |
| // PRMTD_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT3]], [[EXT3]] |
| // PRMTD_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP3]], [[TMP4]] |
| // PRMTD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] |
| // PRMTD_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] |
| // PRMTD_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP6]], [[TMP7]] |
| // PRMTD_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP2]], [[TMP5]] |
| // PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP8]], [[TMP5]] |
| // PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP9]] to half |
| // PRMTD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP10]] to half |
| // PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // PRMTD_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[TMP11:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // PRMTD_FAST-NEXT: ret <2 x half> [[TMP11]] |
| // |
| _Complex _Float16 divf16(_Complex _Float16 a, _Complex _Float16 b) { |
| return a / b; |
| } |
| |
| // FULL-LABEL: define dso_local <2 x half> @mulf16( |
| // FULL-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // FULL-NEXT: entry: |
| // FULL-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 |
| // FULL-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // FULL-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // FULL-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // FULL-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // FULL-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // FULL-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // FULL-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // FULL-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // FULL-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // FULL-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // FULL-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] |
| // FULL-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] |
| // FULL-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] |
| // FULL-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] |
| // FULL-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] |
| // FULL-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] |
| // FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno float [[MUL_R]], [[MUL_R]] |
| // FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]] |
| // FULL: complex_mul_imag_nan: |
| // FULL-NEXT: [[ISNAN_CMP4:%.*]] = fcmp uno float [[MUL_I]], [[MUL_I]] |
| // FULL-NEXT: br i1 [[ISNAN_CMP4]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] |
| // FULL: complex_mul_libcall: |
| // FULL-NEXT: [[CALL:%.*]] = call <2 x float> @__mulsc3(float noundef [[EXT]], float noundef [[EXT1]], float noundef [[EXT2]], float noundef [[EXT3]]) #[[ATTR1]] |
| // FULL-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 |
| // FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0 |
| // FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 |
| // FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1 |
| // FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 |
| // FULL-NEXT: br label [[COMPLEX_MUL_CONT]] |
| // FULL: complex_mul_cont: |
| // FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ] |
| // FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ] |
| // FULL-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[REAL_MUL_PHI]] to half |
| // FULL-NEXT: [[UNPROMOTION5:%.*]] = fptrunc float [[IMAG_MUL_PHI]] to half |
| // FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // FULL-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // FULL-NEXT: store half [[UNPROMOTION5]], ptr [[RETVAL_IMAGP]], align 2 |
| // FULL-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // FULL-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // BASIC-LABEL: define dso_local <2 x half> @mulf16( |
| // BASIC-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // BASIC-NEXT: entry: |
| // BASIC-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // BASIC-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // BASIC-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // BASIC-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // BASIC-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // BASIC-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // BASIC-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // BASIC-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // BASIC-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // BASIC-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // BASIC-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] |
| // BASIC-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] |
| // BASIC-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] |
| // BASIC-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] |
| // BASIC-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] |
| // BASIC-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] |
| // BASIC-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half |
| // BASIC-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half |
| // BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // BASIC-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // BASIC-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // BASIC-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // BASIC-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // IMPRVD-LABEL: define dso_local <2 x half> @mulf16( |
| // IMPRVD-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // IMPRVD-NEXT: entry: |
| // IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // IMPRVD-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // IMPRVD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // IMPRVD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // IMPRVD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // IMPRVD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // IMPRVD-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] |
| // IMPRVD-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] |
| // IMPRVD-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] |
| // IMPRVD-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] |
| // IMPRVD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] |
| // IMPRVD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] |
| // IMPRVD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half |
| // IMPRVD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half |
| // IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // IMPRVD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // IMPRVD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // IMPRVD-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // PRMTD-LABEL: define dso_local <2 x half> @mulf16( |
| // PRMTD-SAME: <2 x half> noundef [[A_COERCE:%.*]], <2 x half> noundef [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // PRMTD-NEXT: entry: |
| // PRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // PRMTD-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // PRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // PRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // PRMTD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // PRMTD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // PRMTD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // PRMTD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // PRMTD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // PRMTD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // PRMTD-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] |
| // PRMTD-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] |
| // PRMTD-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] |
| // PRMTD-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] |
| // PRMTD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] |
| // PRMTD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] |
| // PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half |
| // PRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half |
| // PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // PRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // PRMTD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // PRMTD-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // PRMTD-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // X86WINPRMTD-LABEL: define dso_local i32 @mulf16( |
| // X86WINPRMTD-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // X86WINPRMTD-NEXT: entry: |
| // X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 2 |
| // X86WINPRMTD-NEXT: store i32 [[B_COERCE]], ptr [[B]], align 2 |
| // X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[EXT:%.*]] = fpext half [[A_REAL]] to float |
| // X86WINPRMTD-NEXT: [[EXT1:%.*]] = fpext half [[A_IMAG]] to float |
| // X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[EXT2:%.*]] = fpext half [[B_REAL]] to float |
| // X86WINPRMTD-NEXT: [[EXT3:%.*]] = fpext half [[B_IMAG]] to float |
| // X86WINPRMTD-NEXT: [[MUL_AC:%.*]] = fmul float [[EXT]], [[EXT2]] |
| // X86WINPRMTD-NEXT: [[MUL_BD:%.*]] = fmul float [[EXT1]], [[EXT3]] |
| // X86WINPRMTD-NEXT: [[MUL_AD:%.*]] = fmul float [[EXT]], [[EXT3]] |
| // X86WINPRMTD-NEXT: [[MUL_BC:%.*]] = fmul float [[EXT1]], [[EXT2]] |
| // X86WINPRMTD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]] |
| // X86WINPRMTD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]] |
| // X86WINPRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[MUL_R]] to half |
| // X86WINPRMTD-NEXT: [[UNPROMOTION4:%.*]] = fptrunc float [[MUL_I]] to half |
| // X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // X86WINPRMTD-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[TMP0:%.*]] = load i32, ptr [[RETVAL]], align 2 |
| // X86WINPRMTD-NEXT: ret i32 [[TMP0]] |
| // |
| // BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @mulf16( |
| // BASIC_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // BASIC_FAST-NEXT: entry: |
| // BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // BASIC_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // BASIC_FAST-NEXT: [[EXT1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[EXT2:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_REAL]] to float |
| // BASIC_FAST-NEXT: [[EXT3:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_IMAG]] to float |
| // BASIC_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] |
| // BASIC_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] |
| // BASIC_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] |
| // BASIC_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] |
| // BASIC_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] |
| // BASIC_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] |
| // BASIC_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[MUL_R]] to half |
| // BASIC_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[MUL_I]] to half |
| // BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // BASIC_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // BASIC_FAST-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @mulf16( |
| // FULL_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // FULL_FAST-NEXT: entry: |
| // FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 |
| // FULL_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // FULL_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // FULL_FAST-NEXT: [[EXT1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[EXT2:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_REAL]] to float |
| // FULL_FAST-NEXT: [[EXT3:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_IMAG]] to float |
| // FULL_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] |
| // FULL_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] |
| // FULL_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] |
| // FULL_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] |
| // FULL_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] |
| // FULL_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] |
| // FULL_FAST-NEXT: [[ISNAN_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno float [[MUL_R]], [[MUL_R]] |
| // FULL_FAST-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2:![0-9]+]] |
| // FULL_FAST: complex_mul_imag_nan: |
| // FULL_FAST-NEXT: [[ISNAN_CMP4:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno float [[MUL_I]], [[MUL_I]] |
| // FULL_FAST-NEXT: br i1 [[ISNAN_CMP4]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]] |
| // FULL_FAST: complex_mul_libcall: |
| // FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__mulsc3(float noundef nofpclass(nan inf) [[EXT]], float noundef nofpclass(nan inf) [[EXT1]], float noundef nofpclass(nan inf) [[EXT2]], float noundef nofpclass(nan inf) [[EXT3]]) #[[ATTR1]] |
| // FULL_FAST-NEXT: store <2 x float> [[CALL]], ptr [[COERCE]], align 4 |
| // FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 |
| // FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 |
| // FULL_FAST-NEXT: br label [[COMPLEX_MUL_CONT]] |
| // FULL_FAST: complex_mul_cont: |
| // FULL_FAST-NEXT: [[REAL_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_REAL]], [[COMPLEX_MUL_LIBCALL]] ] |
| // FULL_FAST-NEXT: [[IMAG_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[COERCE_IMAG]], [[COMPLEX_MUL_LIBCALL]] ] |
| // FULL_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[REAL_MUL_PHI]] to half |
| // FULL_FAST-NEXT: [[UNPROMOTION5:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[IMAG_MUL_PHI]] to half |
| // FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // FULL_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // FULL_FAST-NEXT: store half [[UNPROMOTION5]], ptr [[RETVAL_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // FULL_FAST-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @mulf16( |
| // IMPRVD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // IMPRVD_FAST-NEXT: entry: |
| // IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // IMPRVD_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // IMPRVD_FAST-NEXT: [[EXT1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[EXT2:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_REAL]] to float |
| // IMPRVD_FAST-NEXT: [[EXT3:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_IMAG]] to float |
| // IMPRVD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] |
| // IMPRVD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] |
| // IMPRVD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] |
| // IMPRVD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] |
| // IMPRVD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] |
| // IMPRVD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] |
| // IMPRVD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[MUL_R]] to half |
| // IMPRVD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[MUL_I]] to half |
| // IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // IMPRVD_FAST-NEXT: ret <2 x half> [[TMP0]] |
| // |
| // PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @mulf16( |
| // PRMTD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x half> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] { |
| // PRMTD_FAST-NEXT: entry: |
| // PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: [[B:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // PRMTD_FAST-NEXT: store <2 x half> [[B_COERCE]], ptr [[B]], align 2 |
| // PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // PRMTD_FAST-NEXT: [[EXT1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load half, ptr [[B_REALP]], align 2 |
| // PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[B]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load half, ptr [[B_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[EXT2:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_REAL]] to float |
| // PRMTD_FAST-NEXT: [[EXT3:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[B_IMAG]] to float |
| // PRMTD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT2]] |
| // PRMTD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT3]] |
| // PRMTD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT3]] |
| // PRMTD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT1]], [[EXT2]] |
| // PRMTD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[MUL_AC]], [[MUL_BD]] |
| // PRMTD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL_AD]], [[MUL_BC]] |
| // PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[MUL_R]] to half |
| // PRMTD_FAST-NEXT: [[UNPROMOTION4:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[MUL_I]] to half |
| // PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // PRMTD_FAST-NEXT: store half [[UNPROMOTION4]], ptr [[RETVAL_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // PRMTD_FAST-NEXT: ret <2 x half> [[TMP0]] |
| // |
| _Complex _Float16 mulf16(_Complex _Float16 a, _Complex _Float16 b) { |
| return a * b; |
| } |
| |
| // FULL-LABEL: define dso_local <2 x half> @f1( |
| // FULL-SAME: <2 x half> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // FULL-NEXT: entry: |
| // FULL-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 |
| // FULL-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // FULL-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 |
| // FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 |
| // FULL-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 |
| // FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 |
| // FULL-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 |
| // FULL-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // FULL-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // FULL-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // FULL-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // FULL-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 |
| // FULL-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 |
| // FULL-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]], x86_fp80 noundef [[CONV]], x86_fp80 noundef [[CONV1]]) #[[ATTR1]] |
| // FULL-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 |
| // FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 |
| // FULL-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP0]] to half |
| // FULL-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP1]] to half |
| // FULL-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float |
| // FULL-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float |
| // FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // FULL-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // FULL-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // FULL-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float |
| // FULL-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float |
| // FULL-NEXT: [[CALL7:%.*]] = call <2 x float> @__divsc3(float noundef [[EXT]], float noundef [[EXT4]], float noundef [[EXT5]], float noundef [[EXT6]]) #[[ATTR1]] |
| // FULL-NEXT: store <2 x float> [[CALL7]], ptr [[COERCE]], align 4 |
| // FULL-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0 |
| // FULL-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 |
| // FULL-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1 |
| // FULL-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 |
| // FULL-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[COERCE_REAL]] to half |
| // FULL-NEXT: [[UNPROMOTION8:%.*]] = fptrunc float [[COERCE_IMAG]] to half |
| // FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // FULL-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // FULL-NEXT: store half [[UNPROMOTION8]], ptr [[RETVAL_IMAGP]], align 2 |
| // FULL-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // FULL-NEXT: ret <2 x half> [[TMP2]] |
| // |
| // BASIC-LABEL: define dso_local <2 x half> @f1( |
| // BASIC-SAME: <2 x half> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // BASIC-NEXT: entry: |
| // BASIC-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // BASIC-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // BASIC-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 |
| // BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 |
| // BASIC-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 |
| // BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 |
| // BASIC-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 |
| // BASIC-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // BASIC-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // BASIC-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // BASIC-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // BASIC-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 |
| // BASIC-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 |
| // BASIC-NEXT: [[TMP0:%.*]] = fmul x86_fp80 [[B_REAL]], [[CONV]] |
| // BASIC-NEXT: [[TMP1:%.*]] = fmul x86_fp80 [[B_IMAG]], [[CONV1]] |
| // BASIC-NEXT: [[TMP2:%.*]] = fadd x86_fp80 [[TMP0]], [[TMP1]] |
| // BASIC-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[CONV]], [[CONV]] |
| // BASIC-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[CONV1]], [[CONV1]] |
| // BASIC-NEXT: [[TMP5:%.*]] = fadd x86_fp80 [[TMP3]], [[TMP4]] |
| // BASIC-NEXT: [[TMP6:%.*]] = fmul x86_fp80 [[B_IMAG]], [[CONV]] |
| // BASIC-NEXT: [[TMP7:%.*]] = fmul x86_fp80 [[B_REAL]], [[CONV1]] |
| // BASIC-NEXT: [[TMP8:%.*]] = fsub x86_fp80 [[TMP6]], [[TMP7]] |
| // BASIC-NEXT: [[TMP9:%.*]] = fdiv x86_fp80 [[TMP2]], [[TMP5]] |
| // BASIC-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP8]], [[TMP5]] |
| // BASIC-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP9]] to half |
| // BASIC-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP10]] to half |
| // BASIC-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float |
| // BASIC-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float |
| // BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // BASIC-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // BASIC-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // BASIC-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float |
| // BASIC-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float |
| // BASIC-NEXT: [[TMP11:%.*]] = fmul float [[EXT]], [[EXT5]] |
| // BASIC-NEXT: [[TMP12:%.*]] = fmul float [[EXT4]], [[EXT6]] |
| // BASIC-NEXT: [[TMP13:%.*]] = fadd float [[TMP11]], [[TMP12]] |
| // BASIC-NEXT: [[TMP14:%.*]] = fmul float [[EXT5]], [[EXT5]] |
| // BASIC-NEXT: [[TMP15:%.*]] = fmul float [[EXT6]], [[EXT6]] |
| // BASIC-NEXT: [[TMP16:%.*]] = fadd float [[TMP14]], [[TMP15]] |
| // BASIC-NEXT: [[TMP17:%.*]] = fmul float [[EXT4]], [[EXT5]] |
| // BASIC-NEXT: [[TMP18:%.*]] = fmul float [[EXT]], [[EXT6]] |
| // BASIC-NEXT: [[TMP19:%.*]] = fsub float [[TMP17]], [[TMP18]] |
| // BASIC-NEXT: [[TMP20:%.*]] = fdiv float [[TMP13]], [[TMP16]] |
| // BASIC-NEXT: [[TMP21:%.*]] = fdiv float [[TMP19]], [[TMP16]] |
| // BASIC-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP20]] to half |
| // BASIC-NEXT: [[UNPROMOTION7:%.*]] = fptrunc float [[TMP21]] to half |
| // BASIC-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // BASIC-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // BASIC-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // BASIC-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 |
| // BASIC-NEXT: [[TMP22:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // BASIC-NEXT: ret <2 x half> [[TMP22]] |
| // |
| // IMPRVD-LABEL: define dso_local <2 x half> @f1( |
| // IMPRVD-SAME: <2 x half> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // IMPRVD-NEXT: entry: |
| // IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // IMPRVD-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 |
| // IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 |
| // IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 |
| // IMPRVD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 |
| // IMPRVD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // IMPRVD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // IMPRVD-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 |
| // IMPRVD-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 |
| // IMPRVD-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) |
| // IMPRVD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) |
| // IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP0]], [[TMP1]] |
| // IMPRVD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] |
| // IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: |
| // IMPRVD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[CONV1]], [[CONV]] |
| // IMPRVD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[TMP2]], [[CONV1]] |
| // IMPRVD-NEXT: [[TMP4:%.*]] = fadd x86_fp80 [[CONV]], [[TMP3]] |
| // IMPRVD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP2]] |
| // IMPRVD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP5]] |
| // IMPRVD-NEXT: [[TMP7:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP4]] |
| // IMPRVD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP2]] |
| // IMPRVD-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[B_IMAG]], [[TMP8]] |
| // IMPRVD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP4]] |
| // IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]] |
| // IMPRVD: abs_rhsr_less_than_abs_rhsi: |
| // IMPRVD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[CONV]], [[CONV1]] |
| // IMPRVD-NEXT: [[TMP12:%.*]] = fmul x86_fp80 [[TMP11]], [[CONV]] |
| // IMPRVD-NEXT: [[TMP13:%.*]] = fadd x86_fp80 [[CONV1]], [[TMP12]] |
| // IMPRVD-NEXT: [[TMP14:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP11]] |
| // IMPRVD-NEXT: [[TMP15:%.*]] = fadd x86_fp80 [[TMP14]], [[B_IMAG]] |
| // IMPRVD-NEXT: [[TMP16:%.*]] = fdiv x86_fp80 [[TMP15]], [[TMP13]] |
| // IMPRVD-NEXT: [[TMP17:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP11]] |
| // IMPRVD-NEXT: [[TMP18:%.*]] = fsub x86_fp80 [[TMP17]], [[B_REAL]] |
| // IMPRVD-NEXT: [[TMP19:%.*]] = fdiv x86_fp80 [[TMP18]], [[TMP13]] |
| // IMPRVD-NEXT: br label [[COMPLEX_DIV]] |
| // IMPRVD: complex_div: |
| // IMPRVD-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // IMPRVD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // IMPRVD-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to half |
| // IMPRVD-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to half |
| // IMPRVD-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float |
| // IMPRVD-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float |
| // IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // IMPRVD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float |
| // IMPRVD-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float |
| // IMPRVD-NEXT: [[TMP22:%.*]] = call float @llvm.fabs.f32(float [[EXT5]]) |
| // IMPRVD-NEXT: [[TMP23:%.*]] = call float @llvm.fabs.f32(float [[EXT6]]) |
| // IMPRVD-NEXT: [[ABS_CMP7:%.*]] = fcmp ugt float [[TMP22]], [[TMP23]] |
| // IMPRVD-NEXT: br i1 [[ABS_CMP7]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI9:%.*]] |
| // IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi8: |
| // IMPRVD-NEXT: [[TMP24:%.*]] = fdiv float [[EXT6]], [[EXT5]] |
| // IMPRVD-NEXT: [[TMP25:%.*]] = fmul float [[TMP24]], [[EXT6]] |
| // IMPRVD-NEXT: [[TMP26:%.*]] = fadd float [[EXT5]], [[TMP25]] |
| // IMPRVD-NEXT: [[TMP27:%.*]] = fmul float [[EXT4]], [[TMP24]] |
| // IMPRVD-NEXT: [[TMP28:%.*]] = fadd float [[EXT]], [[TMP27]] |
| // IMPRVD-NEXT: [[TMP29:%.*]] = fdiv float [[TMP28]], [[TMP26]] |
| // IMPRVD-NEXT: [[TMP30:%.*]] = fmul float [[EXT]], [[TMP24]] |
| // IMPRVD-NEXT: [[TMP31:%.*]] = fsub float [[EXT4]], [[TMP30]] |
| // IMPRVD-NEXT: [[TMP32:%.*]] = fdiv float [[TMP31]], [[TMP26]] |
| // IMPRVD-NEXT: br label [[COMPLEX_DIV10:%.*]] |
| // IMPRVD: abs_rhsr_less_than_abs_rhsi9: |
| // IMPRVD-NEXT: [[TMP33:%.*]] = fdiv float [[EXT5]], [[EXT6]] |
| // IMPRVD-NEXT: [[TMP34:%.*]] = fmul float [[TMP33]], [[EXT5]] |
| // IMPRVD-NEXT: [[TMP35:%.*]] = fadd float [[EXT6]], [[TMP34]] |
| // IMPRVD-NEXT: [[TMP36:%.*]] = fmul float [[EXT]], [[TMP33]] |
| // IMPRVD-NEXT: [[TMP37:%.*]] = fadd float [[TMP36]], [[EXT4]] |
| // IMPRVD-NEXT: [[TMP38:%.*]] = fdiv float [[TMP37]], [[TMP35]] |
| // IMPRVD-NEXT: [[TMP39:%.*]] = fmul float [[EXT4]], [[TMP33]] |
| // IMPRVD-NEXT: [[TMP40:%.*]] = fsub float [[TMP39]], [[EXT]] |
| // IMPRVD-NEXT: [[TMP41:%.*]] = fdiv float [[TMP40]], [[TMP35]] |
| // IMPRVD-NEXT: br label [[COMPLEX_DIV10]] |
| // IMPRVD: complex_div10: |
| // IMPRVD-NEXT: [[TMP42:%.*]] = phi float [ [[TMP29]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8]] ], [ [[TMP38]], [[ABS_RHSR_LESS_THAN_ABS_RHSI9]] ] |
| // IMPRVD-NEXT: [[TMP43:%.*]] = phi float [ [[TMP32]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8]] ], [ [[TMP41]], [[ABS_RHSR_LESS_THAN_ABS_RHSI9]] ] |
| // IMPRVD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP42]] to half |
| // IMPRVD-NEXT: [[UNPROMOTION11:%.*]] = fptrunc float [[TMP43]] to half |
| // IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // IMPRVD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // IMPRVD-NEXT: store half [[UNPROMOTION11]], ptr [[RETVAL_IMAGP]], align 2 |
| // IMPRVD-NEXT: [[TMP44:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // IMPRVD-NEXT: ret <2 x half> [[TMP44]] |
| // |
| // PRMTD-LABEL: define dso_local <2 x half> @f1( |
| // PRMTD-SAME: <2 x half> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // PRMTD-NEXT: entry: |
| // PRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // PRMTD-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // PRMTD-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 |
| // PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 |
| // PRMTD-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 |
| // PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 |
| // PRMTD-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 |
| // PRMTD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // PRMTD-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // PRMTD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // PRMTD-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // PRMTD-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to x86_fp80 |
| // PRMTD-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to x86_fp80 |
| // PRMTD-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) |
| // PRMTD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) |
| // PRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP0]], [[TMP1]] |
| // PRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] |
| // PRMTD: abs_rhsr_greater_or_equal_abs_rhsi: |
| // PRMTD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[CONV1]], [[CONV]] |
| // PRMTD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[TMP2]], [[CONV1]] |
| // PRMTD-NEXT: [[TMP4:%.*]] = fadd x86_fp80 [[CONV]], [[TMP3]] |
| // PRMTD-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP2]] |
| // PRMTD-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP5]] |
| // PRMTD-NEXT: [[TMP7:%.*]] = fdiv x86_fp80 [[TMP6]], [[TMP4]] |
| // PRMTD-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP2]] |
| // PRMTD-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[B_IMAG]], [[TMP8]] |
| // PRMTD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP4]] |
| // PRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] |
| // PRMTD: abs_rhsr_less_than_abs_rhsi: |
| // PRMTD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[CONV]], [[CONV1]] |
| // PRMTD-NEXT: [[TMP12:%.*]] = fmul x86_fp80 [[TMP11]], [[CONV]] |
| // PRMTD-NEXT: [[TMP13:%.*]] = fadd x86_fp80 [[CONV1]], [[TMP12]] |
| // PRMTD-NEXT: [[TMP14:%.*]] = fmul x86_fp80 [[B_REAL]], [[TMP11]] |
| // PRMTD-NEXT: [[TMP15:%.*]] = fadd x86_fp80 [[TMP14]], [[B_IMAG]] |
| // PRMTD-NEXT: [[TMP16:%.*]] = fdiv x86_fp80 [[TMP15]], [[TMP13]] |
| // PRMTD-NEXT: [[TMP17:%.*]] = fmul x86_fp80 [[B_IMAG]], [[TMP11]] |
| // PRMTD-NEXT: [[TMP18:%.*]] = fsub x86_fp80 [[TMP17]], [[B_REAL]] |
| // PRMTD-NEXT: [[TMP19:%.*]] = fdiv x86_fp80 [[TMP18]], [[TMP13]] |
| // PRMTD-NEXT: br label [[COMPLEX_DIV]] |
| // PRMTD: complex_div: |
| // PRMTD-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // PRMTD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // PRMTD-NEXT: [[CONV2:%.*]] = fptrunc x86_fp80 [[TMP20]] to half |
| // PRMTD-NEXT: [[CONV3:%.*]] = fptrunc x86_fp80 [[TMP21]] to half |
| // PRMTD-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float |
| // PRMTD-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float |
| // PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // PRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // PRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // PRMTD-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float |
| // PRMTD-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float |
| // PRMTD-NEXT: [[TMP22:%.*]] = fmul float [[EXT]], [[EXT5]] |
| // PRMTD-NEXT: [[TMP23:%.*]] = fmul float [[EXT4]], [[EXT6]] |
| // PRMTD-NEXT: [[TMP24:%.*]] = fadd float [[TMP22]], [[TMP23]] |
| // PRMTD-NEXT: [[TMP25:%.*]] = fmul float [[EXT5]], [[EXT5]] |
| // PRMTD-NEXT: [[TMP26:%.*]] = fmul float [[EXT6]], [[EXT6]] |
| // PRMTD-NEXT: [[TMP27:%.*]] = fadd float [[TMP25]], [[TMP26]] |
| // PRMTD-NEXT: [[TMP28:%.*]] = fmul float [[EXT4]], [[EXT5]] |
| // PRMTD-NEXT: [[TMP29:%.*]] = fmul float [[EXT]], [[EXT6]] |
| // PRMTD-NEXT: [[TMP30:%.*]] = fsub float [[TMP28]], [[TMP29]] |
| // PRMTD-NEXT: [[TMP31:%.*]] = fdiv float [[TMP24]], [[TMP27]] |
| // PRMTD-NEXT: [[TMP32:%.*]] = fdiv float [[TMP30]], [[TMP27]] |
| // PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP31]] to half |
| // PRMTD-NEXT: [[UNPROMOTION7:%.*]] = fptrunc float [[TMP32]] to half |
| // PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // PRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // PRMTD-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 |
| // PRMTD-NEXT: [[TMP33:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // PRMTD-NEXT: ret <2 x half> [[TMP33]] |
| // |
| // X86WINPRMTD-LABEL: define dso_local i32 @f1( |
| // X86WINPRMTD-SAME: i32 noundef [[A_COERCE:%.*]], ptr noundef [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // X86WINPRMTD-NEXT: entry: |
| // X86WINPRMTD-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8 |
| // X86WINPRMTD-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 2 |
| // X86WINPRMTD-NEXT: store i32 [[C_COERCE]], ptr [[C]], align 2 |
| // X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8 |
| // X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8 |
| // X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8 |
| // X86WINPRMTD-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // X86WINPRMTD-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[CONV:%.*]] = fpext half [[C_REAL]] to double |
| // X86WINPRMTD-NEXT: [[CONV1:%.*]] = fpext half [[C_IMAG]] to double |
| // X86WINPRMTD-NEXT: [[TMP0:%.*]] = call double @llvm.fabs.f64(double [[CONV]]) |
| // X86WINPRMTD-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[CONV1]]) |
| // X86WINPRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP0]], [[TMP1]] |
| // X86WINPRMTD-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] |
| // X86WINPRMTD: abs_rhsr_greater_or_equal_abs_rhsi: |
| // X86WINPRMTD-NEXT: [[TMP2:%.*]] = fdiv double [[CONV1]], [[CONV]] |
| // X86WINPRMTD-NEXT: [[TMP3:%.*]] = fmul double [[TMP2]], [[CONV1]] |
| // X86WINPRMTD-NEXT: [[TMP4:%.*]] = fadd double [[CONV]], [[TMP3]] |
| // X86WINPRMTD-NEXT: [[TMP5:%.*]] = fmul double [[B_IMAG]], [[TMP2]] |
| // X86WINPRMTD-NEXT: [[TMP6:%.*]] = fadd double [[B_REAL]], [[TMP5]] |
| // X86WINPRMTD-NEXT: [[TMP7:%.*]] = fdiv double [[TMP6]], [[TMP4]] |
| // X86WINPRMTD-NEXT: [[TMP8:%.*]] = fmul double [[B_REAL]], [[TMP2]] |
| // X86WINPRMTD-NEXT: [[TMP9:%.*]] = fsub double [[B_IMAG]], [[TMP8]] |
| // X86WINPRMTD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP4]] |
| // X86WINPRMTD-NEXT: br label [[COMPLEX_DIV:%.*]] |
| // X86WINPRMTD: abs_rhsr_less_than_abs_rhsi: |
| // X86WINPRMTD-NEXT: [[TMP11:%.*]] = fdiv double [[CONV]], [[CONV1]] |
| // X86WINPRMTD-NEXT: [[TMP12:%.*]] = fmul double [[TMP11]], [[CONV]] |
| // X86WINPRMTD-NEXT: [[TMP13:%.*]] = fadd double [[CONV1]], [[TMP12]] |
| // X86WINPRMTD-NEXT: [[TMP14:%.*]] = fmul double [[B_REAL]], [[TMP11]] |
| // X86WINPRMTD-NEXT: [[TMP15:%.*]] = fadd double [[TMP14]], [[B_IMAG]] |
| // X86WINPRMTD-NEXT: [[TMP16:%.*]] = fdiv double [[TMP15]], [[TMP13]] |
| // X86WINPRMTD-NEXT: [[TMP17:%.*]] = fmul double [[B_IMAG]], [[TMP11]] |
| // X86WINPRMTD-NEXT: [[TMP18:%.*]] = fsub double [[TMP17]], [[B_REAL]] |
| // X86WINPRMTD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP13]] |
| // X86WINPRMTD-NEXT: br label [[COMPLEX_DIV]] |
| // X86WINPRMTD: complex_div: |
| // X86WINPRMTD-NEXT: [[TMP20:%.*]] = phi double [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // X86WINPRMTD-NEXT: [[TMP21:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // X86WINPRMTD-NEXT: [[CONV2:%.*]] = fptrunc double [[TMP20]] to half |
| // X86WINPRMTD-NEXT: [[CONV3:%.*]] = fptrunc double [[TMP21]] to half |
| // X86WINPRMTD-NEXT: [[EXT:%.*]] = fpext half [[CONV2]] to float |
| // X86WINPRMTD-NEXT: [[EXT4:%.*]] = fpext half [[CONV3]] to float |
| // X86WINPRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // X86WINPRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[EXT5:%.*]] = fpext half [[A_REAL]] to float |
| // X86WINPRMTD-NEXT: [[EXT6:%.*]] = fpext half [[A_IMAG]] to float |
| // X86WINPRMTD-NEXT: [[TMP22:%.*]] = fmul float [[EXT]], [[EXT5]] |
| // X86WINPRMTD-NEXT: [[TMP23:%.*]] = fmul float [[EXT4]], [[EXT6]] |
| // X86WINPRMTD-NEXT: [[TMP24:%.*]] = fadd float [[TMP22]], [[TMP23]] |
| // X86WINPRMTD-NEXT: [[TMP25:%.*]] = fmul float [[EXT5]], [[EXT5]] |
| // X86WINPRMTD-NEXT: [[TMP26:%.*]] = fmul float [[EXT6]], [[EXT6]] |
| // X86WINPRMTD-NEXT: [[TMP27:%.*]] = fadd float [[TMP25]], [[TMP26]] |
| // X86WINPRMTD-NEXT: [[TMP28:%.*]] = fmul float [[EXT4]], [[EXT5]] |
| // X86WINPRMTD-NEXT: [[TMP29:%.*]] = fmul float [[EXT]], [[EXT6]] |
| // X86WINPRMTD-NEXT: [[TMP30:%.*]] = fsub float [[TMP28]], [[TMP29]] |
| // X86WINPRMTD-NEXT: [[TMP31:%.*]] = fdiv float [[TMP24]], [[TMP27]] |
| // X86WINPRMTD-NEXT: [[TMP32:%.*]] = fdiv float [[TMP30]], [[TMP27]] |
| // X86WINPRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[TMP31]] to half |
| // X86WINPRMTD-NEXT: [[UNPROMOTION7:%.*]] = fptrunc float [[TMP32]] to half |
| // X86WINPRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // X86WINPRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // X86WINPRMTD-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // X86WINPRMTD-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 |
| // X86WINPRMTD-NEXT: [[TMP33:%.*]] = load i32, ptr [[RETVAL]], align 2 |
| // X86WINPRMTD-NEXT: ret i32 [[TMP33]] |
| // |
| // BASIC_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @f1( |
| // BASIC_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // BASIC_FAST-NEXT: entry: |
| // BASIC_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // BASIC_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // BASIC_FAST-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 |
| // BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 |
| // BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 |
| // BASIC_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // BASIC_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[CONV:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[C_REAL]] to x86_fp80 |
| // BASIC_FAST-NEXT: [[CONV1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[C_IMAG]] to x86_fp80 |
| // BASIC_FAST-NEXT: [[TMP0:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[CONV]] |
| // BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[CONV1]] |
| // BASIC_FAST-NEXT: [[TMP2:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP0]], [[TMP1]] |
| // BASIC_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV]] |
| // BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV1]] |
| // BASIC_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP3]], [[TMP4]] |
| // BASIC_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[CONV]] |
| // BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[CONV1]] |
| // BASIC_FAST-NEXT: [[TMP8:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP7]] |
| // BASIC_FAST-NEXT: [[TMP9:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[TMP5]] |
| // BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP8]], [[TMP5]] |
| // BASIC_FAST-NEXT: [[CONV2:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]] to half |
| // BASIC_FAST-NEXT: [[CONV3:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP10]] to half |
| // BASIC_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[CONV2]] to float |
| // BASIC_FAST-NEXT: [[EXT4:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[CONV3]] to float |
| // BASIC_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // BASIC_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[EXT5:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // BASIC_FAST-NEXT: [[EXT6:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // BASIC_FAST-NEXT: [[TMP11:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT5]] |
| // BASIC_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[EXT6]] |
| // BASIC_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP11]], [[TMP12]] |
| // BASIC_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT5]], [[EXT5]] |
| // BASIC_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT6]], [[EXT6]] |
| // BASIC_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP14]], [[TMP15]] |
| // BASIC_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[EXT5]] |
| // BASIC_FAST-NEXT: [[TMP18:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT6]] |
| // BASIC_FAST-NEXT: [[TMP19:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP17]], [[TMP18]] |
| // BASIC_FAST-NEXT: [[TMP20:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP13]], [[TMP16]] |
| // BASIC_FAST-NEXT: [[TMP21:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP19]], [[TMP16]] |
| // BASIC_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP20]] to half |
| // BASIC_FAST-NEXT: [[UNPROMOTION7:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP21]] to half |
| // BASIC_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // BASIC_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // BASIC_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // BASIC_FAST-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 |
| // BASIC_FAST-NEXT: [[TMP22:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // BASIC_FAST-NEXT: ret <2 x half> [[TMP22]] |
| // |
| // FULL_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @f1( |
| // FULL_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // FULL_FAST-NEXT: entry: |
| // FULL_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4 |
| // FULL_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // FULL_FAST-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 |
| // FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 |
| // FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 |
| // FULL_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // FULL_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[CONV:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[C_REAL]] to x86_fp80 |
| // FULL_FAST-NEXT: [[CONV1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[C_IMAG]] to x86_fp80 |
| // FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef nofpclass(nan inf) [[B_REAL]], x86_fp80 noundef nofpclass(nan inf) [[B_IMAG]], x86_fp80 noundef nofpclass(nan inf) [[CONV]], x86_fp80 noundef nofpclass(nan inf) [[CONV1]]) #[[ATTR1]] |
| // FULL_FAST-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0 |
| // FULL_FAST-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1 |
| // FULL_FAST-NEXT: [[CONV2:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP0]] to half |
| // FULL_FAST-NEXT: [[CONV3:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP1]] to half |
| // FULL_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[CONV2]] to float |
| // FULL_FAST-NEXT: [[EXT4:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[CONV3]] to float |
| // FULL_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // FULL_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[EXT5:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // FULL_FAST-NEXT: [[EXT6:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // FULL_FAST-NEXT: [[CALL7:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__divsc3(float noundef nofpclass(nan inf) [[EXT]], float noundef nofpclass(nan inf) [[EXT4]], float noundef nofpclass(nan inf) [[EXT5]], float noundef nofpclass(nan inf) [[EXT6]]) #[[ATTR1]] |
| // FULL_FAST-NEXT: store <2 x float> [[CALL7]], ptr [[COERCE]], align 4 |
| // FULL_FAST-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[COERCE_REAL:%.*]] = load float, ptr [[COERCE_REALP]], align 4 |
| // FULL_FAST-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[COERCE]], i32 0, i32 1 |
| // FULL_FAST-NEXT: [[COERCE_IMAG:%.*]] = load float, ptr [[COERCE_IMAGP]], align 4 |
| // FULL_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[COERCE_REAL]] to half |
| // FULL_FAST-NEXT: [[UNPROMOTION8:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[COERCE_IMAG]] to half |
| // FULL_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // FULL_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // FULL_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // FULL_FAST-NEXT: store half [[UNPROMOTION8]], ptr [[RETVAL_IMAGP]], align 2 |
| // FULL_FAST-NEXT: [[TMP2:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // FULL_FAST-NEXT: ret <2 x half> [[TMP2]] |
| // |
| // IMPRVD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @f1( |
| // IMPRVD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // IMPRVD_FAST-NEXT: entry: |
| // IMPRVD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // IMPRVD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // IMPRVD_FAST-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 |
| // IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 |
| // IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 |
| // IMPRVD_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[CONV:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[C_REAL]] to x86_fp80 |
| // IMPRVD_FAST-NEXT: [[CONV1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[C_IMAG]] to x86_fp80 |
| // IMPRVD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) |
| // IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) |
| // IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]] |
| // IMPRVD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] |
| // IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: |
| // IMPRVD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV]] |
| // IMPRVD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[CONV1]] |
| // IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[TMP3]] |
| // IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP2]] |
| // IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP5]] |
| // IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP4]] |
| // IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP2]] |
| // IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP8]] |
| // IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]] |
| // IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] |
| // IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi: |
| // IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV1]] |
| // IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[CONV]] |
| // IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[TMP12]] |
| // IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP11]] |
| // IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[B_IMAG]] |
| // IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[TMP13]] |
| // IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP11]] |
| // IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[B_REAL]] |
| // IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]] |
| // IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]] |
| // IMPRVD_FAST: complex_div: |
| // IMPRVD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // IMPRVD_FAST-NEXT: [[CONV2:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP20]] to half |
| // IMPRVD_FAST-NEXT: [[CONV3:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP21]] to half |
| // IMPRVD_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[CONV2]] to float |
| // IMPRVD_FAST-NEXT: [[EXT4:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[CONV3]] to float |
| // IMPRVD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[EXT5:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // IMPRVD_FAST-NEXT: [[EXT6:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // IMPRVD_FAST-NEXT: [[TMP22:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[EXT5]]) |
| // IMPRVD_FAST-NEXT: [[TMP23:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[EXT6]]) |
| // IMPRVD_FAST-NEXT: [[ABS_CMP7:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt float [[TMP22]], [[TMP23]] |
| // IMPRVD_FAST-NEXT: br i1 [[ABS_CMP7]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI9:%.*]] |
| // IMPRVD_FAST: abs_rhsr_greater_or_equal_abs_rhsi8: |
| // IMPRVD_FAST-NEXT: [[TMP24:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[EXT6]], [[EXT5]] |
| // IMPRVD_FAST-NEXT: [[TMP25:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP24]], [[EXT6]] |
| // IMPRVD_FAST-NEXT: [[TMP26:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT5]], [[TMP25]] |
| // IMPRVD_FAST-NEXT: [[TMP27:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[TMP24]] |
| // IMPRVD_FAST-NEXT: [[TMP28:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP27]] |
| // IMPRVD_FAST-NEXT: [[TMP29:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP28]], [[TMP26]] |
| // IMPRVD_FAST-NEXT: [[TMP30:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP24]] |
| // IMPRVD_FAST-NEXT: [[TMP31:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[EXT4]], [[TMP30]] |
| // IMPRVD_FAST-NEXT: [[TMP32:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP31]], [[TMP26]] |
| // IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV10:%.*]] |
| // IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi9: |
| // IMPRVD_FAST-NEXT: [[TMP33:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[EXT5]], [[EXT6]] |
| // IMPRVD_FAST-NEXT: [[TMP34:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP33]], [[EXT5]] |
| // IMPRVD_FAST-NEXT: [[TMP35:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[EXT6]], [[TMP34]] |
| // IMPRVD_FAST-NEXT: [[TMP36:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[TMP33]] |
| // IMPRVD_FAST-NEXT: [[TMP37:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP36]], [[EXT4]] |
| // IMPRVD_FAST-NEXT: [[TMP38:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP37]], [[TMP35]] |
| // IMPRVD_FAST-NEXT: [[TMP39:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[TMP33]] |
| // IMPRVD_FAST-NEXT: [[TMP40:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP39]], [[EXT]] |
| // IMPRVD_FAST-NEXT: [[TMP41:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP40]], [[TMP35]] |
| // IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV10]] |
| // IMPRVD_FAST: complex_div10: |
| // IMPRVD_FAST-NEXT: [[TMP42:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP29]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8]] ], [ [[TMP38]], [[ABS_RHSR_LESS_THAN_ABS_RHSI9]] ] |
| // IMPRVD_FAST-NEXT: [[TMP43:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP32]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI8]] ], [ [[TMP41]], [[ABS_RHSR_LESS_THAN_ABS_RHSI9]] ] |
| // IMPRVD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP42]] to half |
| // IMPRVD_FAST-NEXT: [[UNPROMOTION11:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP43]] to half |
| // IMPRVD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // IMPRVD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // IMPRVD_FAST-NEXT: store half [[UNPROMOTION11]], ptr [[RETVAL_IMAGP]], align 2 |
| // IMPRVD_FAST-NEXT: [[TMP44:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // IMPRVD_FAST-NEXT: ret <2 x half> [[TMP44]] |
| // |
| // PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) <2 x half> @f1( |
| // PRMTD_FAST-SAME: <2 x half> noundef nofpclass(nan inf) [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) #[[ATTR0]] { |
| // PRMTD_FAST-NEXT: entry: |
| // PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: [[A:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: [[C:%.*]] = alloca { half, half }, align 2 |
| // PRMTD_FAST-NEXT: store <2 x half> [[A_COERCE]], ptr [[A]], align 2 |
| // PRMTD_FAST-NEXT: store <2 x half> [[C_COERCE]], ptr [[C]], align 2 |
| // PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16 |
| // PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16 |
| // PRMTD_FAST-NEXT: [[C_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[C_REAL:%.*]] = load half, ptr [[C_REALP]], align 2 |
| // PRMTD_FAST-NEXT: [[C_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[C]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: [[C_IMAG:%.*]] = load half, ptr [[C_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[CONV:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[C_REAL]] to x86_fp80 |
| // PRMTD_FAST-NEXT: [[CONV1:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[C_IMAG]] to x86_fp80 |
| // PRMTD_FAST-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV]]) |
| // PRMTD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[CONV1]]) |
| // PRMTD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]] |
| // PRMTD_FAST-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]] |
| // PRMTD_FAST: abs_rhsr_greater_or_equal_abs_rhsi: |
| // PRMTD_FAST-NEXT: [[TMP2:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[CONV]] |
| // PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[CONV1]] |
| // PRMTD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[TMP3]] |
| // PRMTD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP2]] |
| // PRMTD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP5]] |
| // PRMTD_FAST-NEXT: [[TMP7:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP6]], [[TMP4]] |
| // PRMTD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP2]] |
| // PRMTD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP8]] |
| // PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]] |
| // PRMTD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]] |
| // PRMTD_FAST: abs_rhsr_less_than_abs_rhsi: |
| // PRMTD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV]], [[CONV1]] |
| // PRMTD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[CONV]] |
| // PRMTD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[CONV1]], [[TMP12]] |
| // PRMTD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP11]] |
| // PRMTD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[B_IMAG]] |
| // PRMTD_FAST-NEXT: [[TMP16:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[TMP13]] |
| // PRMTD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP11]] |
| // PRMTD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[B_REAL]] |
| // PRMTD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]] |
| // PRMTD_FAST-NEXT: br label [[COMPLEX_DIV]] |
| // PRMTD_FAST: complex_div: |
| // PRMTD_FAST-NEXT: [[TMP20:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // PRMTD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] |
| // PRMTD_FAST-NEXT: [[CONV2:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP20]] to half |
| // PRMTD_FAST-NEXT: [[CONV3:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP21]] to half |
| // PRMTD_FAST-NEXT: [[EXT:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[CONV2]] to float |
| // PRMTD_FAST-NEXT: [[EXT4:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[CONV3]] to float |
| // PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load half, ptr [[A_REALP]], align 2 |
| // PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[A]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load half, ptr [[A_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[EXT5:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_REAL]] to float |
| // PRMTD_FAST-NEXT: [[EXT6:%.*]] = fpext reassoc nnan ninf nsz arcp afn half [[A_IMAG]] to float |
| // PRMTD_FAST-NEXT: [[TMP22:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT5]] |
| // PRMTD_FAST-NEXT: [[TMP23:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[EXT6]] |
| // PRMTD_FAST-NEXT: [[TMP24:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP22]], [[TMP23]] |
| // PRMTD_FAST-NEXT: [[TMP25:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT5]], [[EXT5]] |
| // PRMTD_FAST-NEXT: [[TMP26:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT6]], [[EXT6]] |
| // PRMTD_FAST-NEXT: [[TMP27:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP25]], [[TMP26]] |
| // PRMTD_FAST-NEXT: [[TMP28:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT4]], [[EXT5]] |
| // PRMTD_FAST-NEXT: [[TMP29:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[EXT]], [[EXT6]] |
| // PRMTD_FAST-NEXT: [[TMP30:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP28]], [[TMP29]] |
| // PRMTD_FAST-NEXT: [[TMP31:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP24]], [[TMP27]] |
| // PRMTD_FAST-NEXT: [[TMP32:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP30]], [[TMP27]] |
| // PRMTD_FAST-NEXT: [[UNPROMOTION:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP31]] to half |
| // PRMTD_FAST-NEXT: [[UNPROMOTION7:%.*]] = fptrunc reassoc nnan ninf nsz arcp afn float [[TMP32]] to half |
| // PRMTD_FAST-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 0 |
| // PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { half, half }, ptr [[RETVAL]], i32 0, i32 1 |
| // PRMTD_FAST-NEXT: store half [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 2 |
| // PRMTD_FAST-NEXT: store half [[UNPROMOTION7]], ptr [[RETVAL_IMAGP]], align 2 |
| // PRMTD_FAST-NEXT: [[TMP33:%.*]] = load <2 x half>, ptr [[RETVAL]], align 2 |
| // PRMTD_FAST-NEXT: ret <2 x half> [[TMP33]] |
| // |
| _Complex _Float16 f1(_Complex _Float16 a, _Complex long double b, _Complex _Float16 c) { |
| return (_Complex _Float16)(b / c) / a; |
| } |
| //. |
| // FULL: [[PROF2]] = !{!"branch_weights", i32 1, i32 1048575} |
| //. |
| // FULL_FAST: [[PROF2]] = !{!"branch_weights", i32 1, i32 1048575} |
| //. |