blob: 90c37e8669b08e155f3208e7b2622ebaf6b7090f [file] [log] [blame] [edit]
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// 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=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 -triple x86_64-unknown-linux-gnu -complex-range=promoted \
// RUN: -ffp-contract=off -frounding-math -ffp-exception-behavior=strict \
// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=PRMTD_STRICT
// FULL-LABEL: define dso_local <2 x float> @mulaf(
// FULL-SAME: <2 x float> noundef [[A_COERCE:%.*]], float noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// FULL-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// FULL-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// FULL-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// FULL-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0
// FULL-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
// FULL-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// FULL-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// FULL-NEXT: [[MUL_RL:%.*]] = fmul float [[A_REAL]], [[TMP0]]
// FULL-NEXT: [[MUL_IL:%.*]] = fmul float [[A_IMAG]], [[TMP0]]
// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// FULL-NEXT: store float [[MUL_RL]], ptr [[RETVAL_REALP]], align 4
// FULL-NEXT: store float [[MUL_IL]], ptr [[RETVAL_IMAGP]], align 4
// FULL-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// FULL-NEXT: ret <2 x float> [[TMP1]]
//
// IMPRVD-LABEL: define dso_local <2 x float> @mulaf(
// IMPRVD-SAME: <2 x float> noundef [[A_COERCE:%.*]], float noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// IMPRVD-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// IMPRVD-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// IMPRVD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// IMPRVD-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0
// IMPRVD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
// IMPRVD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// IMPRVD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// IMPRVD-NEXT: [[MUL_RL:%.*]] = fmul float [[A_REAL]], [[TMP0]]
// IMPRVD-NEXT: [[MUL_IL:%.*]] = fmul float [[A_IMAG]], [[TMP0]]
// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// IMPRVD-NEXT: store float [[MUL_RL]], ptr [[RETVAL_REALP]], align 4
// IMPRVD-NEXT: store float [[MUL_IL]], ptr [[RETVAL_IMAGP]], align 4
// IMPRVD-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// IMPRVD-NEXT: ret <2 x float> [[TMP1]]
//
// PRMTD-LABEL: define dso_local <2 x float> @mulaf(
// PRMTD-SAME: <2 x float> noundef [[A_COERCE:%.*]], float noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// PRMTD-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// PRMTD-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// PRMTD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// PRMTD-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0
// PRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
// PRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// PRMTD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// PRMTD-NEXT: [[MUL_RL:%.*]] = fmul float [[A_REAL]], [[TMP0]]
// PRMTD-NEXT: [[MUL_IL:%.*]] = fmul float [[A_IMAG]], [[TMP0]]
// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD-NEXT: store float [[MUL_RL]], ptr [[RETVAL_REALP]], align 4
// PRMTD-NEXT: store float [[MUL_IL]], ptr [[RETVAL_IMAGP]], align 4
// PRMTD-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// PRMTD-NEXT: ret <2 x float> [[TMP1]]
//
// PRMTD_STRICT-LABEL: define dso_local <2 x float> @mulaf(
// PRMTD_STRICT-SAME: <2 x float> noundef [[A_COERCE:%.*]], float noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// PRMTD_STRICT-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// PRMTD_STRICT-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// PRMTD_STRICT-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// PRMTD_STRICT-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// PRMTD_STRICT-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[MUL_RL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[A_REAL]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3:[0-9]+]]
// PRMTD_STRICT-NEXT: [[MUL_IL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[A_IMAG]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store float [[MUL_RL]], ptr [[RETVAL_REALP]], align 4
// PRMTD_STRICT-NEXT: store float [[MUL_IL]], ptr [[RETVAL_IMAGP]], align 4
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// PRMTD_STRICT-NEXT: ret <2 x float> [[TMP1]]
//
_Complex float mulaf(_Complex float a, float b) {
return a * b;
}
// FULL-LABEL: define dso_local void @mulassignf(
// FULL-SAME: ptr noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR1:[0-9]+]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// FULL-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// FULL-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// FULL-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// FULL-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// FULL-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// FULL-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
// FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// FULL-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
// FULL-NEXT: [[MUL_RL:%.*]] = fmul float [[DOTREAL]], [[TMP0]]
// FULL-NEXT: [[MUL_IL:%.*]] = fmul float [[DOTIMAG]], [[TMP0]]
// FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// FULL-NEXT: store float [[MUL_RL]], ptr [[DOTREALP1]], align 4
// FULL-NEXT: store float [[MUL_IL]], ptr [[DOTIMAGP2]], align 4
// FULL-NEXT: ret void
//
// IMPRVD-LABEL: define dso_local void @mulassignf(
// IMPRVD-SAME: ptr noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR1:[0-9]+]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// IMPRVD-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// IMPRVD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// IMPRVD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// IMPRVD-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// IMPRVD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
// IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
// IMPRVD-NEXT: [[MUL_RL:%.*]] = fmul float [[DOTREAL]], [[TMP0]]
// IMPRVD-NEXT: [[MUL_IL:%.*]] = fmul float [[DOTIMAG]], [[TMP0]]
// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// IMPRVD-NEXT: store float [[MUL_RL]], ptr [[DOTREALP1]], align 4
// IMPRVD-NEXT: store float [[MUL_IL]], ptr [[DOTIMAGP2]], align 4
// IMPRVD-NEXT: ret void
//
// PRMTD-LABEL: define dso_local void @mulassignf(
// PRMTD-SAME: ptr noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR1:[0-9]+]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// PRMTD-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// PRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// PRMTD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// PRMTD-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// PRMTD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
// PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// PRMTD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
// PRMTD-NEXT: [[MUL_RL:%.*]] = fmul float [[DOTREAL]], [[TMP0]]
// PRMTD-NEXT: [[MUL_IL:%.*]] = fmul float [[DOTIMAG]], [[TMP0]]
// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// PRMTD-NEXT: store float [[MUL_RL]], ptr [[DOTREALP1]], align 4
// PRMTD-NEXT: store float [[MUL_IL]], ptr [[DOTIMAGP2]], align 4
// PRMTD-NEXT: ret void
//
// PRMTD_STRICT-LABEL: define dso_local void @mulassignf(
// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR2:[0-9]+]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// PRMTD_STRICT-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// PRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
// PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
// PRMTD_STRICT-NEXT: [[MUL_RL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[MUL_IL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store float [[MUL_RL]], ptr [[DOTREALP1]], align 4
// PRMTD_STRICT-NEXT: store float [[MUL_IL]], ptr [[DOTIMAGP2]], align 4
// PRMTD_STRICT-NEXT: ret void
//
void mulassignf(_Complex float *a, float b) {
*a *= b;
}
// FULL-LABEL: define dso_local <2 x float> @mulbf(
// FULL-SAME: float noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// FULL-NEXT: [[B:%.*]] = alloca { float, float }, align 4
// FULL-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// FULL-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
// FULL-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// FULL-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
// FULL-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
// FULL-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
// FULL-NEXT: [[MUL_RL:%.*]] = fmul float [[TMP0]], [[B_REAL]]
// FULL-NEXT: [[MUL_IR:%.*]] = fmul float [[TMP0]], [[B_IMAG]]
// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// FULL-NEXT: store float [[MUL_RL]], ptr [[RETVAL_REALP]], align 4
// FULL-NEXT: store float [[MUL_IR]], ptr [[RETVAL_IMAGP]], align 4
// FULL-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// FULL-NEXT: ret <2 x float> [[TMP1]]
//
// IMPRVD-LABEL: define dso_local <2 x float> @mulbf(
// IMPRVD-SAME: float noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// IMPRVD-NEXT: [[B:%.*]] = alloca { float, float }, align 4
// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// IMPRVD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
// IMPRVD-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// IMPRVD-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
// IMPRVD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
// IMPRVD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
// IMPRVD-NEXT: [[MUL_RL:%.*]] = fmul float [[TMP0]], [[B_REAL]]
// IMPRVD-NEXT: [[MUL_IR:%.*]] = fmul float [[TMP0]], [[B_IMAG]]
// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// IMPRVD-NEXT: store float [[MUL_RL]], ptr [[RETVAL_REALP]], align 4
// IMPRVD-NEXT: store float [[MUL_IR]], ptr [[RETVAL_IMAGP]], align 4
// IMPRVD-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// IMPRVD-NEXT: ret <2 x float> [[TMP1]]
//
// PRMTD-LABEL: define dso_local <2 x float> @mulbf(
// PRMTD-SAME: float noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// PRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4
// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// PRMTD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
// PRMTD-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// PRMTD-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
// PRMTD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
// PRMTD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
// PRMTD-NEXT: [[MUL_RL:%.*]] = fmul float [[TMP0]], [[B_REAL]]
// PRMTD-NEXT: [[MUL_IR:%.*]] = fmul float [[TMP0]], [[B_IMAG]]
// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD-NEXT: store float [[MUL_RL]], ptr [[RETVAL_REALP]], align 4
// PRMTD-NEXT: store float [[MUL_IR]], ptr [[RETVAL_IMAGP]], align 4
// PRMTD-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// PRMTD-NEXT: ret <2 x float> [[TMP1]]
//
// PRMTD_STRICT-LABEL: define dso_local <2 x float> @mulbf(
// PRMTD_STRICT-SAME: float noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// PRMTD_STRICT-NEXT: [[B:%.*]] = alloca { float, float }, align 4
// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca float, align 4
// PRMTD_STRICT-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
// PRMTD_STRICT-NEXT: store float [[A]], ptr [[A_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
// PRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
// PRMTD_STRICT-NEXT: [[MUL_RL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP0]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[MUL_IR:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP0]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store float [[MUL_RL]], ptr [[RETVAL_REALP]], align 4
// PRMTD_STRICT-NEXT: store float [[MUL_IR]], ptr [[RETVAL_IMAGP]], align 4
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// PRMTD_STRICT-NEXT: ret <2 x float> [[TMP1]]
//
_Complex float mulbf(float a, _Complex float b) {
return a * b;
}
// FULL-LABEL: define dso_local <2 x float> @divf(
// FULL-SAME: <2 x float> noundef [[A_COERCE:%.*]], float noundef [[B:%.*]]) #[[ATTR0]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// FULL-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// FULL-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// FULL-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// FULL-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0
// FULL-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
// FULL-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// FULL-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// FULL-NEXT: [[TMP1:%.*]] = fdiv float [[A_REAL]], [[TMP0]]
// FULL-NEXT: [[TMP2:%.*]] = fdiv float [[A_IMAG]], [[TMP0]]
// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// FULL-NEXT: store float [[TMP1]], ptr [[RETVAL_REALP]], align 4
// FULL-NEXT: store float [[TMP2]], ptr [[RETVAL_IMAGP]], align 4
// FULL-NEXT: [[TMP3:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// FULL-NEXT: ret <2 x float> [[TMP3]]
//
// IMPRVD-LABEL: define dso_local <2 x float> @divf(
// IMPRVD-SAME: <2 x float> noundef [[A_COERCE:%.*]], float noundef [[B:%.*]]) #[[ATTR0]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// IMPRVD-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// IMPRVD-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// IMPRVD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// IMPRVD-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0
// IMPRVD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
// IMPRVD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// IMPRVD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// IMPRVD-NEXT: [[TMP1:%.*]] = fdiv float [[A_REAL]], [[TMP0]]
// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv float [[A_IMAG]], [[TMP0]]
// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// IMPRVD-NEXT: store float [[TMP1]], ptr [[RETVAL_REALP]], align 4
// IMPRVD-NEXT: store float [[TMP2]], ptr [[RETVAL_IMAGP]], align 4
// IMPRVD-NEXT: [[TMP3:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// IMPRVD-NEXT: ret <2 x float> [[TMP3]]
//
// PRMTD-LABEL: define dso_local <2 x float> @divf(
// PRMTD-SAME: <2 x float> noundef [[A_COERCE:%.*]], float noundef [[B:%.*]]) #[[ATTR0]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// PRMTD-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// PRMTD-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// PRMTD-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// PRMTD-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0
// PRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
// PRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// PRMTD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// PRMTD-NEXT: [[TMP1:%.*]] = fdiv float [[A_REAL]], [[TMP0]]
// PRMTD-NEXT: [[TMP2:%.*]] = fdiv float [[A_IMAG]], [[TMP0]]
// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD-NEXT: store float [[TMP1]], ptr [[RETVAL_REALP]], align 4
// PRMTD-NEXT: store float [[TMP2]], ptr [[RETVAL_IMAGP]], align 4
// PRMTD-NEXT: [[TMP3:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// PRMTD-NEXT: ret <2 x float> [[TMP3]]
//
// PRMTD_STRICT-LABEL: define dso_local <2 x float> @divf(
// PRMTD_STRICT-SAME: <2 x float> noundef [[A_COERCE:%.*]], float noundef [[B:%.*]]) #[[ATTR0]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// PRMTD_STRICT-NEXT: [[A:%.*]] = alloca { float, float }, align 4
// PRMTD_STRICT-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// PRMTD_STRICT-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
// PRMTD_STRICT-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
// PRMTD_STRICT-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[A_REAL]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[A_IMAG]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store float [[TMP1]], ptr [[RETVAL_REALP]], align 4
// PRMTD_STRICT-NEXT: store float [[TMP2]], ptr [[RETVAL_IMAGP]], align 4
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// PRMTD_STRICT-NEXT: ret <2 x float> [[TMP3]]
//
_Complex float divf(_Complex float a, float b) {
return a / b;
}
// FULL-LABEL: define dso_local void @divassignf(
// FULL-SAME: ptr noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR1]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// FULL-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// FULL-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// FULL-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// FULL-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// FULL-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// FULL-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
// FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// FULL-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
// FULL-NEXT: [[TMP2:%.*]] = fdiv float [[DOTREAL]], [[TMP0]]
// FULL-NEXT: [[TMP3:%.*]] = fdiv float [[DOTIMAG]], [[TMP0]]
// FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// FULL-NEXT: store float [[TMP2]], ptr [[DOTREALP1]], align 4
// FULL-NEXT: store float [[TMP3]], ptr [[DOTIMAGP2]], align 4
// FULL-NEXT: ret void
//
// IMPRVD-LABEL: define dso_local void @divassignf(
// IMPRVD-SAME: ptr noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR1]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// IMPRVD-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// IMPRVD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// IMPRVD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// IMPRVD-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// IMPRVD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
// IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv float [[DOTREAL]], [[TMP0]]
// IMPRVD-NEXT: [[TMP3:%.*]] = fdiv float [[DOTIMAG]], [[TMP0]]
// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// IMPRVD-NEXT: store float [[TMP2]], ptr [[DOTREALP1]], align 4
// IMPRVD-NEXT: store float [[TMP3]], ptr [[DOTIMAGP2]], align 4
// IMPRVD-NEXT: ret void
//
// PRMTD-LABEL: define dso_local void @divassignf(
// PRMTD-SAME: ptr noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR1]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// PRMTD-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// PRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// PRMTD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// PRMTD-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// PRMTD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
// PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// PRMTD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
// PRMTD-NEXT: [[TMP2:%.*]] = fdiv float [[DOTREAL]], [[TMP0]]
// PRMTD-NEXT: [[TMP3:%.*]] = fdiv float [[DOTIMAG]], [[TMP0]]
// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// PRMTD-NEXT: store float [[TMP2]], ptr [[DOTREALP1]], align 4
// PRMTD-NEXT: store float [[TMP3]], ptr [[DOTIMAGP2]], align 4
// PRMTD-NEXT: ret void
//
// PRMTD_STRICT-LABEL: define dso_local void @divassignf(
// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR2]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// PRMTD_STRICT-NEXT: [[B_ADDR:%.*]] = alloca float, align 4
// PRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: store float [[B]], ptr [[B_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
// PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[DOTREAL]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[DOTIMAG]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP1]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store float [[TMP2]], ptr [[DOTREALP1]], align 4
// PRMTD_STRICT-NEXT: store float [[TMP3]], ptr [[DOTIMAGP2]], align 4
// PRMTD_STRICT-NEXT: ret void
//
void divassignf(_Complex float *a, float b) {
*a /= b;
}
// FULL-LABEL: define dso_local { double, double } @divd(
// FULL-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B:%.*]]) #[[ATTR1]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// FULL-NEXT: [[A:%.*]] = alloca { double, double }, align 8
// FULL-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// FULL-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// FULL-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8
// FULL-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// FULL-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8
// FULL-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// FULL-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// FULL-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
// FULL-NEXT: [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
// FULL-NEXT: [[TMP3:%.*]] = fdiv double [[A_REAL]], [[TMP2]]
// FULL-NEXT: [[TMP4:%.*]] = fdiv double [[A_IMAG]], [[TMP2]]
// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
// FULL-NEXT: store double [[TMP3]], ptr [[RETVAL_REALP]], align 8
// FULL-NEXT: store double [[TMP4]], ptr [[RETVAL_IMAGP]], align 8
// FULL-NEXT: [[TMP5:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
// FULL-NEXT: ret { double, double } [[TMP5]]
//
// IMPRVD-LABEL: define dso_local { double, double } @divd(
// IMPRVD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B:%.*]]) #[[ATTR1]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// IMPRVD-NEXT: [[A:%.*]] = alloca { double, double }, align 8
// IMPRVD-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// IMPRVD-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// IMPRVD-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8
// IMPRVD-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// IMPRVD-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8
// IMPRVD-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// IMPRVD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// IMPRVD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
// IMPRVD-NEXT: [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
// IMPRVD-NEXT: [[TMP3:%.*]] = fdiv double [[A_REAL]], [[TMP2]]
// IMPRVD-NEXT: [[TMP4:%.*]] = fdiv double [[A_IMAG]], [[TMP2]]
// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
// IMPRVD-NEXT: store double [[TMP3]], ptr [[RETVAL_REALP]], align 8
// IMPRVD-NEXT: store double [[TMP4]], ptr [[RETVAL_IMAGP]], align 8
// IMPRVD-NEXT: [[TMP5:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
// IMPRVD-NEXT: ret { double, double } [[TMP5]]
//
// PRMTD-LABEL: define dso_local { double, double } @divd(
// PRMTD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B:%.*]]) #[[ATTR1]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// PRMTD-NEXT: [[A:%.*]] = alloca { double, double }, align 8
// PRMTD-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// PRMTD-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// PRMTD-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8
// PRMTD-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// PRMTD-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8
// PRMTD-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// PRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// PRMTD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
// PRMTD-NEXT: [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
// PRMTD-NEXT: [[TMP3:%.*]] = fdiv double [[A_REAL]], [[TMP2]]
// PRMTD-NEXT: [[TMP4:%.*]] = fdiv double [[A_IMAG]], [[TMP2]]
// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD-NEXT: store double [[TMP3]], ptr [[RETVAL_REALP]], align 8
// PRMTD-NEXT: store double [[TMP4]], ptr [[RETVAL_IMAGP]], align 8
// PRMTD-NEXT: [[TMP5:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
// PRMTD-NEXT: ret { double, double } [[TMP5]]
//
// PRMTD_STRICT-LABEL: define dso_local { double, double } @divd(
// PRMTD_STRICT-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B:%.*]]) #[[ATTR2]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// PRMTD_STRICT-NEXT: [[A:%.*]] = alloca { double, double }, align 8
// PRMTD_STRICT-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// PRMTD_STRICT-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8
// PRMTD_STRICT-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
// PRMTD_STRICT-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A_REAL]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A_IMAG]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store double [[TMP3]], ptr [[RETVAL_REALP]], align 8
// PRMTD_STRICT-NEXT: store double [[TMP4]], ptr [[RETVAL_IMAGP]], align 8
// PRMTD_STRICT-NEXT: [[TMP5:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
// PRMTD_STRICT-NEXT: ret { double, double } [[TMP5]]
//
_Complex double divd(_Complex double a, double b) {
return a / b;
}
// FULL-LABEL: define dso_local <2 x float> @divbd(
// FULL-SAME: double noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR0]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// FULL-NEXT: [[B:%.*]] = alloca { double, double }, align 8
// FULL-NEXT: [[A_ADDR:%.*]] = alloca double, align 8
// FULL-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// FULL-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
// FULL-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// FULL-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
// FULL-NEXT: store double [[A]], ptr [[A_ADDR]], align 8
// FULL-NEXT: [[TMP2:%.*]] = load double, ptr [[A_ADDR]], align 8
// FULL-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// FULL-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
// FULL-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// FULL-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
// FULL-NEXT: [[CALL:%.*]] = call { double, double } @__divdc3(double noundef [[TMP2]], double noundef 0.000000e+00, double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2:[0-9]+]]
// FULL-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL]], 0
// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 1
// FULL-NEXT: [[CONV:%.*]] = fptrunc double [[TMP3]] to float
// FULL-NEXT: [[CONV1:%.*]] = fptrunc double [[TMP4]] to float
// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// FULL-NEXT: store float [[CONV]], ptr [[RETVAL_REALP]], align 4
// FULL-NEXT: store float [[CONV1]], ptr [[RETVAL_IMAGP]], align 4
// FULL-NEXT: [[TMP5:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// FULL-NEXT: ret <2 x float> [[TMP5]]
//
// IMPRVD-LABEL: define dso_local <2 x float> @divbd(
// IMPRVD-SAME: double noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR0]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// IMPRVD-NEXT: [[B:%.*]] = alloca { double, double }, align 8
// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca double, align 8
// IMPRVD-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// IMPRVD-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
// IMPRVD-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// IMPRVD-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
// IMPRVD-NEXT: store double [[A]], ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: [[TMP2:%.*]] = load double, ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// IMPRVD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
// IMPRVD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// IMPRVD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
// IMPRVD-NEXT: [[TMP3:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]])
// IMPRVD-NEXT: [[TMP4:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]])
// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP3]], [[TMP4]]
// 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: [[TMP5:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]]
// IMPRVD-NEXT: [[TMP6:%.*]] = fmul double [[TMP5]], [[B_IMAG]]
// IMPRVD-NEXT: [[TMP7:%.*]] = fadd double [[B_REAL]], [[TMP6]]
// IMPRVD-NEXT: [[TMP8:%.*]] = fmul double 0.000000e+00, [[TMP5]]
// IMPRVD-NEXT: [[TMP9:%.*]] = fadd double [[TMP2]], [[TMP8]]
// IMPRVD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP7]]
// IMPRVD-NEXT: [[TMP11:%.*]] = fmul double [[TMP2]], [[TMP5]]
// IMPRVD-NEXT: [[TMP12:%.*]] = fsub double 0.000000e+00, [[TMP11]]
// IMPRVD-NEXT: [[TMP13:%.*]] = fdiv double [[TMP12]], [[TMP7]]
// IMPRVD-NEXT: br label %[[COMPLEX_DIV:.*]]
// IMPRVD: [[ABS_RHSR_LESS_THAN_ABS_RHSI]]:
// IMPRVD-NEXT: [[TMP14:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]]
// IMPRVD-NEXT: [[TMP15:%.*]] = fmul double [[TMP14]], [[B_REAL]]
// IMPRVD-NEXT: [[TMP16:%.*]] = fadd double [[B_IMAG]], [[TMP15]]
// IMPRVD-NEXT: [[TMP17:%.*]] = fmul double [[TMP2]], [[TMP14]]
// IMPRVD-NEXT: [[TMP18:%.*]] = fadd double [[TMP17]], 0.000000e+00
// IMPRVD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP16]]
// IMPRVD-NEXT: [[TMP20:%.*]] = fmul double 0.000000e+00, [[TMP14]]
// IMPRVD-NEXT: [[TMP21:%.*]] = fsub double [[TMP20]], [[TMP2]]
// IMPRVD-NEXT: [[TMP22:%.*]] = fdiv double [[TMP21]], [[TMP16]]
// IMPRVD-NEXT: br label %[[COMPLEX_DIV]]
// IMPRVD: [[COMPLEX_DIV]]:
// IMPRVD-NEXT: [[TMP23:%.*]] = phi double [ [[TMP10]], %[[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], %[[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
// IMPRVD-NEXT: [[TMP24:%.*]] = phi double [ [[TMP13]], %[[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], %[[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
// IMPRVD-NEXT: [[CONV:%.*]] = fptrunc double [[TMP23]] to float
// IMPRVD-NEXT: [[CONV1:%.*]] = fptrunc double [[TMP24]] to float
// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// IMPRVD-NEXT: store float [[CONV]], ptr [[RETVAL_REALP]], align 4
// IMPRVD-NEXT: store float [[CONV1]], ptr [[RETVAL_IMAGP]], align 4
// IMPRVD-NEXT: [[TMP25:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// IMPRVD-NEXT: ret <2 x float> [[TMP25]]
//
// PRMTD-LABEL: define dso_local <2 x float> @divbd(
// PRMTD-SAME: double noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR0]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// PRMTD-NEXT: [[B:%.*]] = alloca { double, double }, align 8
// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca double, align 8
// PRMTD-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// PRMTD-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
// PRMTD-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// PRMTD-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
// PRMTD-NEXT: store double [[A]], ptr [[A_ADDR]], align 8
// PRMTD-NEXT: [[TMP2:%.*]] = load double, ptr [[A_ADDR]], align 8
// PRMTD-NEXT: [[EXT:%.*]] = fpext double [[TMP2]] to x86_fp80
// PRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// PRMTD-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
// PRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// PRMTD-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
// PRMTD-NEXT: [[EXT1:%.*]] = fpext double [[B_REAL]] to x86_fp80
// PRMTD-NEXT: [[EXT2:%.*]] = fpext double [[B_IMAG]] to x86_fp80
// PRMTD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[EXT]], [[EXT1]]
// PRMTD-NEXT: [[TMP4:%.*]] = fmul x86_fp80 0xK00000000000000000000, [[EXT2]]
// PRMTD-NEXT: [[TMP5:%.*]] = fadd x86_fp80 [[TMP3]], [[TMP4]]
// PRMTD-NEXT: [[TMP6:%.*]] = fmul x86_fp80 [[EXT1]], [[EXT1]]
// PRMTD-NEXT: [[TMP7:%.*]] = fmul x86_fp80 [[EXT2]], [[EXT2]]
// PRMTD-NEXT: [[TMP8:%.*]] = fadd x86_fp80 [[TMP6]], [[TMP7]]
// PRMTD-NEXT: [[TMP9:%.*]] = fmul x86_fp80 0xK00000000000000000000, [[EXT1]]
// PRMTD-NEXT: [[TMP10:%.*]] = fmul x86_fp80 [[EXT]], [[EXT2]]
// PRMTD-NEXT: [[TMP11:%.*]] = fsub x86_fp80 [[TMP9]], [[TMP10]]
// PRMTD-NEXT: [[TMP12:%.*]] = fdiv x86_fp80 [[TMP5]], [[TMP8]]
// PRMTD-NEXT: [[TMP13:%.*]] = fdiv x86_fp80 [[TMP11]], [[TMP8]]
// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc x86_fp80 [[TMP12]] to double
// PRMTD-NEXT: [[UNPROMOTION3:%.*]] = fptrunc x86_fp80 [[TMP13]] to double
// PRMTD-NEXT: [[CONV:%.*]] = fptrunc double [[UNPROMOTION]] to float
// PRMTD-NEXT: [[CONV4:%.*]] = fptrunc double [[UNPROMOTION3]] to float
// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD-NEXT: store float [[CONV]], ptr [[RETVAL_REALP]], align 4
// PRMTD-NEXT: store float [[CONV4]], ptr [[RETVAL_IMAGP]], align 4
// PRMTD-NEXT: [[TMP14:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// PRMTD-NEXT: ret <2 x float> [[TMP14]]
//
// PRMTD_STRICT-LABEL: define dso_local <2 x float> @divbd(
// PRMTD_STRICT-SAME: double noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR0]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
// PRMTD_STRICT-NEXT: [[B:%.*]] = alloca { double, double }, align 8
// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca double, align 8
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// PRMTD_STRICT-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
// PRMTD_STRICT-NEXT: store double [[A]], ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = load double, ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[EXT:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[TMP2]], metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
// PRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
// PRMTD_STRICT-NEXT: [[EXT1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[B_REAL]], metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[EXT2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[B_IMAG]], metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[EXT]], x86_fp80 [[EXT1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 0xK00000000000000000000, x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP5:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[TMP3]], x86_fp80 [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP6:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[EXT1]], x86_fp80 [[EXT1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP7:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[EXT2]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP8:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[TMP6]], x86_fp80 [[TMP7]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP9:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 0xK00000000000000000000, x86_fp80 [[EXT1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP10:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[EXT]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP11:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[TMP9]], x86_fp80 [[TMP10]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP12:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP5]], x86_fp80 [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP13:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP11]], x86_fp80 [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[UNPROMOTION:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[UNPROMOTION3:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[CONV:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[UNPROMOTION]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[CONV4:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[UNPROMOTION3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store float [[CONV]], ptr [[RETVAL_REALP]], align 4
// PRMTD_STRICT-NEXT: store float [[CONV4]], ptr [[RETVAL_IMAGP]], align 4
// PRMTD_STRICT-NEXT: [[TMP14:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
// PRMTD_STRICT-NEXT: ret <2 x float> [[TMP14]]
//
_Complex float divbd(double a, _Complex double b) {
return a / b;
}
// FULL-LABEL: define dso_local void @divassignd(
// FULL-SAME: ptr noundef [[A:%.*]], double noundef [[B:%.*]]) #[[ATTR1]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// FULL-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// FULL-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// FULL-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// FULL-NEXT: [[TMP0:%.*]] = load double, ptr [[B_ADDR]], align 8
// FULL-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 0
// FULL-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
// FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 1
// FULL-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
// FULL-NEXT: [[TMP2:%.*]] = fdiv double [[DOTREAL]], [[TMP0]]
// FULL-NEXT: [[TMP3:%.*]] = fdiv double [[DOTIMAG]], [[TMP0]]
// FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 0
// FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 1
// FULL-NEXT: store double [[TMP2]], ptr [[DOTREALP1]], align 8
// FULL-NEXT: store double [[TMP3]], ptr [[DOTIMAGP2]], align 8
// FULL-NEXT: ret void
//
// IMPRVD-LABEL: define dso_local void @divassignd(
// IMPRVD-SAME: ptr noundef [[A:%.*]], double noundef [[B:%.*]]) #[[ATTR1]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// IMPRVD-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// IMPRVD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// IMPRVD-NEXT: [[TMP0:%.*]] = load double, ptr [[B_ADDR]], align 8
// IMPRVD-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 0
// IMPRVD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
// IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 1
// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv double [[DOTREAL]], [[TMP0]]
// IMPRVD-NEXT: [[TMP3:%.*]] = fdiv double [[DOTIMAG]], [[TMP0]]
// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 0
// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 1
// IMPRVD-NEXT: store double [[TMP2]], ptr [[DOTREALP1]], align 8
// IMPRVD-NEXT: store double [[TMP3]], ptr [[DOTIMAGP2]], align 8
// IMPRVD-NEXT: ret void
//
// PRMTD-LABEL: define dso_local void @divassignd(
// PRMTD-SAME: ptr noundef [[A:%.*]], double noundef [[B:%.*]]) #[[ATTR1]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// PRMTD-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// PRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// PRMTD-NEXT: [[TMP0:%.*]] = load double, ptr [[B_ADDR]], align 8
// PRMTD-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 0
// PRMTD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
// PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 1
// PRMTD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
// PRMTD-NEXT: [[TMP2:%.*]] = fdiv double [[DOTREAL]], [[TMP0]]
// PRMTD-NEXT: [[TMP3:%.*]] = fdiv double [[DOTIMAG]], [[TMP0]]
// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 0
// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 1
// PRMTD-NEXT: store double [[TMP2]], ptr [[DOTREALP1]], align 8
// PRMTD-NEXT: store double [[TMP3]], ptr [[DOTIMAGP2]], align 8
// PRMTD-NEXT: ret void
//
// PRMTD_STRICT-LABEL: define dso_local void @divassignd(
// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], double noundef [[B:%.*]]) #[[ATTR2]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// PRMTD_STRICT-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
// PRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: store double [[B]], ptr [[B_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load double, ptr [[B_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
// PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[DOTREAL]], double [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[DOTIMAG]], double [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP1]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store double [[TMP2]], ptr [[DOTREALP1]], align 8
// PRMTD_STRICT-NEXT: store double [[TMP3]], ptr [[DOTIMAGP2]], align 8
// PRMTD_STRICT-NEXT: ret void
//
void divassignd(_Complex double *a, double b) {
*a /= b;
}
// FULL-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
// FULL-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], x86_fp80 noundef [[B:%.*]]) #[[ATTR1]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
// FULL-NEXT: [[B_ADDR:%.*]] = alloca x86_fp80, align 16
// FULL-NEXT: store x86_fp80 [[B]], ptr [[B_ADDR]], align 16
// FULL-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
// FULL-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16
// FULL-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1
// FULL-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16
// FULL-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[B_ADDR]], align 16
// FULL-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[A_REAL]], [[TMP0]]
// FULL-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[A_IMAG]], [[TMP0]]
// FULL-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0
// FULL-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1
// FULL-NEXT: store x86_fp80 [[TMP1]], ptr [[RETVAL_REALP]], align 16
// FULL-NEXT: store x86_fp80 [[TMP2]], ptr [[RETVAL_IMAGP]], align 16
// FULL-NEXT: [[TMP3:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
// FULL-NEXT: ret { x86_fp80, x86_fp80 } [[TMP3]]
//
// IMPRVD-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
// IMPRVD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], x86_fp80 noundef [[B:%.*]]) #[[ATTR1]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
// IMPRVD-NEXT: [[B_ADDR:%.*]] = alloca x86_fp80, align 16
// IMPRVD-NEXT: store x86_fp80 [[B]], ptr [[B_ADDR]], align 16
// IMPRVD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
// IMPRVD-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16
// IMPRVD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1
// IMPRVD-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16
// IMPRVD-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[B_ADDR]], align 16
// IMPRVD-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[A_REAL]], [[TMP0]]
// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[A_IMAG]], [[TMP0]]
// IMPRVD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0
// IMPRVD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1
// IMPRVD-NEXT: store x86_fp80 [[TMP1]], ptr [[RETVAL_REALP]], align 16
// IMPRVD-NEXT: store x86_fp80 [[TMP2]], ptr [[RETVAL_IMAGP]], align 16
// IMPRVD-NEXT: [[TMP3:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
// IMPRVD-NEXT: ret { x86_fp80, x86_fp80 } [[TMP3]]
//
// PRMTD-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
// PRMTD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], x86_fp80 noundef [[B:%.*]]) #[[ATTR1]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
// PRMTD-NEXT: [[B_ADDR:%.*]] = alloca x86_fp80, align 16
// PRMTD-NEXT: store x86_fp80 [[B]], ptr [[B_ADDR]], align 16
// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
// PRMTD-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16
// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1
// PRMTD-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16
// PRMTD-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[B_ADDR]], align 16
// PRMTD-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[A_REAL]], [[TMP0]]
// PRMTD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[A_IMAG]], [[TMP0]]
// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD-NEXT: store x86_fp80 [[TMP1]], ptr [[RETVAL_REALP]], align 16
// PRMTD-NEXT: store x86_fp80 [[TMP2]], ptr [[RETVAL_IMAGP]], align 16
// PRMTD-NEXT: [[TMP3:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
// PRMTD-NEXT: ret { x86_fp80, x86_fp80 } [[TMP3]]
//
// PRMTD_STRICT-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
// PRMTD_STRICT-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], x86_fp80 noundef [[B:%.*]]) #[[ATTR2]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
// PRMTD_STRICT-NEXT: [[B_ADDR:%.*]] = alloca x86_fp80, align 16
// PRMTD_STRICT-NEXT: store x86_fp80 [[B]], ptr [[B_ADDR]], align 16
// PRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16
// PRMTD_STRICT-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[B_ADDR]], align 16
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[A_REAL]], x86_fp80 [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[A_IMAG]], x86_fp80 [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store x86_fp80 [[TMP1]], ptr [[RETVAL_REALP]], align 16
// PRMTD_STRICT-NEXT: store x86_fp80 [[TMP2]], ptr [[RETVAL_IMAGP]], align 16
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
// PRMTD_STRICT-NEXT: ret { x86_fp80, x86_fp80 } [[TMP3]]
//
_Complex long double divld(_Complex long double a, long double b) {
return a / b;
}
// FULL-LABEL: define dso_local void @divassignld(
// FULL-SAME: ptr noundef [[A:%.*]], x86_fp80 noundef [[B:%.*]]) #[[ATTR1]] {
// FULL-NEXT: [[ENTRY:.*:]]
// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// FULL-NEXT: [[B_ADDR:%.*]] = alloca x86_fp80, align 16
// FULL-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// FULL-NEXT: store x86_fp80 [[B]], ptr [[B_ADDR]], align 16
// FULL-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[B_ADDR]], align 16
// FULL-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 0
// FULL-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
// FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 1
// FULL-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
// FULL-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[DOTREAL]], [[TMP0]]
// FULL-NEXT: [[TMP3:%.*]] = fdiv x86_fp80 [[DOTIMAG]], [[TMP0]]
// FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 0
// FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 1
// FULL-NEXT: store x86_fp80 [[TMP2]], ptr [[DOTREALP1]], align 16
// FULL-NEXT: store x86_fp80 [[TMP3]], ptr [[DOTIMAGP2]], align 16
// FULL-NEXT: ret void
//
// IMPRVD-LABEL: define dso_local void @divassignld(
// IMPRVD-SAME: ptr noundef [[A:%.*]], x86_fp80 noundef [[B:%.*]]) #[[ATTR1]] {
// IMPRVD-NEXT: [[ENTRY:.*:]]
// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// IMPRVD-NEXT: [[B_ADDR:%.*]] = alloca x86_fp80, align 16
// IMPRVD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: store x86_fp80 [[B]], ptr [[B_ADDR]], align 16
// IMPRVD-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[B_ADDR]], align 16
// IMPRVD-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 0
// IMPRVD-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
// IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 1
// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
// IMPRVD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[DOTREAL]], [[TMP0]]
// IMPRVD-NEXT: [[TMP3:%.*]] = fdiv x86_fp80 [[DOTIMAG]], [[TMP0]]
// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 0
// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 1
// IMPRVD-NEXT: store x86_fp80 [[TMP2]], ptr [[DOTREALP1]], align 16
// IMPRVD-NEXT: store x86_fp80 [[TMP3]], ptr [[DOTIMAGP2]], align 16
// IMPRVD-NEXT: ret void
//
// PRMTD-LABEL: define dso_local void @divassignld(
// PRMTD-SAME: ptr noundef [[A:%.*]], x86_fp80 noundef [[B:%.*]]) #[[ATTR1]] {
// PRMTD-NEXT: [[ENTRY:.*:]]
// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// PRMTD-NEXT: [[B_ADDR:%.*]] = alloca x86_fp80, align 16
// PRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD-NEXT: store x86_fp80 [[B]], ptr [[B_ADDR]], align 16
// PRMTD-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[B_ADDR]], align 16
// PRMTD-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 0
// PRMTD-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
// PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 1
// PRMTD-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
// PRMTD-NEXT: [[TMP2:%.*]] = fdiv x86_fp80 [[DOTREAL]], [[TMP0]]
// PRMTD-NEXT: [[TMP3:%.*]] = fdiv x86_fp80 [[DOTIMAG]], [[TMP0]]
// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 0
// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 1
// PRMTD-NEXT: store x86_fp80 [[TMP2]], ptr [[DOTREALP1]], align 16
// PRMTD-NEXT: store x86_fp80 [[TMP3]], ptr [[DOTIMAGP2]], align 16
// PRMTD-NEXT: ret void
//
// PRMTD_STRICT-LABEL: define dso_local void @divassignld(
// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], x86_fp80 noundef [[B:%.*]]) #[[ATTR2]] {
// PRMTD_STRICT-NEXT: [[ENTRY:.*:]]
// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// PRMTD_STRICT-NEXT: [[B_ADDR:%.*]] = alloca x86_fp80, align 16
// PRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: store x86_fp80 [[B]], ptr [[B_ADDR]], align 16
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load x86_fp80, ptr [[B_ADDR]], align 16
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
// PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[DOTREAL]], x86_fp80 [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[DOTIMAG]], x86_fp80 [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP1]], i32 0, i32 1
// PRMTD_STRICT-NEXT: store x86_fp80 [[TMP2]], ptr [[DOTREALP1]], align 16
// PRMTD_STRICT-NEXT: store x86_fp80 [[TMP3]], ptr [[DOTIMAGP2]], align 16
// PRMTD_STRICT-NEXT: ret void
//
void divassignld(_Complex long double *a, long double b) {
*a /= b;
}