[clang] 7b00b0b - [Clang][NFC] Extend cmplx range tests for #131129 (#131447)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 18 22:24:07 PDT 2025
Author: Mészáros Gergely
Date: 2025-03-19T06:24:02+01:00
New Revision: 7b00b0b7587120abbab0217c25f23f4e2ba8ae4e
URL: https://github.com/llvm/llvm-project/commit/7b00b0b7587120abbab0217c25f23f4e2ba8ae4e
DIFF: https://github.com/llvm/llvm-project/commit/7b00b0b7587120abbab0217c25f23f4e2ba8ae4e.diff
LOG: [Clang][NFC] Extend cmplx range tests for #131129 (#131447)
- Add tests for complex divdent and real divisor
- Add tests for complex * real multiplication
- Add tests for multiply/divide and assign (`/=`,`*=`) operators
Added:
clang/test/CodeGen/cx-complex-range-real.c
Modified:
clang/test/CodeGen/cx-complex-range.c
Removed:
################################################################################
diff --git a/clang/test/CodeGen/cx-complex-range-real.c b/clang/test/CodeGen/cx-complex-range-real.c
new file mode 100644
index 0000000000000..62dbfcdc6fa53
--- /dev/null
+++ b/clang/test/CodeGen/cx-complex-range-real.c
@@ -0,0 +1,1017 @@
+// 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: [[EXT:%.*]] = fpext float [[A_REAL]] to double
+// PRMTD-NEXT: [[EXT1:%.*]] = fpext float [[A_IMAG]] to double
+// PRMTD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
+// PRMTD-NEXT: [[EXT2:%.*]] = fpext float [[TMP0]] to double
+// PRMTD-NEXT: [[TMP1:%.*]] = fdiv double [[EXT]], [[EXT2]]
+// PRMTD-NEXT: [[TMP2:%.*]] = fdiv double [[EXT1]], [[EXT2]]
+// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP1]] to float
+// PRMTD-NEXT: [[UNPROMOTION3:%.*]] = fptrunc double [[TMP2]] 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 [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4
+// PRMTD-NEXT: store float [[UNPROMOTION3]], 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: [[EXT:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[A_REAL]], metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[EXT1:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[A_IMAG]], metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
+// PRMTD_STRICT-NEXT: [[EXT2:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP0]], metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[EXT]], double [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[EXT1]], double [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[UNPROMOTION:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[TMP1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[UNPROMOTION3:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[TMP2]], 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 [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4
+// PRMTD_STRICT-NEXT: store float [[UNPROMOTION3]], 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: [[EXT:%.*]] = fpext double [[A_REAL]] to x86_fp80
+// PRMTD-NEXT: [[EXT1:%.*]] = fpext double [[A_IMAG]] to x86_fp80
+// PRMTD-NEXT: [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
+// PRMTD-NEXT: [[EXT2:%.*]] = fpext double [[TMP2]] to x86_fp80
+// PRMTD-NEXT: [[TMP3:%.*]] = fdiv x86_fp80 [[EXT]], [[EXT2]]
+// PRMTD-NEXT: [[TMP4:%.*]] = fdiv x86_fp80 [[EXT1]], [[EXT2]]
+// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc x86_fp80 [[TMP3]] to double
+// PRMTD-NEXT: [[UNPROMOTION3:%.*]] = fptrunc x86_fp80 [[TMP4]] to double
+// 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 [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 8
+// PRMTD-NEXT: store double [[UNPROMOTION3]], 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: [[EXT:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[A_REAL]], metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[EXT1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[A_IMAG]], metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
+// PRMTD_STRICT-NEXT: [[EXT2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[TMP2]], metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[EXT]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[EXT1]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[UNPROMOTION:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT: [[UNPROMOTION3:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP4]], 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 [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 8
+// PRMTD_STRICT-NEXT: store double [[UNPROMOTION3]], 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;
+}
diff --git a/clang/test/CodeGen/cx-complex-range.c b/clang/test/CodeGen/cx-complex-range.c
index 88300041061aa..06a349fbc2a47 100644
--- a/clang/test/CodeGen/cx-complex-range.c
+++ b/clang/test/CodeGen/cx-complex-range.c
@@ -597,6 +597,599 @@ _Complex float divf(_Complex float a, _Complex float b) {
return a / b;
}
+// FULL-LABEL: define dso_local void @divassignf(
+// FULL-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// FULL-NEXT: entry:
+// FULL-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
+// FULL-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// FULL-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// FULL-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// FULL-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// FULL-NEXT: [[CALL:%.*]] = call <2 x float> @__divsc3(float noundef [[DOTREAL]], float noundef [[DOTIMAG]], float noundef [[B_REAL]], float noundef [[B_IMAG]]) #[[ATTR2]]
+// 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: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// FULL-NEXT: store float [[COERCE_REAL]], ptr [[DOTREALP1]], align 4
+// FULL-NEXT: store float [[COERCE_IMAG]], ptr [[DOTIMAGP2]], align 4
+// FULL-NEXT: ret void
+//
+// BASIC-LABEL: define dso_local void @divassignf(
+// BASIC-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// BASIC-NEXT: entry:
+// BASIC-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// BASIC-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// BASIC-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// BASIC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// BASIC-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// BASIC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// BASIC-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// BASIC-NEXT: [[TMP1:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP2:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP3:%.*]] = fadd float [[TMP1]], [[TMP2]]
+// BASIC-NEXT: [[TMP4:%.*]] = fmul float [[B_REAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP5:%.*]] = fmul float [[B_IMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP6:%.*]] = fadd float [[TMP4]], [[TMP5]]
+// BASIC-NEXT: [[TMP7:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// BASIC-NEXT: [[TMP8:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP9:%.*]] = fsub float [[TMP7]], [[TMP8]]
+// BASIC-NEXT: [[TMP10:%.*]] = fdiv float [[TMP3]], [[TMP6]]
+// BASIC-NEXT: [[TMP11:%.*]] = fdiv float [[TMP9]], [[TMP6]]
+// BASIC-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// BASIC-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// BASIC-NEXT: store float [[TMP10]], ptr [[DOTREALP1]], align 4
+// BASIC-NEXT: store float [[TMP11]], ptr [[DOTIMAGP2]], align 4
+// BASIC-NEXT: ret void
+//
+// IMPRVD-LABEL: define dso_local void @divassignf(
+// IMPRVD-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// IMPRVD-NEXT: entry:
+// IMPRVD-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// IMPRVD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// IMPRVD-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]])
+// IMPRVD-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]])
+// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]]
+// IMPRVD-NEXT: [[TMP4:%.*]] = fmul float [[TMP3]], [[B_IMAG]]
+// IMPRVD-NEXT: [[TMP5:%.*]] = fadd float [[B_REAL]], [[TMP4]]
+// IMPRVD-NEXT: [[TMP6:%.*]] = fmul float [[DOTIMAG]], [[TMP3]]
+// IMPRVD-NEXT: [[TMP7:%.*]] = fadd float [[DOTREAL]], [[TMP6]]
+// IMPRVD-NEXT: [[TMP8:%.*]] = fdiv float [[TMP7]], [[TMP5]]
+// IMPRVD-NEXT: [[TMP9:%.*]] = fmul float [[DOTREAL]], [[TMP3]]
+// IMPRVD-NEXT: [[TMP10:%.*]] = fsub float [[DOTIMAG]], [[TMP9]]
+// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv float [[TMP10]], [[TMP5]]
+// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]]
+// IMPRVD: abs_rhsr_less_than_abs_rhsi:
+// IMPRVD-NEXT: [[TMP12:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]]
+// IMPRVD-NEXT: [[TMP13:%.*]] = fmul float [[TMP12]], [[B_REAL]]
+// IMPRVD-NEXT: [[TMP14:%.*]] = fadd float [[B_IMAG]], [[TMP13]]
+// IMPRVD-NEXT: [[TMP15:%.*]] = fmul float [[DOTREAL]], [[TMP12]]
+// IMPRVD-NEXT: [[TMP16:%.*]] = fadd float [[TMP15]], [[DOTIMAG]]
+// IMPRVD-NEXT: [[TMP17:%.*]] = fdiv float [[TMP16]], [[TMP14]]
+// IMPRVD-NEXT: [[TMP18:%.*]] = fmul float [[DOTIMAG]], [[TMP12]]
+// IMPRVD-NEXT: [[TMP19:%.*]] = fsub float [[TMP18]], [[DOTREAL]]
+// IMPRVD-NEXT: [[TMP20:%.*]] = fdiv float [[TMP19]], [[TMP14]]
+// IMPRVD-NEXT: br label [[COMPLEX_DIV]]
+// IMPRVD: complex_div:
+// IMPRVD-NEXT: [[TMP21:%.*]] = phi float [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD-NEXT: [[TMP22:%.*]] = phi float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD-NEXT: store float [[TMP21]], ptr [[DOTREALP1]], align 4
+// IMPRVD-NEXT: store float [[TMP22]], ptr [[DOTIMAGP2]], align 4
+// IMPRVD-NEXT: ret void
+//
+// PRMTD-LABEL: define dso_local void @divassignf(
+// PRMTD-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// PRMTD-NEXT: entry:
+// PRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// PRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// PRMTD-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]])
+// PRMTD-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]])
+// PRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]]
+// PRMTD-NEXT: [[TMP4:%.*]] = fmul float [[TMP3]], [[B_IMAG]]
+// PRMTD-NEXT: [[TMP5:%.*]] = fadd float [[B_REAL]], [[TMP4]]
+// PRMTD-NEXT: [[TMP6:%.*]] = fmul float [[DOTIMAG]], [[TMP3]]
+// PRMTD-NEXT: [[TMP7:%.*]] = fadd float [[DOTREAL]], [[TMP6]]
+// PRMTD-NEXT: [[TMP8:%.*]] = fdiv float [[TMP7]], [[TMP5]]
+// PRMTD-NEXT: [[TMP9:%.*]] = fmul float [[DOTREAL]], [[TMP3]]
+// PRMTD-NEXT: [[TMP10:%.*]] = fsub float [[DOTIMAG]], [[TMP9]]
+// PRMTD-NEXT: [[TMP11:%.*]] = fdiv float [[TMP10]], [[TMP5]]
+// PRMTD-NEXT: br label [[COMPLEX_DIV:%.*]]
+// PRMTD: abs_rhsr_less_than_abs_rhsi:
+// PRMTD-NEXT: [[TMP12:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]]
+// PRMTD-NEXT: [[TMP13:%.*]] = fmul float [[TMP12]], [[B_REAL]]
+// PRMTD-NEXT: [[TMP14:%.*]] = fadd float [[B_IMAG]], [[TMP13]]
+// PRMTD-NEXT: [[TMP15:%.*]] = fmul float [[DOTREAL]], [[TMP12]]
+// PRMTD-NEXT: [[TMP16:%.*]] = fadd float [[TMP15]], [[DOTIMAG]]
+// PRMTD-NEXT: [[TMP17:%.*]] = fdiv float [[TMP16]], [[TMP14]]
+// PRMTD-NEXT: [[TMP18:%.*]] = fmul float [[DOTIMAG]], [[TMP12]]
+// PRMTD-NEXT: [[TMP19:%.*]] = fsub float [[TMP18]], [[DOTREAL]]
+// PRMTD-NEXT: [[TMP20:%.*]] = fdiv float [[TMP19]], [[TMP14]]
+// PRMTD-NEXT: br label [[COMPLEX_DIV]]
+// PRMTD: complex_div:
+// PRMTD-NEXT: [[TMP21:%.*]] = phi float [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD-NEXT: [[TMP22:%.*]] = phi float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD-NEXT: store float [[TMP21]], ptr [[DOTREALP1]], align 4
+// PRMTD-NEXT: store float [[TMP22]], ptr [[DOTIMAGP2]], align 4
+// PRMTD-NEXT: ret void
+//
+// X86WINPRMTD-LABEL: define dso_local void @divassignf(
+// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], i64 noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD-NEXT: entry:
+// X86WINPRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// X86WINPRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: store i64 [[B_COERCE]], ptr [[B]], align 4
+// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// X86WINPRMTD-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// X86WINPRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// X86WINPRMTD-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]])
+// X86WINPRMTD-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]])
+// X86WINPRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fmul float [[TMP3]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fadd float [[B_REAL]], [[TMP4]]
+// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fmul float [[DOTIMAG]], [[TMP3]]
+// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fadd float [[DOTREAL]], [[TMP6]]
+// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fdiv float [[TMP7]], [[TMP5]]
+// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fmul float [[DOTREAL]], [[TMP3]]
+// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fsub float [[DOTIMAG]], [[TMP9]]
+// X86WINPRMTD-NEXT: [[TMP11:%.*]] = fdiv float [[TMP10]], [[TMP5]]
+// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV:%.*]]
+// X86WINPRMTD: abs_rhsr_less_than_abs_rhsi:
+// X86WINPRMTD-NEXT: [[TMP12:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[TMP13:%.*]] = fmul float [[TMP12]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[TMP14:%.*]] = fadd float [[B_IMAG]], [[TMP13]]
+// X86WINPRMTD-NEXT: [[TMP15:%.*]] = fmul float [[DOTREAL]], [[TMP12]]
+// X86WINPRMTD-NEXT: [[TMP16:%.*]] = fadd float [[TMP15]], [[DOTIMAG]]
+// X86WINPRMTD-NEXT: [[TMP17:%.*]] = fdiv float [[TMP16]], [[TMP14]]
+// X86WINPRMTD-NEXT: [[TMP18:%.*]] = fmul float [[DOTIMAG]], [[TMP12]]
+// X86WINPRMTD-NEXT: [[TMP19:%.*]] = fsub float [[TMP18]], [[DOTREAL]]
+// X86WINPRMTD-NEXT: [[TMP20:%.*]] = fdiv float [[TMP19]], [[TMP14]]
+// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV]]
+// X86WINPRMTD: complex_div:
+// X86WINPRMTD-NEXT: [[TMP21:%.*]] = phi float [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD-NEXT: [[TMP22:%.*]] = phi float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: store float [[TMP21]], ptr [[DOTREALP1]], align 4
+// X86WINPRMTD-NEXT: store float [[TMP22]], ptr [[DOTIMAGP2]], align 4
+// X86WINPRMTD-NEXT: ret void
+//
+// AVRFP32-LABEL: define dso_local void @divassignf(
+// AVRFP32-SAME: ptr noundef [[A:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP32-NEXT: entry:
+// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1
+// AVRFP32-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP32-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1
+// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1
+// AVRFP32-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 1
+// AVRFP32-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 1
+// AVRFP32-NEXT: [[TMP3:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_REAL]])
+// AVRFP32-NEXT: [[TMP4:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_IMAG]])
+// AVRFP32-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP3]], [[TMP4]]
+// AVRFP32-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// AVRFP32: abs_rhsr_greater_or_equal_abs_rhsi:
+// AVRFP32-NEXT: [[TMP5:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]]
+// AVRFP32-NEXT: [[TMP6:%.*]] = fmul float [[TMP5]], [[B_IMAG]]
+// AVRFP32-NEXT: [[TMP7:%.*]] = fadd float [[B_REAL]], [[TMP6]]
+// AVRFP32-NEXT: [[TMP8:%.*]] = fmul float [[DOTIMAG]], [[TMP5]]
+// AVRFP32-NEXT: [[TMP9:%.*]] = fadd float [[DOTREAL]], [[TMP8]]
+// AVRFP32-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP7]]
+// AVRFP32-NEXT: [[TMP11:%.*]] = fmul float [[DOTREAL]], [[TMP5]]
+// AVRFP32-NEXT: [[TMP12:%.*]] = fsub float [[DOTIMAG]], [[TMP11]]
+// AVRFP32-NEXT: [[TMP13:%.*]] = fdiv float [[TMP12]], [[TMP7]]
+// AVRFP32-NEXT: br label [[COMPLEX_DIV:%.*]]
+// AVRFP32: abs_rhsr_less_than_abs_rhsi:
+// AVRFP32-NEXT: [[TMP14:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]]
+// AVRFP32-NEXT: [[TMP15:%.*]] = fmul float [[TMP14]], [[B_REAL]]
+// AVRFP32-NEXT: [[TMP16:%.*]] = fadd float [[B_IMAG]], [[TMP15]]
+// AVRFP32-NEXT: [[TMP17:%.*]] = fmul float [[DOTREAL]], [[TMP14]]
+// AVRFP32-NEXT: [[TMP18:%.*]] = fadd float [[TMP17]], [[DOTIMAG]]
+// AVRFP32-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP16]]
+// AVRFP32-NEXT: [[TMP20:%.*]] = fmul float [[DOTIMAG]], [[TMP14]]
+// AVRFP32-NEXT: [[TMP21:%.*]] = fsub float [[TMP20]], [[DOTREAL]]
+// AVRFP32-NEXT: [[TMP22:%.*]] = fdiv float [[TMP21]], [[TMP16]]
+// AVRFP32-NEXT: br label [[COMPLEX_DIV]]
+// AVRFP32: complex_div:
+// AVRFP32-NEXT: [[TMP23:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP32-NEXT: [[TMP24:%.*]] = phi float [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP32-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[TMP23]], ptr [[DOTREALP1]], align 1
+// AVRFP32-NEXT: store float [[TMP24]], ptr [[DOTIMAGP2]], align 1
+// AVRFP32-NEXT: ret void
+//
+// AVRFP64-LABEL: define dso_local void @divassignf(
+// AVRFP64-SAME: ptr noundef [[A:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP64-NEXT: entry:
+// AVRFP64-NEXT: [[B:%.*]] = alloca { float, float }, align 1
+// AVRFP64-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: store float [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: store float [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP64-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1
+// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1
+// AVRFP64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 1
+// AVRFP64-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 1
+// AVRFP64-NEXT: [[TMP3:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_REAL]])
+// AVRFP64-NEXT: [[TMP4:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_IMAG]])
+// AVRFP64-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP3]], [[TMP4]]
+// AVRFP64-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// AVRFP64: abs_rhsr_greater_or_equal_abs_rhsi:
+// AVRFP64-NEXT: [[TMP5:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]]
+// AVRFP64-NEXT: [[TMP6:%.*]] = fmul float [[TMP5]], [[B_IMAG]]
+// AVRFP64-NEXT: [[TMP7:%.*]] = fadd float [[B_REAL]], [[TMP6]]
+// AVRFP64-NEXT: [[TMP8:%.*]] = fmul float [[DOTIMAG]], [[TMP5]]
+// AVRFP64-NEXT: [[TMP9:%.*]] = fadd float [[DOTREAL]], [[TMP8]]
+// AVRFP64-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP7]]
+// AVRFP64-NEXT: [[TMP11:%.*]] = fmul float [[DOTREAL]], [[TMP5]]
+// AVRFP64-NEXT: [[TMP12:%.*]] = fsub float [[DOTIMAG]], [[TMP11]]
+// AVRFP64-NEXT: [[TMP13:%.*]] = fdiv float [[TMP12]], [[TMP7]]
+// AVRFP64-NEXT: br label [[COMPLEX_DIV:%.*]]
+// AVRFP64: abs_rhsr_less_than_abs_rhsi:
+// AVRFP64-NEXT: [[TMP14:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]]
+// AVRFP64-NEXT: [[TMP15:%.*]] = fmul float [[TMP14]], [[B_REAL]]
+// AVRFP64-NEXT: [[TMP16:%.*]] = fadd float [[B_IMAG]], [[TMP15]]
+// AVRFP64-NEXT: [[TMP17:%.*]] = fmul float [[DOTREAL]], [[TMP14]]
+// AVRFP64-NEXT: [[TMP18:%.*]] = fadd float [[TMP17]], [[DOTIMAG]]
+// AVRFP64-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP16]]
+// AVRFP64-NEXT: [[TMP20:%.*]] = fmul float [[DOTIMAG]], [[TMP14]]
+// AVRFP64-NEXT: [[TMP21:%.*]] = fsub float [[TMP20]], [[DOTREAL]]
+// AVRFP64-NEXT: [[TMP22:%.*]] = fdiv float [[TMP21]], [[TMP16]]
+// AVRFP64-NEXT: br label [[COMPLEX_DIV]]
+// AVRFP64: complex_div:
+// AVRFP64-NEXT: [[TMP23:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP64-NEXT: [[TMP24:%.*]] = phi float [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP64-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: store float [[TMP23]], ptr [[DOTREALP1]], align 1
+// AVRFP64-NEXT: store float [[TMP24]], ptr [[DOTIMAGP2]], align 1
+// AVRFP64-NEXT: ret void
+//
+// BASIC_FAST-LABEL: define dso_local void @divassignf(
+// BASIC_FAST-SAME: ptr noundef [[A:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] {
+// BASIC_FAST-NEXT: entry:
+// BASIC_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// BASIC_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// BASIC_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// BASIC_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// BASIC_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP2:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP3:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP1]], [[TMP2]]
+// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[B_REAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[B_IMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP4]], [[TMP5]]
+// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP7]], [[TMP8]]
+// BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP3]], [[TMP6]]
+// BASIC_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP9]], [[TMP6]]
+// BASIC_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// BASIC_FAST-NEXT: store float [[TMP10]], ptr [[DOTREALP1]], align 4
+// BASIC_FAST-NEXT: store float [[TMP11]], ptr [[DOTIMAGP2]], align 4
+// BASIC_FAST-NEXT: ret void
+//
+// FULL_FAST-LABEL: define dso_local void @divassignf(
+// FULL_FAST-SAME: ptr noundef [[A:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] {
+// FULL_FAST-NEXT: entry:
+// FULL_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// FULL_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
+// FULL_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// FULL_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// FULL_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// FULL_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// FULL_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// FULL_FAST-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) <2 x float> @__divsc3(float noundef nofpclass(nan inf) [[DOTREAL]], float noundef nofpclass(nan inf) [[DOTIMAG]], float noundef nofpclass(nan inf) [[B_REAL]], float noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]]
+// 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: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// FULL_FAST-NEXT: store float [[COERCE_REAL]], ptr [[DOTREALP1]], align 4
+// FULL_FAST-NEXT: store float [[COERCE_IMAG]], ptr [[DOTIMAGP2]], align 4
+// FULL_FAST-NEXT: ret void
+//
+// IMPRVD_FAST-LABEL: define dso_local void @divassignf(
+// IMPRVD_FAST-SAME: ptr noundef [[A:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] {
+// IMPRVD_FAST-NEXT: entry:
+// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// IMPRVD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// IMPRVD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// IMPRVD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[B_REAL]])
+// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[B_IMAG]])
+// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt float [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[B_IMAG]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP3]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[B_REAL]], [[TMP4]]
+// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[TMP3]]
+// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[TMP6]]
+// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP7]], [[TMP5]]
+// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[TMP3]]
+// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[TMP9]]
+// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP10]], [[TMP5]]
+// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]]
+// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi:
+// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[B_REAL]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP12]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[B_IMAG]], [[TMP13]]
+// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[TMP12]]
+// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP15]], [[DOTIMAG]]
+// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP16]], [[TMP14]]
+// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[TMP12]]
+// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP18]], [[DOTREAL]]
+// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP19]], [[TMP14]]
+// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]]
+// IMPRVD_FAST: complex_div:
+// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store float [[TMP21]], ptr [[DOTREALP1]], align 4
+// IMPRVD_FAST-NEXT: store float [[TMP22]], ptr [[DOTIMAGP2]], align 4
+// IMPRVD_FAST-NEXT: ret void
+//
+// PRMTD_FAST-LABEL: define dso_local void @divassignf(
+// PRMTD_FAST-SAME: ptr noundef [[A:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] {
+// PRMTD_FAST-NEXT: entry:
+// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// PRMTD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// PRMTD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// PRMTD_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// PRMTD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// PRMTD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[B_REAL]])
+// PRMTD_FAST-NEXT: [[TMP2:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fabs.f32(float [[B_IMAG]])
+// PRMTD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt float [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[B_IMAG]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP3]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[B_REAL]], [[TMP4]]
+// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[TMP3]]
+// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[TMP6]]
+// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP7]], [[TMP5]]
+// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[TMP3]]
+// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[TMP9]]
+// PRMTD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP10]], [[TMP5]]
+// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]]
+// PRMTD_FAST: abs_rhsr_less_than_abs_rhsi:
+// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[B_REAL]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP12]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[B_IMAG]], [[TMP13]]
+// PRMTD_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[TMP12]]
+// PRMTD_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[TMP15]], [[DOTIMAG]]
+// PRMTD_FAST-NEXT: [[TMP17:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP16]], [[TMP14]]
+// PRMTD_FAST-NEXT: [[TMP18:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[TMP12]]
+// PRMTD_FAST-NEXT: [[TMP19:%.*]] = fsub reassoc nnan ninf nsz arcp afn float [[TMP18]], [[DOTREAL]]
+// PRMTD_FAST-NEXT: [[TMP20:%.*]] = fdiv reassoc nnan ninf nsz arcp afn float [[TMP19]], [[TMP14]]
+// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV]]
+// PRMTD_FAST: complex_div:
+// PRMTD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_FAST-NEXT: [[TMP22:%.*]] = phi reassoc nnan ninf nsz arcp afn float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store float [[TMP21]], ptr [[DOTREALP1]], align 4
+// PRMTD_FAST-NEXT: store float [[TMP22]], ptr [[DOTIMAGP2]], align 4
+// PRMTD_FAST-NEXT: ret void
+//
+// X86WINPRMTD_STRICT-LABEL: define dso_local void @divassignf(
+// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], i64 noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD_STRICT-NEXT: entry:
+// X86WINPRMTD_STRICT-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// X86WINPRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: store i64 [[B_COERCE]], ptr [[B]], align 4
+// X86WINPRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// X86WINPRMTD_STRICT-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]]) #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]]) #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP1]], float [[TMP2]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// X86WINPRMTD_STRICT: abs_rhsr_greater_or_equal_abs_rhsi:
+// X86WINPRMTD_STRICT-NEXT: [[TMP3:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[B_IMAG]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP4:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP3]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP5:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[B_REAL]], float [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP6:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP7:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[DOTREAL]], float [[TMP6]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP8:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[TMP7]], float [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP9:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP10:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[DOTIMAG]], float [[TMP9]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP11:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[TMP10]], float [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br label [[COMPLEX_DIV:%.*]]
+// X86WINPRMTD_STRICT: abs_rhsr_less_than_abs_rhsi:
+// X86WINPRMTD_STRICT-NEXT: [[TMP12:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[B_REAL]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP13:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP12]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP14:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[B_IMAG]], float [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP15:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP16:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[TMP15]], float [[DOTIMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP17:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[TMP16]], float [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP18:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP19:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[TMP18]], float [[DOTREAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP20:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[TMP19]], float [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br label [[COMPLEX_DIV]]
+// X86WINPRMTD_STRICT: complex_div:
+// X86WINPRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi float [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD_STRICT-NEXT: [[TMP22:%.*]] = phi float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: store float [[TMP21]], ptr [[DOTREALP1]], align 4
+// X86WINPRMTD_STRICT-NEXT: store float [[TMP22]], ptr [[DOTIMAGP2]], align 4
+// X86WINPRMTD_STRICT-NEXT: ret void
+//
+// PRMTD_STRICT-LABEL: define dso_local void @divassignf(
+// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// PRMTD_STRICT-NEXT: entry:
+// PRMTD_STRICT-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_STRICT-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// PRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]]) #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]]) #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f32(float [[TMP1]], float [[TMP2]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// PRMTD_STRICT: abs_rhsr_greater_or_equal_abs_rhsi:
+// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[B_IMAG]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP3]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP5:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[B_REAL]], float [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP6:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP7:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[DOTREAL]], float [[TMP6]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP8:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[TMP7]], float [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP9:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP10:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[DOTIMAG]], float [[TMP9]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP11:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[TMP10]], float [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br label [[COMPLEX_DIV:%.*]]
+// PRMTD_STRICT: abs_rhsr_less_than_abs_rhsi:
+// PRMTD_STRICT-NEXT: [[TMP12:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[B_REAL]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP13:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP12]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP14:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[B_IMAG]], float [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP15:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP16:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[TMP15]], float [[DOTIMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP17:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[TMP16]], float [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP18:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP19:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[TMP18]], float [[DOTREAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP20:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[TMP19]], float [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br label [[COMPLEX_DIV]]
+// PRMTD_STRICT: complex_div:
+// PRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi float [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_STRICT-NEXT: [[TMP22:%.*]] = phi float [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: store float [[TMP21]], ptr [[DOTREALP1]], align 4
+// PRMTD_STRICT-NEXT: store float [[TMP22]], ptr [[DOTIMAGP2]], align 4
+// PRMTD_STRICT-NEXT: ret void
+//
+void divassignf(_Complex float *a, _Complex float b) {
+ *a /= b;
+}
+
// FULL-LABEL: define dso_local <2 x float> @mulf(
// FULL-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
// FULL-NEXT: entry:
@@ -1024,68 +1617,476 @@ _Complex float mulf(_Complex float a, _Complex float b) {
return a * b;
}
-// FULL-LABEL: define dso_local { double, double } @divd(
-// FULL-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] {
+// FULL-LABEL: define dso_local void @mulassignf(
+// FULL-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
// FULL-NEXT: entry:
-// FULL-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
-// FULL-NEXT: [[A:%.*]] = alloca { double, double }, align 8
-// FULL-NEXT: [[B:%.*]] = alloca { double, 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: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
-// FULL-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8
-// FULL-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
-// FULL-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], 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: [[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 [[A_REAL]], double noundef [[A_IMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2]]
-// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 0
-// FULL-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL]], 1
-// 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 [[TMP4]], ptr [[RETVAL_REALP]], align 8
-// FULL-NEXT: store double [[TMP5]], ptr [[RETVAL_IMAGP]], align 8
-// FULL-NEXT: [[TMP6:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
-// FULL-NEXT: ret { double, double } [[TMP6]]
+// FULL-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
+// FULL-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// FULL-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// FULL-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// FULL-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// FULL-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// FULL-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// FULL-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// FULL-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// 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]]
+// FULL: complex_mul_imag_nan:
+// FULL-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno float [[MUL_I]], [[MUL_I]]
+// FULL-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
+// FULL: complex_mul_libcall:
+// FULL-NEXT: [[CALL:%.*]] = call <2 x float> @__mulsc3(float noundef [[DOTREAL]], float noundef [[DOTIMAG]], float noundef [[B_REAL]], float noundef [[B_IMAG]]) #[[ATTR2]]
+// 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: [[DOTREALP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// FULL-NEXT: [[DOTIMAGP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// FULL-NEXT: store float [[REAL_MUL_PHI]], ptr [[DOTREALP2]], align 4
+// FULL-NEXT: store float [[IMAG_MUL_PHI]], ptr [[DOTIMAGP3]], align 4
+// FULL-NEXT: ret void
//
-// BASIC-LABEL: define dso_local { double, double } @divd(
-// BASIC-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] {
+// BASIC-LABEL: define dso_local void @mulassignf(
+// BASIC-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
// BASIC-NEXT: entry:
-// BASIC-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
-// BASIC-NEXT: [[A:%.*]] = alloca { double, double }, align 8
-// BASIC-NEXT: [[B:%.*]] = alloca { double, double }, align 8
-// BASIC-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
-// BASIC-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8
-// BASIC-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
-// BASIC-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8
-// BASIC-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
-// BASIC-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8
-// BASIC-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
-// BASIC-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8
-// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
-// BASIC-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
-// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
-// BASIC-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
-// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
-// BASIC-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
-// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
-// BASIC-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
-// BASIC-NEXT: [[TMP4:%.*]] = fmul double [[A_REAL]], [[B_REAL]]
-// BASIC-NEXT: [[TMP5:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]]
-// BASIC-NEXT: [[TMP6:%.*]] = fadd double [[TMP4]], [[TMP5]]
-// BASIC-NEXT: [[TMP7:%.*]] = fmul double [[B_REAL]], [[B_REAL]]
-// BASIC-NEXT: [[TMP8:%.*]] = fmul double [[B_IMAG]], [[B_IMAG]]
-// BASIC-NEXT: [[TMP9:%.*]] = fadd double [[TMP7]], [[TMP8]]
-// BASIC-NEXT: [[TMP10:%.*]] = fmul double [[A_IMAG]], [[B_REAL]]
-// BASIC-NEXT: [[TMP11:%.*]] = fmul double [[A_REAL]], [[B_IMAG]]
+// BASIC-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// BASIC-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// BASIC-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// BASIC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// BASIC-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// BASIC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// BASIC-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// BASIC-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// BASIC-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// BASIC-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// BASIC-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
+// BASIC-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
+// BASIC-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// BASIC-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// BASIC-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// BASIC-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// BASIC-NEXT: ret void
+//
+// IMPRVD-LABEL: define dso_local void @mulassignf(
+// IMPRVD-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// IMPRVD-NEXT: entry:
+// IMPRVD-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// IMPRVD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// IMPRVD-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// IMPRVD-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// IMPRVD-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// IMPRVD-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// IMPRVD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
+// IMPRVD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
+// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// IMPRVD-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// IMPRVD-NEXT: ret void
+//
+// PRMTD-LABEL: define dso_local void @mulassignf(
+// PRMTD-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// PRMTD-NEXT: entry:
+// PRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// PRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// PRMTD-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// PRMTD-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// PRMTD-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// PRMTD-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// PRMTD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
+// PRMTD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
+// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// PRMTD-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// PRMTD-NEXT: ret void
+//
+// X86WINPRMTD-LABEL: define dso_local void @mulassignf(
+// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], i64 noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD-NEXT: entry:
+// X86WINPRMTD-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// X86WINPRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: store i64 [[B_COERCE]], ptr [[B]], align 4
+// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// X86WINPRMTD-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// X86WINPRMTD-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// X86WINPRMTD-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// X86WINPRMTD-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// X86WINPRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// X86WINPRMTD-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
+// X86WINPRMTD-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
+// X86WINPRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// X86WINPRMTD-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// X86WINPRMTD-NEXT: ret void
+//
+// AVRFP32-LABEL: define dso_local void @mulassignf(
+// AVRFP32-SAME: ptr noundef [[A:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP32-NEXT: entry:
+// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1
+// AVRFP32-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP32-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1
+// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1
+// AVRFP32-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 1
+// AVRFP32-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 1
+// AVRFP32-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// AVRFP32-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// AVRFP32-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// AVRFP32-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// AVRFP32-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
+// AVRFP32-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
+// AVRFP32-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 1
+// AVRFP32-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 1
+// AVRFP32-NEXT: ret void
+//
+// AVRFP64-LABEL: define dso_local void @mulassignf(
+// AVRFP64-SAME: ptr noundef [[A:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP64-NEXT: entry:
+// AVRFP64-NEXT: [[B:%.*]] = alloca { float, float }, align 1
+// AVRFP64-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: store float [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: store float [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP64-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1
+// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1
+// AVRFP64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 1
+// AVRFP64-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 1
+// AVRFP64-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// AVRFP64-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// AVRFP64-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// AVRFP64-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// AVRFP64-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
+// AVRFP64-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
+// AVRFP64-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 1
+// AVRFP64-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 1
+// AVRFP64-NEXT: ret void
+//
+// BASIC_FAST-LABEL: define dso_local void @mulassignf(
+// BASIC_FAST-SAME: ptr noundef [[A:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] {
+// BASIC_FAST-NEXT: entry:
+// BASIC_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// BASIC_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// BASIC_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// BASIC_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// BASIC_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// BASIC_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_REAL]]
+// 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: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// BASIC_FAST-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// BASIC_FAST-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// BASIC_FAST-NEXT: ret void
+//
+// FULL_FAST-LABEL: define dso_local void @mulassignf(
+// FULL_FAST-SAME: ptr noundef [[A:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] {
+// FULL_FAST-NEXT: entry:
+// FULL_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// FULL_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL_FAST-NEXT: [[COERCE:%.*]] = alloca { float, float }, align 4
+// FULL_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// FULL_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// FULL_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// FULL_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// FULL_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// FULL_FAST-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// FULL_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_REAL]]
+// FULL_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_IMAG]]
+// FULL_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_IMAG]]
+// FULL_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_REAL]]
+// 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]]
+// FULL_FAST: complex_mul_imag_nan:
+// FULL_FAST-NEXT: [[ISNAN_CMP1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno float [[MUL_I]], [[MUL_I]]
+// FULL_FAST-NEXT: br i1 [[ISNAN_CMP1]], 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) [[DOTREAL]], float noundef nofpclass(nan inf) [[DOTIMAG]], float noundef nofpclass(nan inf) [[B_REAL]], float noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]]
+// 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: [[DOTREALP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTIMAGP3:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// FULL_FAST-NEXT: store float [[REAL_MUL_PHI]], ptr [[DOTREALP2]], align 4
+// FULL_FAST-NEXT: store float [[IMAG_MUL_PHI]], ptr [[DOTIMAGP3]], align 4
+// FULL_FAST-NEXT: ret void
+//
+// IMPRVD_FAST-LABEL: define dso_local void @mulassignf(
+// IMPRVD_FAST-SAME: ptr noundef [[A:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] {
+// IMPRVD_FAST-NEXT: entry:
+// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// IMPRVD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// IMPRVD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// IMPRVD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// IMPRVD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_REAL]]
+// 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: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// IMPRVD_FAST-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// IMPRVD_FAST-NEXT: ret void
+//
+// PRMTD_FAST-LABEL: define dso_local void @mulassignf(
+// PRMTD_FAST-SAME: ptr noundef [[A:%.*]], <2 x float> noundef nofpclass(nan inf) [[B_COERCE:%.*]]) #[[ATTR0]] {
+// PRMTD_FAST-NEXT: entry:
+// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// PRMTD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_FAST-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// PRMTD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// PRMTD_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// PRMTD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// PRMTD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTREAL]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[DOTIMAG]], [[B_REAL]]
+// 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: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// PRMTD_FAST-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// PRMTD_FAST-NEXT: ret void
+//
+// X86WINPRMTD_STRICT-LABEL: define dso_local void @mulassignf(
+// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], i64 noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD_STRICT-NEXT: entry:
+// X86WINPRMTD_STRICT-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// X86WINPRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: store i64 [[B_COERCE]], ptr [[B]], align 4
+// X86WINPRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// X86WINPRMTD_STRICT-NEXT: [[MUL_AC:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_BD:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_AD:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_BC:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_R:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[MUL_AC]], float [[MUL_BD]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_I:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[MUL_AD]], float [[MUL_BC]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// X86WINPRMTD_STRICT-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// X86WINPRMTD_STRICT-NEXT: ret void
+//
+// PRMTD_STRICT-LABEL: define dso_local void @mulassignf(
+// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0]] {
+// PRMTD_STRICT-NEXT: entry:
+// PRMTD_STRICT-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_STRICT-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// PRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4
+// PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4
+// PRMTD_STRICT-NEXT: [[MUL_AC:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_BD:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_AD:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTREAL]], float [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_BC:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_R:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[MUL_AC]], float [[MUL_BD]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_I:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[MUL_AD]], float [[MUL_BC]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 4
+// PRMTD_STRICT-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 4
+// PRMTD_STRICT-NEXT: ret void
+//
+void mulassignf(_Complex float *a, _Complex 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_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] {
+// FULL-NEXT: entry:
+// FULL-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// FULL-NEXT: [[A:%.*]] = alloca { double, double }, align 8
+// FULL-NEXT: [[B:%.*]] = alloca { double, 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: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// FULL-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8
+// FULL-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// FULL-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], 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: [[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 [[A_REAL]], double noundef [[A_IMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2]]
+// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 0
+// FULL-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL]], 1
+// 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 [[TMP4]], ptr [[RETVAL_REALP]], align 8
+// FULL-NEXT: store double [[TMP5]], ptr [[RETVAL_IMAGP]], align 8
+// FULL-NEXT: [[TMP6:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
+// FULL-NEXT: ret { double, double } [[TMP6]]
+//
+// BASIC-LABEL: define dso_local { double, double } @divd(
+// BASIC-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] {
+// BASIC-NEXT: entry:
+// BASIC-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// BASIC-NEXT: [[A:%.*]] = alloca { double, double }, align 8
+// BASIC-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// BASIC-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
+// BASIC-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8
+// BASIC-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
+// BASIC-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8
+// BASIC-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8
+// BASIC-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8
+// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
+// BASIC-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
+// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
+// BASIC-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
+// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// BASIC-NEXT: [[TMP4:%.*]] = fmul double [[A_REAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP5:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP6:%.*]] = fadd double [[TMP4]], [[TMP5]]
+// BASIC-NEXT: [[TMP7:%.*]] = fmul double [[B_REAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP8:%.*]] = fmul double [[B_IMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP9:%.*]] = fadd double [[TMP7]], [[TMP8]]
+// BASIC-NEXT: [[TMP10:%.*]] = fmul double [[A_IMAG]], [[B_REAL]]
+// BASIC-NEXT: [[TMP11:%.*]] = fmul double [[A_REAL]], [[B_IMAG]]
// BASIC-NEXT: [[TMP12:%.*]] = fsub double [[TMP10]], [[TMP11]]
// BASIC-NEXT: [[TMP13:%.*]] = fdiv double [[TMP6]], [[TMP9]]
// BASIC-NEXT: [[TMP14:%.*]] = fdiv double [[TMP12]], [[TMP9]]
@@ -1155,7 +2156,7 @@ _Complex float mulf(_Complex float a, _Complex float b) {
// IMPRVD-NEXT: ret { double, double } [[TMP26]]
//
// PRMTD-LABEL: define dso_local { double, double } @divd(
-// PRMTD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] {
+// PRMTD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2:[0-9]+]] {
// PRMTD-NEXT: entry:
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// PRMTD-NEXT: [[A:%.*]] = alloca { double, double }, align 8
@@ -1513,7 +2514,7 @@ _Complex float mulf(_Complex float a, _Complex float b) {
// IMPRVD_FAST-NEXT: ret { double, double } [[TMP26]]
//
// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) { double, double } @divd(
-// PRMTD_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1:[0-9]+]] {
+// PRMTD_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR2:[0-9]+]] {
// PRMTD_FAST-NEXT: entry:
// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8
@@ -1619,7 +2620,7 @@ _Complex float mulf(_Complex float a, _Complex float b) {
// X86WINPRMTD_STRICT-NEXT: ret void
//
// PRMTD_STRICT-LABEL: define dso_local { double, double } @divd(
-// PRMTD_STRICT-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2:[0-9]+]] {
+// PRMTD_STRICT-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR3:[0-9]+]] {
// PRMTD_STRICT-NEXT: entry:
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// PRMTD_STRICT-NEXT: [[A:%.*]] = alloca { double, double }, align 8
@@ -1668,71 +2669,683 @@ _Complex double divd(_Complex double a, _Complex double b) {
return a / b;
}
-// FULL-LABEL: define dso_local { double, double } @muld(
-// FULL-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// FULL-LABEL: define dso_local void @divassignd(
+// FULL-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
// FULL-NEXT: entry:
-// FULL-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
-// FULL-NEXT: [[A:%.*]] = alloca { double, double }, align 8
// FULL-NEXT: [[B:%.*]] = alloca { double, 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: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
-// FULL-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8
-// FULL-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
-// FULL-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], 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: [[A_ADDR:%.*]] = alloca ptr, 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 ptr [[A]], 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: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]]
-// FULL-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]]
-// FULL-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]]
-// FULL-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]]
-// FULL-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
-// FULL-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
-// FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno double [[MUL_R]], [[MUL_R]]
-// FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
-// FULL: complex_mul_imag_nan:
-// FULL-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno double [[MUL_I]], [[MUL_I]]
-// FULL-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
-// FULL: complex_mul_libcall:
-// FULL-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef [[A_REAL]], double noundef [[A_IMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2]]
-// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 0
-// FULL-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL]], 1
-// FULL-NEXT: br label [[COMPLEX_MUL_CONT]]
-// FULL: complex_mul_cont:
-// FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP4]], [[COMPLEX_MUL_LIBCALL]] ]
-// FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP5]], [[COMPLEX_MUL_LIBCALL]] ]
-// 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 [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 8
-// FULL-NEXT: store double [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 8
-// FULL-NEXT: [[TMP6:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
-// FULL-NEXT: ret { double, double } [[TMP6]]
+// FULL-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// FULL-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// FULL-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// FULL-NEXT: [[CALL:%.*]] = call { double, double } @__divdc3(double noundef [[DOTREAL]], double noundef [[DOTIMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2]]
+// FULL-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL]], 0
+// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 1
+// FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// FULL-NEXT: store double [[TMP3]], ptr [[DOTREALP1]], align 8
+// FULL-NEXT: store double [[TMP4]], ptr [[DOTIMAGP2]], align 8
+// FULL-NEXT: ret void
//
-// BASIC-LABEL: define dso_local { double, double } @muld(
-// BASIC-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// BASIC-LABEL: define dso_local void @divassignd(
+// BASIC-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
// BASIC-NEXT: entry:
-// BASIC-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
-// BASIC-NEXT: [[A:%.*]] = alloca { double, double }, align 8
// BASIC-NEXT: [[B:%.*]] = alloca { double, double }, align 8
-// BASIC-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
-// BASIC-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8
-// BASIC-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
-// BASIC-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8
-// BASIC-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
-// BASIC-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8
-// BASIC-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
-// BASIC-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8
-// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
-// BASIC-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
-// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
+// BASIC-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// BASIC-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// BASIC-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// BASIC-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// BASIC-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// BASIC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// BASIC-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// BASIC-NEXT: [[TMP3:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP4:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]]
+// BASIC-NEXT: [[TMP6:%.*]] = fmul double [[B_REAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP7:%.*]] = fmul double [[B_IMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP8:%.*]] = fadd double [[TMP6]], [[TMP7]]
+// BASIC-NEXT: [[TMP9:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// BASIC-NEXT: [[TMP10:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP11:%.*]] = fsub double [[TMP9]], [[TMP10]]
+// BASIC-NEXT: [[TMP12:%.*]] = fdiv double [[TMP5]], [[TMP8]]
+// BASIC-NEXT: [[TMP13:%.*]] = fdiv double [[TMP11]], [[TMP8]]
+// BASIC-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// BASIC-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// BASIC-NEXT: store double [[TMP12]], ptr [[DOTREALP1]], align 8
+// BASIC-NEXT: store double [[TMP13]], ptr [[DOTIMAGP2]], align 8
+// BASIC-NEXT: ret void
+//
+// IMPRVD-LABEL: define dso_local void @divassignd(
+// IMPRVD-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// IMPRVD-NEXT: entry:
+// IMPRVD-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, 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 ptr [[A]], 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: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], 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 [[DOTIMAG]], [[TMP5]]
+// IMPRVD-NEXT: [[TMP9:%.*]] = fadd double [[DOTREAL]], [[TMP8]]
+// IMPRVD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP7]]
+// IMPRVD-NEXT: [[TMP11:%.*]] = fmul double [[DOTREAL]], [[TMP5]]
+// IMPRVD-NEXT: [[TMP12:%.*]] = fsub double [[DOTIMAG]], [[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 [[DOTREAL]], [[TMP14]]
+// IMPRVD-NEXT: [[TMP18:%.*]] = fadd double [[TMP17]], [[DOTIMAG]]
+// IMPRVD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP16]]
+// IMPRVD-NEXT: [[TMP20:%.*]] = fmul double [[DOTIMAG]], [[TMP14]]
+// IMPRVD-NEXT: [[TMP21:%.*]] = fsub double [[TMP20]], [[DOTREAL]]
+// 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: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// IMPRVD-NEXT: store double [[TMP23]], ptr [[DOTREALP1]], align 8
+// IMPRVD-NEXT: store double [[TMP24]], ptr [[DOTIMAGP2]], align 8
+// IMPRVD-NEXT: ret void
+//
+// PRMTD-LABEL: define dso_local void @divassignd(
+// PRMTD-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// PRMTD-NEXT: entry:
+// PRMTD-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, 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 ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// PRMTD-NEXT: [[TMP3:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]])
+// PRMTD-NEXT: [[TMP4:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]])
+// PRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP3]], [[TMP4]]
+// 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: [[TMP5:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]]
+// PRMTD-NEXT: [[TMP6:%.*]] = fmul double [[TMP5]], [[B_IMAG]]
+// PRMTD-NEXT: [[TMP7:%.*]] = fadd double [[B_REAL]], [[TMP6]]
+// PRMTD-NEXT: [[TMP8:%.*]] = fmul double [[DOTIMAG]], [[TMP5]]
+// PRMTD-NEXT: [[TMP9:%.*]] = fadd double [[DOTREAL]], [[TMP8]]
+// PRMTD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP7]]
+// PRMTD-NEXT: [[TMP11:%.*]] = fmul double [[DOTREAL]], [[TMP5]]
+// PRMTD-NEXT: [[TMP12:%.*]] = fsub double [[DOTIMAG]], [[TMP11]]
+// PRMTD-NEXT: [[TMP13:%.*]] = fdiv double [[TMP12]], [[TMP7]]
+// PRMTD-NEXT: br label [[COMPLEX_DIV:%.*]]
+// PRMTD: abs_rhsr_less_than_abs_rhsi:
+// PRMTD-NEXT: [[TMP14:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]]
+// PRMTD-NEXT: [[TMP15:%.*]] = fmul double [[TMP14]], [[B_REAL]]
+// PRMTD-NEXT: [[TMP16:%.*]] = fadd double [[B_IMAG]], [[TMP15]]
+// PRMTD-NEXT: [[TMP17:%.*]] = fmul double [[DOTREAL]], [[TMP14]]
+// PRMTD-NEXT: [[TMP18:%.*]] = fadd double [[TMP17]], [[DOTIMAG]]
+// PRMTD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP16]]
+// PRMTD-NEXT: [[TMP20:%.*]] = fmul double [[DOTIMAG]], [[TMP14]]
+// PRMTD-NEXT: [[TMP21:%.*]] = fsub double [[TMP20]], [[DOTREAL]]
+// PRMTD-NEXT: [[TMP22:%.*]] = fdiv double [[TMP21]], [[TMP16]]
+// PRMTD-NEXT: br label [[COMPLEX_DIV]]
+// PRMTD: complex_div:
+// PRMTD-NEXT: [[TMP23:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD-NEXT: [[TMP24:%.*]] = phi double [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD-NEXT: store double [[TMP23]], ptr [[DOTREALP1]], align 8
+// PRMTD-NEXT: store double [[TMP24]], ptr [[DOTIMAGP2]], align 8
+// PRMTD-NEXT: ret void
+//
+// X86WINPRMTD-LABEL: define dso_local void @divassignd(
+// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD-NEXT: entry:
+// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
+// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// X86WINPRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// X86WINPRMTD-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]])
+// X86WINPRMTD-NEXT: [[TMP2:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]])
+// X86WINPRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fmul double [[TMP3]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fadd double [[B_REAL]], [[TMP4]]
+// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fmul double [[DOTIMAG]], [[TMP3]]
+// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fadd double [[DOTREAL]], [[TMP6]]
+// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fdiv double [[TMP7]], [[TMP5]]
+// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fmul double [[DOTREAL]], [[TMP3]]
+// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fsub double [[DOTIMAG]], [[TMP9]]
+// X86WINPRMTD-NEXT: [[TMP11:%.*]] = fdiv double [[TMP10]], [[TMP5]]
+// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV:%.*]]
+// X86WINPRMTD: abs_rhsr_less_than_abs_rhsi:
+// X86WINPRMTD-NEXT: [[TMP12:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[TMP13:%.*]] = fmul double [[TMP12]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[TMP14:%.*]] = fadd double [[B_IMAG]], [[TMP13]]
+// X86WINPRMTD-NEXT: [[TMP15:%.*]] = fmul double [[DOTREAL]], [[TMP12]]
+// X86WINPRMTD-NEXT: [[TMP16:%.*]] = fadd double [[TMP15]], [[DOTIMAG]]
+// X86WINPRMTD-NEXT: [[TMP17:%.*]] = fdiv double [[TMP16]], [[TMP14]]
+// X86WINPRMTD-NEXT: [[TMP18:%.*]] = fmul double [[DOTIMAG]], [[TMP12]]
+// X86WINPRMTD-NEXT: [[TMP19:%.*]] = fsub double [[TMP18]], [[DOTREAL]]
+// X86WINPRMTD-NEXT: [[TMP20:%.*]] = fdiv double [[TMP19]], [[TMP14]]
+// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV]]
+// X86WINPRMTD: complex_div:
+// X86WINPRMTD-NEXT: [[TMP21:%.*]] = phi double [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD-NEXT: [[TMP22:%.*]] = phi double [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: store double [[TMP21]], ptr [[DOTREALP1]], align 8
+// X86WINPRMTD-NEXT: store double [[TMP22]], ptr [[DOTIMAGP2]], align 8
+// X86WINPRMTD-NEXT: ret void
+//
+// AVRFP32-LABEL: define dso_local void @divassignd(
+// AVRFP32-SAME: ptr noundef [[A:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP32-NEXT: entry:
+// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1
+// AVRFP32-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP32-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1
+// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1
+// AVRFP32-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 1
+// AVRFP32-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 1
+// AVRFP32-NEXT: [[TMP3:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_REAL]])
+// AVRFP32-NEXT: [[TMP4:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_IMAG]])
+// AVRFP32-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP3]], [[TMP4]]
+// AVRFP32-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// AVRFP32: abs_rhsr_greater_or_equal_abs_rhsi:
+// AVRFP32-NEXT: [[TMP5:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]]
+// AVRFP32-NEXT: [[TMP6:%.*]] = fmul float [[TMP5]], [[B_IMAG]]
+// AVRFP32-NEXT: [[TMP7:%.*]] = fadd float [[B_REAL]], [[TMP6]]
+// AVRFP32-NEXT: [[TMP8:%.*]] = fmul float [[DOTIMAG]], [[TMP5]]
+// AVRFP32-NEXT: [[TMP9:%.*]] = fadd float [[DOTREAL]], [[TMP8]]
+// AVRFP32-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP7]]
+// AVRFP32-NEXT: [[TMP11:%.*]] = fmul float [[DOTREAL]], [[TMP5]]
+// AVRFP32-NEXT: [[TMP12:%.*]] = fsub float [[DOTIMAG]], [[TMP11]]
+// AVRFP32-NEXT: [[TMP13:%.*]] = fdiv float [[TMP12]], [[TMP7]]
+// AVRFP32-NEXT: br label [[COMPLEX_DIV:%.*]]
+// AVRFP32: abs_rhsr_less_than_abs_rhsi:
+// AVRFP32-NEXT: [[TMP14:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]]
+// AVRFP32-NEXT: [[TMP15:%.*]] = fmul float [[TMP14]], [[B_REAL]]
+// AVRFP32-NEXT: [[TMP16:%.*]] = fadd float [[B_IMAG]], [[TMP15]]
+// AVRFP32-NEXT: [[TMP17:%.*]] = fmul float [[DOTREAL]], [[TMP14]]
+// AVRFP32-NEXT: [[TMP18:%.*]] = fadd float [[TMP17]], [[DOTIMAG]]
+// AVRFP32-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP16]]
+// AVRFP32-NEXT: [[TMP20:%.*]] = fmul float [[DOTIMAG]], [[TMP14]]
+// AVRFP32-NEXT: [[TMP21:%.*]] = fsub float [[TMP20]], [[DOTREAL]]
+// AVRFP32-NEXT: [[TMP22:%.*]] = fdiv float [[TMP21]], [[TMP16]]
+// AVRFP32-NEXT: br label [[COMPLEX_DIV]]
+// AVRFP32: complex_div:
+// AVRFP32-NEXT: [[TMP23:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP32-NEXT: [[TMP24:%.*]] = phi float [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP32-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[TMP23]], ptr [[DOTREALP1]], align 1
+// AVRFP32-NEXT: store float [[TMP24]], ptr [[DOTIMAGP2]], align 1
+// AVRFP32-NEXT: ret void
+//
+// AVRFP64-LABEL: define dso_local void @divassignd(
+// AVRFP64-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP64-NEXT: entry:
+// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 1
+// AVRFP64-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP64-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 1
+// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 1
+// AVRFP64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 1
+// AVRFP64-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 1
+// AVRFP64-NEXT: [[TMP3:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[B_REAL]])
+// AVRFP64-NEXT: [[TMP4:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[B_IMAG]])
+// AVRFP64-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP3]], [[TMP4]]
+// AVRFP64-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// AVRFP64: abs_rhsr_greater_or_equal_abs_rhsi:
+// AVRFP64-NEXT: [[TMP5:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]]
+// AVRFP64-NEXT: [[TMP6:%.*]] = fmul double [[TMP5]], [[B_IMAG]]
+// AVRFP64-NEXT: [[TMP7:%.*]] = fadd double [[B_REAL]], [[TMP6]]
+// AVRFP64-NEXT: [[TMP8:%.*]] = fmul double [[DOTIMAG]], [[TMP5]]
+// AVRFP64-NEXT: [[TMP9:%.*]] = fadd double [[DOTREAL]], [[TMP8]]
+// AVRFP64-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP7]]
+// AVRFP64-NEXT: [[TMP11:%.*]] = fmul double [[DOTREAL]], [[TMP5]]
+// AVRFP64-NEXT: [[TMP12:%.*]] = fsub double [[DOTIMAG]], [[TMP11]]
+// AVRFP64-NEXT: [[TMP13:%.*]] = fdiv double [[TMP12]], [[TMP7]]
+// AVRFP64-NEXT: br label [[COMPLEX_DIV:%.*]]
+// AVRFP64: abs_rhsr_less_than_abs_rhsi:
+// AVRFP64-NEXT: [[TMP14:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]]
+// AVRFP64-NEXT: [[TMP15:%.*]] = fmul double [[TMP14]], [[B_REAL]]
+// AVRFP64-NEXT: [[TMP16:%.*]] = fadd double [[B_IMAG]], [[TMP15]]
+// AVRFP64-NEXT: [[TMP17:%.*]] = fmul double [[DOTREAL]], [[TMP14]]
+// AVRFP64-NEXT: [[TMP18:%.*]] = fadd double [[TMP17]], [[DOTIMAG]]
+// AVRFP64-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP16]]
+// AVRFP64-NEXT: [[TMP20:%.*]] = fmul double [[DOTIMAG]], [[TMP14]]
+// AVRFP64-NEXT: [[TMP21:%.*]] = fsub double [[TMP20]], [[DOTREAL]]
+// AVRFP64-NEXT: [[TMP22:%.*]] = fdiv double [[TMP21]], [[TMP16]]
+// AVRFP64-NEXT: br label [[COMPLEX_DIV]]
+// AVRFP64: complex_div:
+// AVRFP64-NEXT: [[TMP23:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP64-NEXT: [[TMP24:%.*]] = phi double [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP64-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: store double [[TMP23]], ptr [[DOTREALP1]], align 1
+// AVRFP64-NEXT: store double [[TMP24]], ptr [[DOTIMAGP2]], align 1
+// AVRFP64-NEXT: ret void
+//
+// BASIC_FAST-LABEL: define dso_local void @divassignd(
+// BASIC_FAST-SAME: ptr noundef [[A:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// BASIC_FAST-NEXT: entry:
+// BASIC_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// BASIC_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// BASIC_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// BASIC_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// BASIC_FAST-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// BASIC_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// BASIC_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP3]], [[TMP4]]
+// BASIC_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[B_REAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[B_IMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP8:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP6]], [[TMP7]]
+// BASIC_FAST-NEXT: [[TMP9:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP10:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP11:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[TMP9]], [[TMP10]]
+// BASIC_FAST-NEXT: [[TMP12:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP5]], [[TMP8]]
+// BASIC_FAST-NEXT: [[TMP13:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP11]], [[TMP8]]
+// BASIC_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// BASIC_FAST-NEXT: store double [[TMP12]], ptr [[DOTREALP1]], align 8
+// BASIC_FAST-NEXT: store double [[TMP13]], ptr [[DOTIMAGP2]], align 8
+// BASIC_FAST-NEXT: ret void
+//
+// FULL_FAST-LABEL: define dso_local void @divassignd(
+// FULL_FAST-SAME: ptr noundef [[A:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// FULL_FAST-NEXT: entry:
+// FULL_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// FULL_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// FULL_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// FULL_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// FULL_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// FULL_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// FULL_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// FULL_FAST-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// FULL_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// FULL_FAST-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// FULL_FAST-NEXT: [[CALL:%.*]] = call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) { double, double } @__divdc3(double noundef nofpclass(nan inf) [[DOTREAL]], double noundef nofpclass(nan inf) [[DOTIMAG]], double noundef nofpclass(nan inf) [[B_REAL]], double noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]]
+// FULL_FAST-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL]], 0
+// FULL_FAST-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 1
+// FULL_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// FULL_FAST-NEXT: store double [[TMP3]], ptr [[DOTREALP1]], align 8
+// FULL_FAST-NEXT: store double [[TMP4]], ptr [[DOTIMAGP2]], align 8
+// FULL_FAST-NEXT: ret void
+//
+// IMPRVD_FAST-LABEL: define dso_local void @divassignd(
+// IMPRVD_FAST-SAME: ptr noundef [[A:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// IMPRVD_FAST-NEXT: entry:
+// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// IMPRVD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// IMPRVD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// IMPRVD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// IMPRVD_FAST-NEXT: [[TMP3:%.*]] = call reassoc nnan ninf nsz arcp afn double @llvm.fabs.f64(double [[B_REAL]])
+// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = call reassoc nnan ninf nsz arcp afn double @llvm.fabs.f64(double [[B_IMAG]])
+// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt double [[TMP3]], [[TMP4]]
+// 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: [[TMP5:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[B_IMAG]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[TMP5]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[B_REAL]], [[TMP6]]
+// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[TMP5]]
+// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[TMP8]]
+// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP9]], [[TMP7]]
+// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[TMP5]]
+// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[TMP11]]
+// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP12]], [[TMP7]]
+// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]]
+// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi:
+// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[B_REAL]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[TMP14]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[B_IMAG]], [[TMP15]]
+// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[TMP14]]
+// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP17]], [[DOTIMAG]]
+// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP18]], [[TMP16]]
+// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[TMP14]]
+// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[TMP20]], [[DOTREAL]]
+// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP21]], [[TMP16]]
+// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]]
+// IMPRVD_FAST: complex_div:
+// IMPRVD_FAST-NEXT: [[TMP23:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD_FAST-NEXT: [[TMP24:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store double [[TMP23]], ptr [[DOTREALP1]], align 8
+// IMPRVD_FAST-NEXT: store double [[TMP24]], ptr [[DOTIMAGP2]], align 8
+// IMPRVD_FAST-NEXT: ret void
+//
+// PRMTD_FAST-LABEL: define dso_local void @divassignd(
+// PRMTD_FAST-SAME: ptr noundef [[A:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// PRMTD_FAST-NEXT: entry:
+// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// PRMTD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// PRMTD_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// PRMTD_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// PRMTD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// PRMTD_FAST-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// PRMTD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// PRMTD_FAST-NEXT: [[TMP3:%.*]] = call reassoc nnan ninf nsz arcp afn double @llvm.fabs.f64(double [[B_REAL]])
+// PRMTD_FAST-NEXT: [[TMP4:%.*]] = call reassoc nnan ninf nsz arcp afn double @llvm.fabs.f64(double [[B_IMAG]])
+// PRMTD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt double [[TMP3]], [[TMP4]]
+// 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: [[TMP5:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[B_IMAG]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[TMP5]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[B_REAL]], [[TMP6]]
+// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[TMP5]]
+// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[TMP8]]
+// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP9]], [[TMP7]]
+// PRMTD_FAST-NEXT: [[TMP11:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[TMP5]]
+// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[TMP11]]
+// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP12]], [[TMP7]]
+// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]]
+// PRMTD_FAST: abs_rhsr_less_than_abs_rhsi:
+// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[B_REAL]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[TMP14]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[B_IMAG]], [[TMP15]]
+// PRMTD_FAST-NEXT: [[TMP17:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[TMP14]]
+// PRMTD_FAST-NEXT: [[TMP18:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[TMP17]], [[DOTIMAG]]
+// PRMTD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP18]], [[TMP16]]
+// PRMTD_FAST-NEXT: [[TMP20:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[TMP14]]
+// PRMTD_FAST-NEXT: [[TMP21:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[TMP20]], [[DOTREAL]]
+// PRMTD_FAST-NEXT: [[TMP22:%.*]] = fdiv reassoc nnan ninf nsz arcp afn double [[TMP21]], [[TMP16]]
+// PRMTD_FAST-NEXT: br label [[COMPLEX_DIV]]
+// PRMTD_FAST: complex_div:
+// PRMTD_FAST-NEXT: [[TMP23:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_FAST-NEXT: [[TMP24:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store double [[TMP23]], ptr [[DOTREALP1]], align 8
+// PRMTD_FAST-NEXT: store double [[TMP24]], ptr [[DOTIMAGP2]], align 8
+// PRMTD_FAST-NEXT: ret void
+//
+// X86WINPRMTD_STRICT-LABEL: define dso_local void @divassignd(
+// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD_STRICT-NEXT: entry:
+// X86WINPRMTD_STRICT-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]]) #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP2:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]]) #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double [[TMP2]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// X86WINPRMTD_STRICT: abs_rhsr_greater_or_equal_abs_rhsi:
+// X86WINPRMTD_STRICT-NEXT: [[TMP3:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_IMAG]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP4:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP3]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP5:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_REAL]], double [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP6:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP7:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[DOTREAL]], double [[TMP6]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP8:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP7]], double [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP9:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP10:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[DOTIMAG]], double [[TMP9]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP11:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP10]], double [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br label [[COMPLEX_DIV:%.*]]
+// X86WINPRMTD_STRICT: abs_rhsr_less_than_abs_rhsi:
+// X86WINPRMTD_STRICT-NEXT: [[TMP12:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_REAL]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP13:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP12]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP14:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_IMAG]], double [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP15:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP16:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[TMP15]], double [[DOTIMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP17:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP16]], double [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP18:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP19:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[TMP18]], double [[DOTREAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP20:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP19]], double [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br label [[COMPLEX_DIV]]
+// X86WINPRMTD_STRICT: complex_div:
+// X86WINPRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi double [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD_STRICT-NEXT: [[TMP22:%.*]] = phi double [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: store double [[TMP21]], ptr [[DOTREALP1]], align 8
+// X86WINPRMTD_STRICT-NEXT: store double [[TMP22]], ptr [[DOTIMAGP2]], align 8
+// X86WINPRMTD_STRICT-NEXT: ret void
+//
+// PRMTD_STRICT-LABEL: define dso_local void @divassignd(
+// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR3]] {
+// PRMTD_STRICT-NEXT: entry:
+// PRMTD_STRICT-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, 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 ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]]) #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]]) #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP3]], double [[TMP4]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// PRMTD_STRICT: abs_rhsr_greater_or_equal_abs_rhsi:
+// PRMTD_STRICT-NEXT: [[TMP5:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_IMAG]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP6:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP5]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP7:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_REAL]], double [[TMP6]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP8:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP9:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[DOTREAL]], double [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP10:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP9]], double [[TMP7]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP11:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP12:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[DOTIMAG]], double [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP13:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP12]], double [[TMP7]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br label [[COMPLEX_DIV:%.*]]
+// PRMTD_STRICT: abs_rhsr_less_than_abs_rhsi:
+// PRMTD_STRICT-NEXT: [[TMP14:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_REAL]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP15:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP14]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP16:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_IMAG]], double [[TMP15]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP17:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP18:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[TMP17]], double [[DOTIMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP19:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP18]], double [[TMP16]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP20:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP21:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[TMP20]], double [[DOTREAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP22:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP21]], double [[TMP16]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br label [[COMPLEX_DIV]]
+// PRMTD_STRICT: complex_div:
+// PRMTD_STRICT-NEXT: [[TMP23:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_STRICT-NEXT: [[TMP24:%.*]] = phi double [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: store double [[TMP23]], ptr [[DOTREALP1]], align 8
+// PRMTD_STRICT-NEXT: store double [[TMP24]], ptr [[DOTIMAGP2]], align 8
+// PRMTD_STRICT-NEXT: ret void
+//
+void divassignd(_Complex double *a, _Complex double b) {
+ *a /= b;
+}
+
+// FULL-LABEL: define dso_local { double, double } @muld(
+// FULL-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// FULL-NEXT: entry:
+// FULL-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// FULL-NEXT: [[A:%.*]] = alloca { double, double }, align 8
+// FULL-NEXT: [[B:%.*]] = alloca { double, 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: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// FULL-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8
+// FULL-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// FULL-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], 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: [[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: [[MUL_AC:%.*]] = fmul double [[A_REAL]], [[B_REAL]]
+// FULL-NEXT: [[MUL_BD:%.*]] = fmul double [[A_IMAG]], [[B_IMAG]]
+// FULL-NEXT: [[MUL_AD:%.*]] = fmul double [[A_REAL]], [[B_IMAG]]
+// FULL-NEXT: [[MUL_BC:%.*]] = fmul double [[A_IMAG]], [[B_REAL]]
+// FULL-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// FULL-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno double [[MUL_R]], [[MUL_R]]
+// FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
+// FULL: complex_mul_imag_nan:
+// FULL-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno double [[MUL_I]], [[MUL_I]]
+// FULL-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
+// FULL: complex_mul_libcall:
+// FULL-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef [[A_REAL]], double noundef [[A_IMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2]]
+// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 0
+// FULL-NEXT: [[TMP5:%.*]] = extractvalue { double, double } [[CALL]], 1
+// FULL-NEXT: br label [[COMPLEX_MUL_CONT]]
+// FULL: complex_mul_cont:
+// FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP4]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP5]], [[COMPLEX_MUL_LIBCALL]] ]
+// 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 [[REAL_MUL_PHI]], ptr [[RETVAL_REALP]], align 8
+// FULL-NEXT: store double [[IMAG_MUL_PHI]], ptr [[RETVAL_IMAGP]], align 8
+// FULL-NEXT: [[TMP6:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
+// FULL-NEXT: ret { double, double } [[TMP6]]
+//
+// BASIC-LABEL: define dso_local { double, double } @muld(
+// BASIC-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// BASIC-NEXT: entry:
+// BASIC-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
+// BASIC-NEXT: [[A:%.*]] = alloca { double, double }, align 8
+// BASIC-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// BASIC-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
+// BASIC-NEXT: store double [[A_COERCE0]], ptr [[TMP0]], align 8
+// BASIC-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
+// BASIC-NEXT: store double [[A_COERCE1]], ptr [[TMP1]], align 8
+// BASIC-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: store double [[B_COERCE0]], ptr [[TMP2]], align 8
+// BASIC-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: store double [[B_COERCE1]], ptr [[TMP3]], align 8
+// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
+// BASIC-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
+// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
// BASIC-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// BASIC-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
@@ -1787,7 +3400,7 @@ _Complex double divd(_Complex double a, _Complex double b) {
// IMPRVD-NEXT: ret { double, double } [[TMP4]]
//
// PRMTD-LABEL: define dso_local { double, double } @muld(
-// PRMTD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// PRMTD-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2]] {
// PRMTD-NEXT: entry:
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// PRMTD-NEXT: [[A:%.*]] = alloca { double, double }, align 8
@@ -2053,7 +3666,7 @@ _Complex double divd(_Complex double a, _Complex double b) {
// IMPRVD_FAST-NEXT: ret { double, double } [[TMP4]]
//
// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) { double, double } @muld(
-// PRMTD_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// PRMTD_FAST-SAME: double noundef nofpclass(nan inf) [[A_COERCE0:%.*]], double noundef nofpclass(nan inf) [[A_COERCE1:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR2]] {
// PRMTD_FAST-NEXT: entry:
// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// PRMTD_FAST-NEXT: [[A:%.*]] = alloca { double, double }, align 8
@@ -2125,7 +3738,7 @@ _Complex double divd(_Complex double a, _Complex double b) {
// X86WINPRMTD_STRICT-NEXT: ret void
//
// PRMTD_STRICT-LABEL: define dso_local { double, double } @muld(
-// PRMTD_STRICT-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// PRMTD_STRICT-SAME: double noundef [[A_COERCE0:%.*]], double noundef [[A_COERCE1:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR3]] {
// PRMTD_STRICT-NEXT: entry:
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { double, double }, align 8
// PRMTD_STRICT-NEXT: [[A:%.*]] = alloca { double, double }, align 8
@@ -2163,42 +3776,469 @@ _Complex double muld(_Complex double a, _Complex double b) {
return a * b;
}
-// FULL-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
-// FULL-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// FULL-LABEL: define dso_local void @mulassignd(
+// FULL-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
// FULL-NEXT: entry:
-// FULL-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, 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: [[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: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef [[A_REAL]], x86_fp80 noundef [[A_IMAG]], x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]]) #[[ATTR2]]
-// FULL-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0
-// FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1
-// 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 [[TMP0]], ptr [[RETVAL_REALP]], align 16
-// FULL-NEXT: store x86_fp80 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16
-// FULL-NEXT: [[TMP2:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
-// FULL-NEXT: ret { x86_fp80, x86_fp80 } [[TMP2]]
+// FULL-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, 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 ptr [[A]], 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: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// FULL-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// FULL-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// FULL-NEXT: [[MUL_AC:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// FULL-NEXT: [[MUL_BD:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// FULL-NEXT: [[MUL_AD:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// FULL-NEXT: [[MUL_BC:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// FULL-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// FULL-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno double [[MUL_R]], [[MUL_R]]
+// FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
+// FULL: complex_mul_imag_nan:
+// FULL-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno double [[MUL_I]], [[MUL_I]]
+// FULL-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
+// FULL: complex_mul_libcall:
+// FULL-NEXT: [[CALL:%.*]] = call { double, double } @__muldc3(double noundef [[DOTREAL]], double noundef [[DOTIMAG]], double noundef [[B_REAL]], double noundef [[B_IMAG]]) #[[ATTR2]]
+// FULL-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL]], 0
+// FULL-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 1
+// FULL-NEXT: br label [[COMPLEX_MUL_CONT]]
+// FULL: complex_mul_cont:
+// FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP3]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP4]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL-NEXT: [[DOTREALP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// FULL-NEXT: [[DOTIMAGP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// FULL-NEXT: store double [[REAL_MUL_PHI]], ptr [[DOTREALP2]], align 8
+// FULL-NEXT: store double [[IMAG_MUL_PHI]], ptr [[DOTIMAGP3]], align 8
+// FULL-NEXT: ret void
//
-// BASIC-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
-// BASIC-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// BASIC-LABEL: define dso_local void @mulassignd(
+// BASIC-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR1]] {
// BASIC-NEXT: entry:
-// BASIC-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
-// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
-// BASIC-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16
-// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1
-// BASIC-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16
-// 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: [[TMP0:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_REAL]]
-// BASIC-NEXT: [[TMP1:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// BASIC-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// BASIC-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// BASIC-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// BASIC-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// BASIC-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// BASIC-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// BASIC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// BASIC-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// BASIC-NEXT: [[MUL_AC:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// BASIC-NEXT: [[MUL_BD:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[MUL_AD:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// BASIC-NEXT: [[MUL_BC:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// BASIC-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// BASIC-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// BASIC-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// BASIC-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// BASIC-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// BASIC-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// BASIC-NEXT: ret void
+//
+// IMPRVD-LABEL: define dso_local void @mulassignd(
+// IMPRVD-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// IMPRVD-NEXT: entry:
+// IMPRVD-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, 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 ptr [[A]], 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: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// IMPRVD-NEXT: [[MUL_AC:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// IMPRVD-NEXT: [[MUL_BD:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// IMPRVD-NEXT: [[MUL_AD:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// IMPRVD-NEXT: [[MUL_BC:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// IMPRVD-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// IMPRVD-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// IMPRVD-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// IMPRVD-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// IMPRVD-NEXT: ret void
+//
+// PRMTD-LABEL: define dso_local void @mulassignd(
+// PRMTD-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// PRMTD-NEXT: entry:
+// PRMTD-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, 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 ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// PRMTD-NEXT: [[MUL_AC:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// PRMTD-NEXT: [[MUL_BD:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// PRMTD-NEXT: [[MUL_AD:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// PRMTD-NEXT: [[MUL_BC:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// PRMTD-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// PRMTD-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// PRMTD-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// PRMTD-NEXT: ret void
+//
+// X86WINPRMTD-LABEL: define dso_local void @mulassignd(
+// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD-NEXT: entry:
+// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
+// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// X86WINPRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// X86WINPRMTD-NEXT: [[MUL_AC:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[MUL_BD:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[MUL_AD:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[MUL_BC:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// X86WINPRMTD-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// X86WINPRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// X86WINPRMTD-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// X86WINPRMTD-NEXT: ret void
+//
+// AVRFP32-LABEL: define dso_local void @mulassignd(
+// AVRFP32-SAME: ptr noundef [[A:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP32-NEXT: entry:
+// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1
+// AVRFP32-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP32-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1
+// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1
+// AVRFP32-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 1
+// AVRFP32-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 1
+// AVRFP32-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// AVRFP32-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// AVRFP32-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// AVRFP32-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// AVRFP32-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
+// AVRFP32-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
+// AVRFP32-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 1
+// AVRFP32-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 1
+// AVRFP32-NEXT: ret void
+//
+// AVRFP64-LABEL: define dso_local void @mulassignd(
+// AVRFP64-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP64-NEXT: entry:
+// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 1
+// AVRFP64-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP64-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 1
+// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 1
+// AVRFP64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 1
+// AVRFP64-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 1
+// AVRFP64-NEXT: [[MUL_AC:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// AVRFP64-NEXT: [[MUL_BD:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// AVRFP64-NEXT: [[MUL_AD:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// AVRFP64-NEXT: [[MUL_BC:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// AVRFP64-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// AVRFP64-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// AVRFP64-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 1
+// AVRFP64-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 1
+// AVRFP64-NEXT: ret void
+//
+// BASIC_FAST-LABEL: define dso_local void @mulassignd(
+// BASIC_FAST-SAME: ptr noundef [[A:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// BASIC_FAST-NEXT: entry:
+// BASIC_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// BASIC_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// BASIC_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// BASIC_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// BASIC_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// BASIC_FAST-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// BASIC_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// BASIC_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[MUL_AC]], [[MUL_BD]]
+// BASIC_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[MUL_AD]], [[MUL_BC]]
+// BASIC_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// BASIC_FAST-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// BASIC_FAST-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// BASIC_FAST-NEXT: ret void
+//
+// FULL_FAST-LABEL: define dso_local void @mulassignd(
+// FULL_FAST-SAME: ptr noundef [[A:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR1]] {
+// FULL_FAST-NEXT: entry:
+// FULL_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// FULL_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// FULL_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// FULL_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// FULL_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// FULL_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// FULL_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// FULL_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// FULL_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// FULL_FAST-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// FULL_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// FULL_FAST-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// FULL_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_REAL]]
+// FULL_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_IMAG]]
+// FULL_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_IMAG]]
+// FULL_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_REAL]]
+// FULL_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[MUL_AC]], [[MUL_BD]]
+// FULL_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[MUL_AD]], [[MUL_BC]]
+// FULL_FAST-NEXT: [[ISNAN_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno double [[MUL_R]], [[MUL_R]]
+// FULL_FAST-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
+// FULL_FAST: complex_mul_imag_nan:
+// FULL_FAST-NEXT: [[ISNAN_CMP1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno double [[MUL_I]], [[MUL_I]]
+// FULL_FAST-NEXT: br i1 [[ISNAN_CMP1]], 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) { double, double } @__muldc3(double noundef nofpclass(nan inf) [[DOTREAL]], double noundef nofpclass(nan inf) [[DOTIMAG]], double noundef nofpclass(nan inf) [[B_REAL]], double noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]]
+// FULL_FAST-NEXT: [[TMP3:%.*]] = extractvalue { double, double } [[CALL]], 0
+// FULL_FAST-NEXT: [[TMP4:%.*]] = extractvalue { double, double } [[CALL]], 1
+// 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 double [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP3]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL_FAST-NEXT: [[IMAG_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn double [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP4]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL_FAST-NEXT: [[DOTREALP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTIMAGP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// FULL_FAST-NEXT: store double [[REAL_MUL_PHI]], ptr [[DOTREALP2]], align 8
+// FULL_FAST-NEXT: store double [[IMAG_MUL_PHI]], ptr [[DOTIMAGP3]], align 8
+// FULL_FAST-NEXT: ret void
+//
+// IMPRVD_FAST-LABEL: define dso_local void @mulassignd(
+// IMPRVD_FAST-SAME: ptr noundef [[A:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// IMPRVD_FAST-NEXT: entry:
+// IMPRVD_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// IMPRVD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// IMPRVD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// IMPRVD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// IMPRVD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// IMPRVD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[MUL_AC]], [[MUL_BD]]
+// IMPRVD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[MUL_AD]], [[MUL_BC]]
+// IMPRVD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// IMPRVD_FAST-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// IMPRVD_FAST-NEXT: ret void
+//
+// PRMTD_FAST-LABEL: define dso_local void @mulassignd(
+// PRMTD_FAST-SAME: ptr noundef [[A:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]]) #[[ATTR2]] {
+// PRMTD_FAST-NEXT: entry:
+// PRMTD_FAST-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// PRMTD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_FAST-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// PRMTD_FAST-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 8
+// PRMTD_FAST-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 8
+// PRMTD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// PRMTD_FAST-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// PRMTD_FAST-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// PRMTD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// PRMTD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTREAL]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn double [[DOTIMAG]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn double [[MUL_AC]], [[MUL_BD]]
+// PRMTD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn double [[MUL_AD]], [[MUL_BC]]
+// PRMTD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// PRMTD_FAST-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// PRMTD_FAST-NEXT: ret void
+//
+// X86WINPRMTD_STRICT-LABEL: define dso_local void @mulassignd(
+// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD_STRICT-NEXT: entry:
+// X86WINPRMTD_STRICT-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[MUL_AC:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_BD:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_AD:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_BC:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_R:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[MUL_AC]], double [[MUL_BD]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_I:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[MUL_AD]], double [[MUL_BC]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// X86WINPRMTD_STRICT-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// X86WINPRMTD_STRICT-NEXT: ret void
+//
+// PRMTD_STRICT-LABEL: define dso_local void @mulassignd(
+// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) #[[ATTR3]] {
+// PRMTD_STRICT-NEXT: entry:
+// PRMTD_STRICT-NEXT: [[B:%.*]] = alloca { double, double }, align 8
+// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, 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 ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// PRMTD_STRICT-NEXT: [[MUL_AC:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_BD:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_AD:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_BC:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_R:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[MUL_AC]], double [[MUL_BD]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_I:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[MUL_AD]], double [[MUL_BC]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// PRMTD_STRICT-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// PRMTD_STRICT-NEXT: ret void
+//
+void mulassignd(_Complex double *a, _Complex 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:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// FULL-NEXT: entry:
+// FULL-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, 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: [[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: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef [[A_REAL]], x86_fp80 noundef [[A_IMAG]], x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]]) #[[ATTR2]]
+// FULL-NEXT: [[TMP0:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0
+// FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1
+// 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 [[TMP0]], ptr [[RETVAL_REALP]], align 16
+// FULL-NEXT: store x86_fp80 [[TMP1]], ptr [[RETVAL_IMAGP]], align 16
+// FULL-NEXT: [[TMP2:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
+// FULL-NEXT: ret { x86_fp80, x86_fp80 } [[TMP2]]
+//
+// BASIC-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
+// BASIC-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// BASIC-NEXT: entry:
+// BASIC-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
+// BASIC-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
+// BASIC-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16
+// BASIC-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1
+// BASIC-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16
+// 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: [[TMP0:%.*]] = fmul x86_fp80 [[A_REAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP1:%.*]] = fmul x86_fp80 [[A_IMAG]], [[B_IMAG]]
// BASIC-NEXT: [[TMP2:%.*]] = fadd x86_fp80 [[TMP0]], [[TMP1]]
// BASIC-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[B_REAL]], [[B_REAL]]
// BASIC-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[B_IMAG]], [[B_IMAG]]
@@ -2264,7 +4304,7 @@ _Complex double muld(_Complex double a, _Complex double b) {
// IMPRVD-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]]
//
// PRMTD-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
-// PRMTD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// PRMTD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
// PRMTD-NEXT: entry:
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
@@ -2584,173 +4624,740 @@ _Complex double muld(_Complex double a, _Complex double b) {
// 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: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0
-// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1
-// IMPRVD_FAST-NEXT: store x86_fp80 [[TMP20]], ptr [[RETVAL_REALP]], align 16
-// IMPRVD_FAST-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16
-// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
-// IMPRVD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]]
+// 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: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store x86_fp80 [[TMP20]], ptr [[RETVAL_REALP]], align 16
+// IMPRVD_FAST-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16
+// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
+// IMPRVD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]]
+//
+// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) { x86_fp80, x86_fp80 } @divld(
+// PRMTD_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// PRMTD_FAST-NEXT: entry:
+// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
+// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16
+// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16
+// 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: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]])
+// PRMTD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]])
+// 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 [[B_IMAG]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP3]]
+// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP2]]
+// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[A_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 [[A_REAL]], [[TMP2]]
+// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[A_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 [[B_REAL]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP12]]
+// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[TMP11]]
+// PRMTD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[A_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 [[A_IMAG]], [[TMP11]]
+// PRMTD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[A_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: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store x86_fp80 [[TMP20]], ptr [[RETVAL_REALP]], align 16
+// PRMTD_FAST-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16
+// PRMTD_FAST-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
+// PRMTD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]]
+//
+// X86WINPRMTD_STRICT-LABEL: define dso_local void @divld(
+// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD_STRICT-NEXT: entry:
+// X86WINPRMTD_STRICT-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: [[A_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_INDIRECT_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]]) #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]]) #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP0]], double [[TMP1]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// X86WINPRMTD_STRICT: abs_rhsr_greater_or_equal_abs_rhsi:
+// X86WINPRMTD_STRICT-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_IMAG]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP3:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP2]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP4:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_REAL]], double [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP5:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A_IMAG]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP6:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A_REAL]], double [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP7:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP6]], double [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP8:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A_REAL]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP9:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A_IMAG]], double [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP10:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP9]], double [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br label [[COMPLEX_DIV:%.*]]
+// X86WINPRMTD_STRICT: abs_rhsr_less_than_abs_rhsi:
+// X86WINPRMTD_STRICT-NEXT: [[TMP11:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_REAL]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP12:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP11]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP13:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_IMAG]], double [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP14:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A_REAL]], double [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP15:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[TMP14]], double [[A_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP16:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP15]], double [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP17:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A_IMAG]], double [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP18:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[TMP17]], double [[A_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP19:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP18]], double [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: br label [[COMPLEX_DIV]]
+// X86WINPRMTD_STRICT: complex_div:
+// X86WINPRMTD_STRICT-NEXT: [[TMP20:%.*]] = phi double [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: store double [[TMP20]], ptr [[AGG_RESULT_REALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: store double [[TMP21]], ptr [[AGG_RESULT_IMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
+// X86WINPRMTD_STRICT-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
+// X86WINPRMTD_STRICT-NEXT: ret void
+//
+// PRMTD_STRICT-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
+// PRMTD_STRICT-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR3]] {
+// PRMTD_STRICT-NEXT: entry:
+// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, 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: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16
+// PRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16
+// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]]) #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]]) #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f80(x86_fp80 [[TMP0]], x86_fp80 [[TMP1]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// PRMTD_STRICT: abs_rhsr_greater_or_equal_abs_rhsi:
+// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[B_IMAG]], x86_fp80 [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[TMP2]], x86_fp80 [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[B_REAL]], x86_fp80 [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP5:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[A_IMAG]], x86_fp80 [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP6:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[A_REAL]], x86_fp80 [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP7:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP6]], x86_fp80 [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP8:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[A_REAL]], x86_fp80 [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP9:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[A_IMAG]], x86_fp80 [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP10:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP9]], x86_fp80 [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br label [[COMPLEX_DIV:%.*]]
+// PRMTD_STRICT: abs_rhsr_less_than_abs_rhsi:
+// PRMTD_STRICT-NEXT: [[TMP11:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[B_REAL]], x86_fp80 [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP12:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[TMP11]], x86_fp80 [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP13:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[B_IMAG]], x86_fp80 [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP14:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[A_REAL]], x86_fp80 [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP15:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[TMP14]], x86_fp80 [[A_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP16:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP15]], x86_fp80 [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP17:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[A_IMAG]], x86_fp80 [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP18:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[TMP17]], x86_fp80 [[A_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP19:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP18]], x86_fp80 [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: br label [[COMPLEX_DIV]]
+// PRMTD_STRICT: complex_div:
+// PRMTD_STRICT-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// 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 [[TMP20]], ptr [[RETVAL_REALP]], align 16
+// PRMTD_STRICT-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16
+// PRMTD_STRICT-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
+// PRMTD_STRICT-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]]
+//
+_Complex long double divld(_Complex long double a, _Complex long double b) {
+ return a / b;
+}
+
+// FULL-LABEL: define dso_local void @divassignld(
+// FULL-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// FULL-NEXT: entry:
+// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], 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 [[TMP0]], i32 0, i32 1
+// FULL-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// FULL-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__divxc3(x86_fp80 noundef [[DOTREAL]], x86_fp80 noundef [[DOTIMAG]], x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]]) #[[ATTR2]]
+// FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0
+// FULL-NEXT: [[TMP2:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1
+// FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// FULL-NEXT: store x86_fp80 [[TMP1]], ptr [[DOTREALP1]], align 16
+// FULL-NEXT: store x86_fp80 [[TMP2]], ptr [[DOTIMAGP2]], align 16
+// FULL-NEXT: ret void
+//
+// BASIC-LABEL: define dso_local void @divassignld(
+// BASIC-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// BASIC-NEXT: entry:
+// BASIC-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// BASIC-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// BASIC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// BASIC-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// BASIC-NEXT: [[TMP1:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP2:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP3:%.*]] = fadd x86_fp80 [[TMP1]], [[TMP2]]
+// BASIC-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[B_REAL]], [[B_REAL]]
+// BASIC-NEXT: [[TMP5:%.*]] = fmul x86_fp80 [[B_IMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP6:%.*]] = fadd x86_fp80 [[TMP4]], [[TMP5]]
+// BASIC-NEXT: [[TMP7:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// BASIC-NEXT: [[TMP8:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// BASIC-NEXT: [[TMP9:%.*]] = fsub x86_fp80 [[TMP7]], [[TMP8]]
+// BASIC-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP3]], [[TMP6]]
+// BASIC-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[TMP9]], [[TMP6]]
+// BASIC-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// BASIC-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// BASIC-NEXT: store x86_fp80 [[TMP10]], ptr [[DOTREALP1]], align 16
+// BASIC-NEXT: store x86_fp80 [[TMP11]], ptr [[DOTIMAGP2]], align 16
+// BASIC-NEXT: ret void
+//
+// IMPRVD-LABEL: define dso_local void @divassignld(
+// IMPRVD-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// IMPRVD-NEXT: entry:
+// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], 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 [[TMP0]], i32 0, i32 1
+// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// IMPRVD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]])
+// IMPRVD-NEXT: [[TMP2:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]])
+// IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv x86_fp80 [[B_IMAG]], [[B_REAL]]
+// IMPRVD-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[TMP3]], [[B_IMAG]]
+// IMPRVD-NEXT: [[TMP5:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP4]]
+// IMPRVD-NEXT: [[TMP6:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[TMP3]]
+// IMPRVD-NEXT: [[TMP7:%.*]] = fadd x86_fp80 [[DOTREAL]], [[TMP6]]
+// IMPRVD-NEXT: [[TMP8:%.*]] = fdiv x86_fp80 [[TMP7]], [[TMP5]]
+// IMPRVD-NEXT: [[TMP9:%.*]] = fmul x86_fp80 [[DOTREAL]], [[TMP3]]
+// IMPRVD-NEXT: [[TMP10:%.*]] = fsub x86_fp80 [[DOTIMAG]], [[TMP9]]
+// IMPRVD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[TMP10]], [[TMP5]]
+// IMPRVD-NEXT: br label [[COMPLEX_DIV:%.*]]
+// IMPRVD: abs_rhsr_less_than_abs_rhsi:
+// IMPRVD-NEXT: [[TMP12:%.*]] = fdiv x86_fp80 [[B_REAL]], [[B_IMAG]]
+// IMPRVD-NEXT: [[TMP13:%.*]] = fmul x86_fp80 [[TMP12]], [[B_REAL]]
+// IMPRVD-NEXT: [[TMP14:%.*]] = fadd x86_fp80 [[B_IMAG]], [[TMP13]]
+// IMPRVD-NEXT: [[TMP15:%.*]] = fmul x86_fp80 [[DOTREAL]], [[TMP12]]
+// IMPRVD-NEXT: [[TMP16:%.*]] = fadd x86_fp80 [[TMP15]], [[DOTIMAG]]
+// IMPRVD-NEXT: [[TMP17:%.*]] = fdiv x86_fp80 [[TMP16]], [[TMP14]]
+// IMPRVD-NEXT: [[TMP18:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[TMP12]]
+// IMPRVD-NEXT: [[TMP19:%.*]] = fsub x86_fp80 [[TMP18]], [[DOTREAL]]
+// IMPRVD-NEXT: [[TMP20:%.*]] = fdiv x86_fp80 [[TMP19]], [[TMP14]]
+// IMPRVD-NEXT: br label [[COMPLEX_DIV]]
+// IMPRVD: complex_div:
+// IMPRVD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD-NEXT: [[TMP22:%.*]] = phi x86_fp80 [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD-NEXT: store x86_fp80 [[TMP21]], ptr [[DOTREALP1]], align 16
+// IMPRVD-NEXT: store x86_fp80 [[TMP22]], ptr [[DOTIMAGP2]], align 16
+// IMPRVD-NEXT: ret void
+//
+// PRMTD-LABEL: define dso_local void @divassignld(
+// PRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// PRMTD-NEXT: entry:
+// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], 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 [[TMP0]], i32 0, i32 1
+// PRMTD-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// PRMTD-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]])
+// PRMTD-NEXT: [[TMP2:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]])
+// PRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt x86_fp80 [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv x86_fp80 [[B_IMAG]], [[B_REAL]]
+// PRMTD-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[TMP3]], [[B_IMAG]]
+// PRMTD-NEXT: [[TMP5:%.*]] = fadd x86_fp80 [[B_REAL]], [[TMP4]]
+// PRMTD-NEXT: [[TMP6:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[TMP3]]
+// PRMTD-NEXT: [[TMP7:%.*]] = fadd x86_fp80 [[DOTREAL]], [[TMP6]]
+// PRMTD-NEXT: [[TMP8:%.*]] = fdiv x86_fp80 [[TMP7]], [[TMP5]]
+// PRMTD-NEXT: [[TMP9:%.*]] = fmul x86_fp80 [[DOTREAL]], [[TMP3]]
+// PRMTD-NEXT: [[TMP10:%.*]] = fsub x86_fp80 [[DOTIMAG]], [[TMP9]]
+// PRMTD-NEXT: [[TMP11:%.*]] = fdiv x86_fp80 [[TMP10]], [[TMP5]]
+// PRMTD-NEXT: br label [[COMPLEX_DIV:%.*]]
+// PRMTD: abs_rhsr_less_than_abs_rhsi:
+// PRMTD-NEXT: [[TMP12:%.*]] = fdiv x86_fp80 [[B_REAL]], [[B_IMAG]]
+// PRMTD-NEXT: [[TMP13:%.*]] = fmul x86_fp80 [[TMP12]], [[B_REAL]]
+// PRMTD-NEXT: [[TMP14:%.*]] = fadd x86_fp80 [[B_IMAG]], [[TMP13]]
+// PRMTD-NEXT: [[TMP15:%.*]] = fmul x86_fp80 [[DOTREAL]], [[TMP12]]
+// PRMTD-NEXT: [[TMP16:%.*]] = fadd x86_fp80 [[TMP15]], [[DOTIMAG]]
+// PRMTD-NEXT: [[TMP17:%.*]] = fdiv x86_fp80 [[TMP16]], [[TMP14]]
+// PRMTD-NEXT: [[TMP18:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[TMP12]]
+// PRMTD-NEXT: [[TMP19:%.*]] = fsub x86_fp80 [[TMP18]], [[DOTREAL]]
+// PRMTD-NEXT: [[TMP20:%.*]] = fdiv x86_fp80 [[TMP19]], [[TMP14]]
+// PRMTD-NEXT: br label [[COMPLEX_DIV]]
+// PRMTD: complex_div:
+// PRMTD-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD-NEXT: [[TMP22:%.*]] = phi x86_fp80 [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD-NEXT: store x86_fp80 [[TMP21]], ptr [[DOTREALP1]], align 16
+// PRMTD-NEXT: store x86_fp80 [[TMP22]], ptr [[DOTIMAGP2]], align 16
+// PRMTD-NEXT: ret void
+//
+// X86WINPRMTD-LABEL: define dso_local void @divassignld(
+// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD-NEXT: entry:
+// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
+// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// X86WINPRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// X86WINPRMTD-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]])
+// X86WINPRMTD-NEXT: [[TMP2:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]])
+// X86WINPRMTD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[TMP4:%.*]] = fmul double [[TMP3]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[TMP5:%.*]] = fadd double [[B_REAL]], [[TMP4]]
+// X86WINPRMTD-NEXT: [[TMP6:%.*]] = fmul double [[DOTIMAG]], [[TMP3]]
+// X86WINPRMTD-NEXT: [[TMP7:%.*]] = fadd double [[DOTREAL]], [[TMP6]]
+// X86WINPRMTD-NEXT: [[TMP8:%.*]] = fdiv double [[TMP7]], [[TMP5]]
+// X86WINPRMTD-NEXT: [[TMP9:%.*]] = fmul double [[DOTREAL]], [[TMP3]]
+// X86WINPRMTD-NEXT: [[TMP10:%.*]] = fsub double [[DOTIMAG]], [[TMP9]]
+// X86WINPRMTD-NEXT: [[TMP11:%.*]] = fdiv double [[TMP10]], [[TMP5]]
+// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV:%.*]]
+// X86WINPRMTD: abs_rhsr_less_than_abs_rhsi:
+// X86WINPRMTD-NEXT: [[TMP12:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[TMP13:%.*]] = fmul double [[TMP12]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[TMP14:%.*]] = fadd double [[B_IMAG]], [[TMP13]]
+// X86WINPRMTD-NEXT: [[TMP15:%.*]] = fmul double [[DOTREAL]], [[TMP12]]
+// X86WINPRMTD-NEXT: [[TMP16:%.*]] = fadd double [[TMP15]], [[DOTIMAG]]
+// X86WINPRMTD-NEXT: [[TMP17:%.*]] = fdiv double [[TMP16]], [[TMP14]]
+// X86WINPRMTD-NEXT: [[TMP18:%.*]] = fmul double [[DOTIMAG]], [[TMP12]]
+// X86WINPRMTD-NEXT: [[TMP19:%.*]] = fsub double [[TMP18]], [[DOTREAL]]
+// X86WINPRMTD-NEXT: [[TMP20:%.*]] = fdiv double [[TMP19]], [[TMP14]]
+// X86WINPRMTD-NEXT: br label [[COMPLEX_DIV]]
+// X86WINPRMTD: complex_div:
+// X86WINPRMTD-NEXT: [[TMP21:%.*]] = phi double [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD-NEXT: [[TMP22:%.*]] = phi double [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: store double [[TMP21]], ptr [[DOTREALP1]], align 8
+// X86WINPRMTD-NEXT: store double [[TMP22]], ptr [[DOTIMAGP2]], align 8
+// X86WINPRMTD-NEXT: ret void
+//
+// AVRFP32-LABEL: define dso_local void @divassignld(
+// AVRFP32-SAME: ptr noundef [[A:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP32-NEXT: entry:
+// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1
+// AVRFP32-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP32-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1
+// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1
+// AVRFP32-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 1
+// AVRFP32-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 1
+// AVRFP32-NEXT: [[TMP3:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_REAL]])
+// AVRFP32-NEXT: [[TMP4:%.*]] = call addrspace(1) float @llvm.fabs.f32(float [[B_IMAG]])
+// AVRFP32-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP3]], [[TMP4]]
+// AVRFP32-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// AVRFP32: abs_rhsr_greater_or_equal_abs_rhsi:
+// AVRFP32-NEXT: [[TMP5:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]]
+// AVRFP32-NEXT: [[TMP6:%.*]] = fmul float [[TMP5]], [[B_IMAG]]
+// AVRFP32-NEXT: [[TMP7:%.*]] = fadd float [[B_REAL]], [[TMP6]]
+// AVRFP32-NEXT: [[TMP8:%.*]] = fmul float [[DOTIMAG]], [[TMP5]]
+// AVRFP32-NEXT: [[TMP9:%.*]] = fadd float [[DOTREAL]], [[TMP8]]
+// AVRFP32-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP7]]
+// AVRFP32-NEXT: [[TMP11:%.*]] = fmul float [[DOTREAL]], [[TMP5]]
+// AVRFP32-NEXT: [[TMP12:%.*]] = fsub float [[DOTIMAG]], [[TMP11]]
+// AVRFP32-NEXT: [[TMP13:%.*]] = fdiv float [[TMP12]], [[TMP7]]
+// AVRFP32-NEXT: br label [[COMPLEX_DIV:%.*]]
+// AVRFP32: abs_rhsr_less_than_abs_rhsi:
+// AVRFP32-NEXT: [[TMP14:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]]
+// AVRFP32-NEXT: [[TMP15:%.*]] = fmul float [[TMP14]], [[B_REAL]]
+// AVRFP32-NEXT: [[TMP16:%.*]] = fadd float [[B_IMAG]], [[TMP15]]
+// AVRFP32-NEXT: [[TMP17:%.*]] = fmul float [[DOTREAL]], [[TMP14]]
+// AVRFP32-NEXT: [[TMP18:%.*]] = fadd float [[TMP17]], [[DOTIMAG]]
+// AVRFP32-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP16]]
+// AVRFP32-NEXT: [[TMP20:%.*]] = fmul float [[DOTIMAG]], [[TMP14]]
+// AVRFP32-NEXT: [[TMP21:%.*]] = fsub float [[TMP20]], [[DOTREAL]]
+// AVRFP32-NEXT: [[TMP22:%.*]] = fdiv float [[TMP21]], [[TMP16]]
+// AVRFP32-NEXT: br label [[COMPLEX_DIV]]
+// AVRFP32: complex_div:
+// AVRFP32-NEXT: [[TMP23:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP32-NEXT: [[TMP24:%.*]] = phi float [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP32-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[TMP23]], ptr [[DOTREALP1]], align 1
+// AVRFP32-NEXT: store float [[TMP24]], ptr [[DOTIMAGP2]], align 1
+// AVRFP32-NEXT: ret void
+//
+// AVRFP64-LABEL: define dso_local void @divassignld(
+// AVRFP64-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP64-NEXT: entry:
+// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 1
+// AVRFP64-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP64-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 1
+// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 1
+// AVRFP64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 1
+// AVRFP64-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 1
+// AVRFP64-NEXT: [[TMP3:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[B_REAL]])
+// AVRFP64-NEXT: [[TMP4:%.*]] = call addrspace(1) double @llvm.fabs.f64(double [[B_IMAG]])
+// AVRFP64-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP3]], [[TMP4]]
+// AVRFP64-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// AVRFP64: abs_rhsr_greater_or_equal_abs_rhsi:
+// AVRFP64-NEXT: [[TMP5:%.*]] = fdiv double [[B_IMAG]], [[B_REAL]]
+// AVRFP64-NEXT: [[TMP6:%.*]] = fmul double [[TMP5]], [[B_IMAG]]
+// AVRFP64-NEXT: [[TMP7:%.*]] = fadd double [[B_REAL]], [[TMP6]]
+// AVRFP64-NEXT: [[TMP8:%.*]] = fmul double [[DOTIMAG]], [[TMP5]]
+// AVRFP64-NEXT: [[TMP9:%.*]] = fadd double [[DOTREAL]], [[TMP8]]
+// AVRFP64-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP7]]
+// AVRFP64-NEXT: [[TMP11:%.*]] = fmul double [[DOTREAL]], [[TMP5]]
+// AVRFP64-NEXT: [[TMP12:%.*]] = fsub double [[DOTIMAG]], [[TMP11]]
+// AVRFP64-NEXT: [[TMP13:%.*]] = fdiv double [[TMP12]], [[TMP7]]
+// AVRFP64-NEXT: br label [[COMPLEX_DIV:%.*]]
+// AVRFP64: abs_rhsr_less_than_abs_rhsi:
+// AVRFP64-NEXT: [[TMP14:%.*]] = fdiv double [[B_REAL]], [[B_IMAG]]
+// AVRFP64-NEXT: [[TMP15:%.*]] = fmul double [[TMP14]], [[B_REAL]]
+// AVRFP64-NEXT: [[TMP16:%.*]] = fadd double [[B_IMAG]], [[TMP15]]
+// AVRFP64-NEXT: [[TMP17:%.*]] = fmul double [[DOTREAL]], [[TMP14]]
+// AVRFP64-NEXT: [[TMP18:%.*]] = fadd double [[TMP17]], [[DOTIMAG]]
+// AVRFP64-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP16]]
+// AVRFP64-NEXT: [[TMP20:%.*]] = fmul double [[DOTIMAG]], [[TMP14]]
+// AVRFP64-NEXT: [[TMP21:%.*]] = fsub double [[TMP20]], [[DOTREAL]]
+// AVRFP64-NEXT: [[TMP22:%.*]] = fdiv double [[TMP21]], [[TMP16]]
+// AVRFP64-NEXT: br label [[COMPLEX_DIV]]
+// AVRFP64: complex_div:
+// AVRFP64-NEXT: [[TMP23:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP64-NEXT: [[TMP24:%.*]] = phi double [ [[TMP13]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP22]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// AVRFP64-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: store double [[TMP23]], ptr [[DOTREALP1]], align 1
+// AVRFP64-NEXT: store double [[TMP24]], ptr [[DOTIMAGP2]], align 1
+// AVRFP64-NEXT: ret void
+//
+// BASIC_FAST-LABEL: define dso_local void @divassignld(
+// BASIC_FAST-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// BASIC_FAST-NEXT: entry:
+// BASIC_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// BASIC_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// BASIC_FAST-NEXT: [[TMP1:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP2:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP3:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP1]], [[TMP2]]
+// BASIC_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP4]], [[TMP5]]
+// BASIC_FAST-NEXT: [[TMP7:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[TMP8:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP7]], [[TMP8]]
+// BASIC_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP3]], [[TMP6]]
+// BASIC_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP6]]
+// BASIC_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// BASIC_FAST-NEXT: store x86_fp80 [[TMP10]], ptr [[DOTREALP1]], align 16
+// BASIC_FAST-NEXT: store x86_fp80 [[TMP11]], ptr [[DOTIMAGP2]], align 16
+// BASIC_FAST-NEXT: ret void
+//
+// FULL_FAST-LABEL: define dso_local void @divassignld(
+// FULL_FAST-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// FULL_FAST-NEXT: entry:
+// FULL_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// FULL_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// FULL_FAST-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// 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) [[DOTREAL]], x86_fp80 noundef nofpclass(nan inf) [[DOTIMAG]], x86_fp80 noundef nofpclass(nan inf) [[B_REAL]], x86_fp80 noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]]
+// FULL_FAST-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0
+// FULL_FAST-NEXT: [[TMP2:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1
+// FULL_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// FULL_FAST-NEXT: store x86_fp80 [[TMP1]], ptr [[DOTREALP1]], align 16
+// FULL_FAST-NEXT: store x86_fp80 [[TMP2]], ptr [[DOTIMAGP2]], align 16
+// FULL_FAST-NEXT: ret void
+//
+// IMPRVD_FAST-LABEL: define dso_local void @divassignld(
+// IMPRVD_FAST-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// IMPRVD_FAST-NEXT: entry:
+// IMPRVD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// IMPRVD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// IMPRVD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]])
+// IMPRVD_FAST-NEXT: [[TMP2:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]])
+// IMPRVD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP1]], [[TMP2]]
+// 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: [[TMP3:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP3]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP4]]
+// IMPRVD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[TMP3]]
+// IMPRVD_FAST-NEXT: [[TMP7:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[TMP6]]
+// IMPRVD_FAST-NEXT: [[TMP8:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP7]], [[TMP5]]
+// IMPRVD_FAST-NEXT: [[TMP9:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[TMP3]]
+// IMPRVD_FAST-NEXT: [[TMP10:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[TMP9]]
+// IMPRVD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP10]], [[TMP5]]
+// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV:%.*]]
+// IMPRVD_FAST: abs_rhsr_less_than_abs_rhsi:
+// IMPRVD_FAST-NEXT: [[TMP12:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[TMP13:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP12]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[TMP14:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP13]]
+// IMPRVD_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[TMP12]]
+// IMPRVD_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[DOTIMAG]]
+// IMPRVD_FAST-NEXT: [[TMP17:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP16]], [[TMP14]]
+// IMPRVD_FAST-NEXT: [[TMP18:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[TMP12]]
+// IMPRVD_FAST-NEXT: [[TMP19:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[DOTREAL]]
+// IMPRVD_FAST-NEXT: [[TMP20:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP19]], [[TMP14]]
+// IMPRVD_FAST-NEXT: br label [[COMPLEX_DIV]]
+// IMPRVD_FAST: complex_div:
+// IMPRVD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD_FAST-NEXT: [[TMP22:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// IMPRVD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store x86_fp80 [[TMP21]], ptr [[DOTREALP1]], align 16
+// IMPRVD_FAST-NEXT: store x86_fp80 [[TMP22]], ptr [[DOTIMAGP2]], align 16
+// IMPRVD_FAST-NEXT: ret void
//
-// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) { x86_fp80, x86_fp80 } @divld(
-// PRMTD_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// PRMTD_FAST-LABEL: define dso_local void @divassignld(
+// PRMTD_FAST-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
// PRMTD_FAST-NEXT: entry:
-// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
-// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
-// PRMTD_FAST-NEXT: [[A_REAL:%.*]] = load x86_fp80, ptr [[A_REALP]], align 16
-// PRMTD_FAST-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1
-// PRMTD_FAST-NEXT: [[A_IMAG:%.*]] = load x86_fp80, ptr [[A_IMAGP]], align 16
+// PRMTD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// 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: [[TMP0:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]])
-// PRMTD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]])
-// PRMTD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP0]], [[TMP1]]
+// PRMTD_FAST-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// PRMTD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// PRMTD_FAST-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]])
+// PRMTD_FAST-NEXT: [[TMP2:%.*]] = call reassoc nnan ninf nsz arcp afn x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]])
+// PRMTD_FAST-NEXT: [[ABS_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn ugt x86_fp80 [[TMP1]], [[TMP2]]
// 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 [[B_IMAG]], [[B_REAL]]
-// PRMTD_FAST-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP2]], [[B_IMAG]]
-// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP3]]
-// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP2]]
-// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[A_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 [[A_REAL]], [[TMP2]]
-// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[A_IMAG]], [[TMP8]]
-// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP9]], [[TMP4]]
+// PRMTD_FAST-NEXT: [[TMP3:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[TMP4:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP3]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[TMP5:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[TMP4]]
+// PRMTD_FAST-NEXT: [[TMP6:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[TMP3]]
+// PRMTD_FAST-NEXT: [[TMP7:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[TMP6]]
+// PRMTD_FAST-NEXT: [[TMP8:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP7]], [[TMP5]]
+// PRMTD_FAST-NEXT: [[TMP9:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[TMP3]]
+// PRMTD_FAST-NEXT: [[TMP10:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[TMP9]]
+// PRMTD_FAST-NEXT: [[TMP11:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP10]], [[TMP5]]
// 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 [[B_REAL]], [[B_IMAG]]
-// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP11]], [[B_REAL]]
-// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP12]]
-// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[A_REAL]], [[TMP11]]
-// PRMTD_FAST-NEXT: [[TMP15:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP14]], [[A_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 [[A_IMAG]], [[TMP11]]
-// PRMTD_FAST-NEXT: [[TMP18:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP17]], [[A_REAL]]
-// PRMTD_FAST-NEXT: [[TMP19:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[TMP13]]
+// PRMTD_FAST-NEXT: [[TMP12:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[B_REAL]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[TMP13:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP12]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[TMP14:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[B_IMAG]], [[TMP13]]
+// PRMTD_FAST-NEXT: [[TMP15:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[TMP12]]
+// PRMTD_FAST-NEXT: [[TMP16:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP15]], [[DOTIMAG]]
+// PRMTD_FAST-NEXT: [[TMP17:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP16]], [[TMP14]]
+// PRMTD_FAST-NEXT: [[TMP18:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[TMP12]]
+// PRMTD_FAST-NEXT: [[TMP19:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP18]], [[DOTREAL]]
+// PRMTD_FAST-NEXT: [[TMP20:%.*]] = fdiv reassoc nnan ninf nsz arcp afn x86_fp80 [[TMP19]], [[TMP14]]
// 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: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 0
-// PRMTD_FAST-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[RETVAL]], i32 0, i32 1
-// PRMTD_FAST-NEXT: store x86_fp80 [[TMP20]], ptr [[RETVAL_REALP]], align 16
-// PRMTD_FAST-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16
-// PRMTD_FAST-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
-// PRMTD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]]
+// PRMTD_FAST-NEXT: [[TMP21:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_FAST-NEXT: [[TMP22:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store x86_fp80 [[TMP21]], ptr [[DOTREALP1]], align 16
+// PRMTD_FAST-NEXT: store x86_fp80 [[TMP22]], ptr [[DOTIMAGP2]], align 16
+// PRMTD_FAST-NEXT: ret void
//
-// X86WINPRMTD_STRICT-LABEL: define dso_local void @divld(
-// X86WINPRMTD_STRICT-SAME: ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD_STRICT-LABEL: define dso_local void @divassignld(
+// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
// X86WINPRMTD_STRICT-NEXT: entry:
-// X86WINPRMTD_STRICT-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8
// X86WINPRMTD_STRICT-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
-// X86WINPRMTD_STRICT-NEXT: [[A_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
-// X86WINPRMTD_STRICT-NEXT: store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
// X86WINPRMTD_STRICT-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
-// X86WINPRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_INDIRECT_ADDR]], align 8
-// X86WINPRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0
-// X86WINPRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
-// X86WINPRMTD_STRICT-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
-// X86WINPRMTD_STRICT-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
// X86WINPRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
// X86WINPRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
-// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]]) #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]]) #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP0]], double [[TMP1]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_REAL]]) #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP2:%.*]] = call double @llvm.fabs.f64(double [[B_IMAG]]) #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[TMP1]], double [[TMP2]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR3]]
// X86WINPRMTD_STRICT-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
// X86WINPRMTD_STRICT: abs_rhsr_greater_or_equal_abs_rhsi:
-// X86WINPRMTD_STRICT-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_IMAG]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP3:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP2]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP4:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_REAL]], double [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP5:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A_IMAG]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP6:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A_REAL]], double [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP7:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP6]], double [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP8:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A_REAL]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP9:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A_IMAG]], double [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP10:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP9]], double [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP3:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_IMAG]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP4:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP3]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP5:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_REAL]], double [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP6:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP7:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[DOTREAL]], double [[TMP6]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP8:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP7]], double [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP9:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP10:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[DOTIMAG]], double [[TMP9]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP11:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP10]], double [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// X86WINPRMTD_STRICT-NEXT: br label [[COMPLEX_DIV:%.*]]
// X86WINPRMTD_STRICT: abs_rhsr_less_than_abs_rhsi:
-// X86WINPRMTD_STRICT-NEXT: [[TMP11:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_REAL]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP12:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP11]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP13:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_IMAG]], double [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP14:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A_REAL]], double [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP15:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[TMP14]], double [[A_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP16:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP15]], double [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP17:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A_IMAG]], double [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP18:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[TMP17]], double [[A_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// X86WINPRMTD_STRICT-NEXT: [[TMP19:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP18]], double [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP12:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[B_REAL]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP13:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[TMP12]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP14:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[B_IMAG]], double [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP15:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP16:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[TMP15]], double [[DOTIMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP17:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP16]], double [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP18:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP19:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[TMP18]], double [[DOTREAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[TMP20:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[TMP19]], double [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
// X86WINPRMTD_STRICT-NEXT: br label [[COMPLEX_DIV]]
// X86WINPRMTD_STRICT: complex_div:
-// X86WINPRMTD_STRICT-NEXT: [[TMP20:%.*]] = phi double [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
-// X86WINPRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi double [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
-// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// X86WINPRMTD_STRICT-NEXT: store double [[TMP20]], ptr [[AGG_RESULT_REALP]], align 8
-// X86WINPRMTD_STRICT-NEXT: store double [[TMP21]], ptr [[AGG_RESULT_IMAGP]], align 8
-// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_REAL:%.*]] = load double, ptr [[AGG_RESULT_REALP1]], align 8
-// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_IMAG:%.*]] = load double, ptr [[AGG_RESULT_IMAGP2]], align 8
-// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
-// X86WINPRMTD_STRICT-NEXT: [[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
-// X86WINPRMTD_STRICT-NEXT: store double [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 8
-// X86WINPRMTD_STRICT-NEXT: store double [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi double [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD_STRICT-NEXT: [[TMP22:%.*]] = phi double [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: store double [[TMP21]], ptr [[DOTREALP1]], align 8
+// X86WINPRMTD_STRICT-NEXT: store double [[TMP22]], ptr [[DOTIMAGP2]], align 8
// X86WINPRMTD_STRICT-NEXT: ret void
//
-// PRMTD_STRICT-LABEL: define dso_local { x86_fp80, x86_fp80 } @divld(
-// PRMTD_STRICT-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// PRMTD_STRICT-LABEL: define dso_local void @divassignld(
+// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR3]] {
// PRMTD_STRICT-NEXT: entry:
-// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, 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: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
// PRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0
// PRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16
// PRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1
// PRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16
-// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]]) #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]]) #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f80(x86_fp80 [[TMP0]], x86_fp80 [[TMP1]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], 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 [[TMP0]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_REAL]]) #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[B_IMAG]]) #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[ABS_CMP:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f80(x86_fp80 [[TMP1]], x86_fp80 [[TMP2]], metadata !"ugt", metadata !"fpexcept.strict") #[[ATTR4]]
// PRMTD_STRICT-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
// PRMTD_STRICT: abs_rhsr_greater_or_equal_abs_rhsi:
-// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[B_IMAG]], x86_fp80 [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[TMP2]], x86_fp80 [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[B_REAL]], x86_fp80 [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP5:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[A_IMAG]], x86_fp80 [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP6:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[A_REAL]], x86_fp80 [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP7:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP6]], x86_fp80 [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP8:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[A_REAL]], x86_fp80 [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP9:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[A_IMAG]], x86_fp80 [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP10:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP9]], x86_fp80 [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[B_IMAG]], x86_fp80 [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[TMP3]], x86_fp80 [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP5:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[B_REAL]], x86_fp80 [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP6:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[DOTIMAG]], x86_fp80 [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP7:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[DOTREAL]], x86_fp80 [[TMP6]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP8:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP7]], x86_fp80 [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP9:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[DOTREAL]], x86_fp80 [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP10:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[DOTIMAG]], x86_fp80 [[TMP9]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP11:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP10]], x86_fp80 [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
// PRMTD_STRICT-NEXT: br label [[COMPLEX_DIV:%.*]]
// PRMTD_STRICT: abs_rhsr_less_than_abs_rhsi:
-// PRMTD_STRICT-NEXT: [[TMP11:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[B_REAL]], x86_fp80 [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP12:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[TMP11]], x86_fp80 [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP13:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[B_IMAG]], x86_fp80 [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP14:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[A_REAL]], x86_fp80 [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP15:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[TMP14]], x86_fp80 [[A_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP16:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP15]], x86_fp80 [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP17:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[A_IMAG]], x86_fp80 [[TMP11]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP18:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[TMP17]], x86_fp80 [[A_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
-// PRMTD_STRICT-NEXT: [[TMP19:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP18]], x86_fp80 [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP12:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[B_REAL]], x86_fp80 [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP13:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[TMP12]], x86_fp80 [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP14:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[B_IMAG]], x86_fp80 [[TMP13]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP15:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[DOTREAL]], x86_fp80 [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP16:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[TMP15]], x86_fp80 [[DOTIMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP17:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP16]], x86_fp80 [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP18:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[DOTIMAG]], x86_fp80 [[TMP12]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP19:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[TMP18]], x86_fp80 [[DOTREAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[TMP20:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP19]], x86_fp80 [[TMP14]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
// PRMTD_STRICT-NEXT: br label [[COMPLEX_DIV]]
// PRMTD_STRICT: complex_div:
-// PRMTD_STRICT-NEXT: [[TMP20:%.*]] = phi x86_fp80 [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
-// PRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
-// 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 [[TMP20]], ptr [[RETVAL_REALP]], align 16
-// PRMTD_STRICT-NEXT: store x86_fp80 [[TMP21]], ptr [[RETVAL_IMAGP]], align 16
-// PRMTD_STRICT-NEXT: [[TMP22:%.*]] = load { x86_fp80, x86_fp80 }, ptr [[RETVAL]], align 16
-// PRMTD_STRICT-NEXT: ret { x86_fp80, x86_fp80 } [[TMP22]]
+// PRMTD_STRICT-NEXT: [[TMP21:%.*]] = phi x86_fp80 [ [[TMP8]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP17]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_STRICT-NEXT: [[TMP22:%.*]] = phi x86_fp80 [ [[TMP11]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP20]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: store x86_fp80 [[TMP21]], ptr [[DOTREALP1]], align 16
+// PRMTD_STRICT-NEXT: store x86_fp80 [[TMP22]], ptr [[DOTIMAGP2]], align 16
+// PRMTD_STRICT-NEXT: ret void
//
-_Complex long double divld(_Complex long double a, _Complex long double b) {
- return a / b;
+void divassignld(_Complex long double *a, _Complex long double b) {
+ *a /= b;
}
// FULL-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld(
@@ -2842,7 +5449,7 @@ _Complex long double divld(_Complex long double a, _Complex long double b) {
// IMPRVD-NEXT: ret { x86_fp80, x86_fp80 } [[TMP0]]
//
// PRMTD-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld(
-// PRMTD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// PRMTD-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
// PRMTD-NEXT: entry:
// PRMTD-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
// PRMTD-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
@@ -3068,7 +5675,7 @@ _Complex long double divld(_Complex long double a, _Complex long double b) {
// IMPRVD_FAST-NEXT: ret { x86_fp80, x86_fp80 } [[TMP0]]
//
// PRMTD_FAST-LABEL: define dso_local nofpclass(nan inf) { x86_fp80, x86_fp80 } @mulld(
-// PRMTD_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// PRMTD_FAST-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
// PRMTD_FAST-NEXT: entry:
// PRMTD_FAST-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
// PRMTD_FAST-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
@@ -3130,7 +5737,7 @@ _Complex long double divld(_Complex long double a, _Complex long double b) {
// X86WINPRMTD_STRICT-NEXT: ret void
//
// PRMTD_STRICT-LABEL: define dso_local { x86_fp80, x86_fp80 } @mulld(
-// PRMTD_STRICT-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// PRMTD_STRICT-SAME: ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR3]] {
// PRMTD_STRICT-NEXT: entry:
// PRMTD_STRICT-NEXT: [[RETVAL:%.*]] = alloca { x86_fp80, x86_fp80 }, align 16
// PRMTD_STRICT-NEXT: [[A_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0
@@ -3158,6 +5765,388 @@ _Complex long double mulld(_Complex long double a, _Complex long double b) {
return a * b;
}
+// FULL-LABEL: define dso_local void @mulassignld(
+// FULL-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// FULL-NEXT: entry:
+// FULL-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], 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 [[TMP0]], i32 0, i32 1
+// FULL-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// FULL-NEXT: [[MUL_AC:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_REAL]]
+// FULL-NEXT: [[MUL_BD:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// FULL-NEXT: [[MUL_AD:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// FULL-NEXT: [[MUL_BC:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// FULL-NEXT: [[MUL_R:%.*]] = fsub x86_fp80 [[MUL_AC]], [[MUL_BD]]
+// FULL-NEXT: [[MUL_I:%.*]] = fadd x86_fp80 [[MUL_AD]], [[MUL_BC]]
+// FULL-NEXT: [[ISNAN_CMP:%.*]] = fcmp uno x86_fp80 [[MUL_R]], [[MUL_R]]
+// FULL-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
+// FULL: complex_mul_imag_nan:
+// FULL-NEXT: [[ISNAN_CMP1:%.*]] = fcmp uno x86_fp80 [[MUL_I]], [[MUL_I]]
+// FULL-NEXT: br i1 [[ISNAN_CMP1]], label [[COMPLEX_MUL_LIBCALL:%.*]], label [[COMPLEX_MUL_CONT]], !prof [[PROF2]]
+// FULL: complex_mul_libcall:
+// FULL-NEXT: [[CALL:%.*]] = call { x86_fp80, x86_fp80 } @__mulxc3(x86_fp80 noundef [[DOTREAL]], x86_fp80 noundef [[DOTIMAG]], x86_fp80 noundef [[B_REAL]], x86_fp80 noundef [[B_IMAG]]) #[[ATTR2]]
+// FULL-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0
+// FULL-NEXT: [[TMP2:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1
+// FULL-NEXT: br label [[COMPLEX_MUL_CONT]]
+// FULL: complex_mul_cont:
+// FULL-NEXT: [[REAL_MUL_PHI:%.*]] = phi x86_fp80 [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP1]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL-NEXT: [[IMAG_MUL_PHI:%.*]] = phi x86_fp80 [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP2]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL-NEXT: [[DOTREALP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// FULL-NEXT: [[DOTIMAGP3:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// FULL-NEXT: store x86_fp80 [[REAL_MUL_PHI]], ptr [[DOTREALP2]], align 16
+// FULL-NEXT: store x86_fp80 [[IMAG_MUL_PHI]], ptr [[DOTIMAGP3]], align 16
+// FULL-NEXT: ret void
+//
+// BASIC-LABEL: define dso_local void @mulassignld(
+// BASIC-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// BASIC-NEXT: entry:
+// BASIC-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// BASIC-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// BASIC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// BASIC-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// BASIC-NEXT: [[MUL_AC:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_REAL]]
+// BASIC-NEXT: [[MUL_BD:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// BASIC-NEXT: [[MUL_AD:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// BASIC-NEXT: [[MUL_BC:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// BASIC-NEXT: [[MUL_R:%.*]] = fsub x86_fp80 [[MUL_AC]], [[MUL_BD]]
+// BASIC-NEXT: [[MUL_I:%.*]] = fadd x86_fp80 [[MUL_AD]], [[MUL_BC]]
+// BASIC-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// BASIC-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// BASIC-NEXT: store x86_fp80 [[MUL_R]], ptr [[DOTREALP1]], align 16
+// BASIC-NEXT: store x86_fp80 [[MUL_I]], ptr [[DOTIMAGP2]], align 16
+// BASIC-NEXT: ret void
+//
+// IMPRVD-LABEL: define dso_local void @mulassignld(
+// IMPRVD-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// IMPRVD-NEXT: entry:
+// IMPRVD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], 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 [[TMP0]], i32 0, i32 1
+// IMPRVD-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// IMPRVD-NEXT: [[MUL_AC:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_REAL]]
+// IMPRVD-NEXT: [[MUL_BD:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// IMPRVD-NEXT: [[MUL_AD:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// IMPRVD-NEXT: [[MUL_BC:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// IMPRVD-NEXT: [[MUL_R:%.*]] = fsub x86_fp80 [[MUL_AC]], [[MUL_BD]]
+// IMPRVD-NEXT: [[MUL_I:%.*]] = fadd x86_fp80 [[MUL_AD]], [[MUL_BC]]
+// IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD-NEXT: store x86_fp80 [[MUL_R]], ptr [[DOTREALP1]], align 16
+// IMPRVD-NEXT: store x86_fp80 [[MUL_I]], ptr [[DOTIMAGP2]], align 16
+// IMPRVD-NEXT: ret void
+//
+// PRMTD-LABEL: define dso_local void @mulassignld(
+// PRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// PRMTD-NEXT: entry:
+// PRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], 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 [[TMP0]], i32 0, i32 1
+// PRMTD-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// PRMTD-NEXT: [[MUL_AC:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_REAL]]
+// PRMTD-NEXT: [[MUL_BD:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// PRMTD-NEXT: [[MUL_AD:%.*]] = fmul x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// PRMTD-NEXT: [[MUL_BC:%.*]] = fmul x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// PRMTD-NEXT: [[MUL_R:%.*]] = fsub x86_fp80 [[MUL_AC]], [[MUL_BD]]
+// PRMTD-NEXT: [[MUL_I:%.*]] = fadd x86_fp80 [[MUL_AD]], [[MUL_BC]]
+// PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD-NEXT: store x86_fp80 [[MUL_R]], ptr [[DOTREALP1]], align 16
+// PRMTD-NEXT: store x86_fp80 [[MUL_I]], ptr [[DOTIMAGP2]], align 16
+// PRMTD-NEXT: ret void
+//
+// X86WINPRMTD-LABEL: define dso_local void @mulassignld(
+// X86WINPRMTD-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD-NEXT: entry:
+// X86WINPRMTD-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
+// X86WINPRMTD-NEXT: store ptr [[A]], ptr [[A_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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// X86WINPRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// X86WINPRMTD-NEXT: [[MUL_AC:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[MUL_BD:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[MUL_AD:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// X86WINPRMTD-NEXT: [[MUL_BC:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// X86WINPRMTD-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// X86WINPRMTD-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// X86WINPRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// X86WINPRMTD-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// X86WINPRMTD-NEXT: ret void
+//
+// AVRFP32-LABEL: define dso_local void @mulassignld(
+// AVRFP32-SAME: ptr noundef [[A:%.*]], float noundef [[B_COERCE0:%.*]], float noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP32-NEXT: entry:
+// AVRFP32-NEXT: [[B:%.*]] = alloca { float, float }, align 1
+// AVRFP32-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP32-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: store float [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP32-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP32-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 0
+// AVRFP32-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 1
+// AVRFP32-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[B]], i32 0, i32 1
+// AVRFP32-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 1
+// AVRFP32-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP32-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 1
+// AVRFP32-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 1
+// AVRFP32-NEXT: [[MUL_AC:%.*]] = fmul float [[DOTREAL]], [[B_REAL]]
+// AVRFP32-NEXT: [[MUL_BD:%.*]] = fmul float [[DOTIMAG]], [[B_IMAG]]
+// AVRFP32-NEXT: [[MUL_AD:%.*]] = fmul float [[DOTREAL]], [[B_IMAG]]
+// AVRFP32-NEXT: [[MUL_BC:%.*]] = fmul float [[DOTIMAG]], [[B_REAL]]
+// AVRFP32-NEXT: [[MUL_R:%.*]] = fsub float [[MUL_AC]], [[MUL_BD]]
+// AVRFP32-NEXT: [[MUL_I:%.*]] = fadd float [[MUL_AD]], [[MUL_BC]]
+// AVRFP32-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP32-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP32-NEXT: store float [[MUL_R]], ptr [[DOTREALP1]], align 1
+// AVRFP32-NEXT: store float [[MUL_I]], ptr [[DOTIMAGP2]], align 1
+// AVRFP32-NEXT: ret void
+//
+// AVRFP64-LABEL: define dso_local void @mulassignld(
+// AVRFP64-SAME: ptr noundef [[A:%.*]], double noundef [[B_COERCE0:%.*]], double noundef [[B_COERCE1:%.*]]) addrspace(1) #[[ATTR0]] {
+// AVRFP64-NEXT: entry:
+// AVRFP64-NEXT: [[B:%.*]] = alloca { double, double }, align 1
+// AVRFP64-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 1
+// AVRFP64-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: store double [[B_COERCE0]], ptr [[TMP0]], align 1
+// AVRFP64-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: store double [[B_COERCE1]], ptr [[TMP1]], align 1
+// AVRFP64-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// AVRFP64-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 1
+// AVRFP64-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// AVRFP64-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 1
+// AVRFP64-NEXT: [[TMP2:%.*]] = load ptr, ptr [[A_ADDR]], align 1
+// AVRFP64-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 1
+// AVRFP64-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 1
+// AVRFP64-NEXT: [[MUL_AC:%.*]] = fmul double [[DOTREAL]], [[B_REAL]]
+// AVRFP64-NEXT: [[MUL_BD:%.*]] = fmul double [[DOTIMAG]], [[B_IMAG]]
+// AVRFP64-NEXT: [[MUL_AD:%.*]] = fmul double [[DOTREAL]], [[B_IMAG]]
+// AVRFP64-NEXT: [[MUL_BC:%.*]] = fmul double [[DOTIMAG]], [[B_REAL]]
+// AVRFP64-NEXT: [[MUL_R:%.*]] = fsub double [[MUL_AC]], [[MUL_BD]]
+// AVRFP64-NEXT: [[MUL_I:%.*]] = fadd double [[MUL_AD]], [[MUL_BC]]
+// AVRFP64-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 0
+// AVRFP64-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP2]], i32 0, i32 1
+// AVRFP64-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 1
+// AVRFP64-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 1
+// AVRFP64-NEXT: ret void
+//
+// BASIC_FAST-LABEL: define dso_local void @mulassignld(
+// BASIC_FAST-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// BASIC_FAST-NEXT: entry:
+// BASIC_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// BASIC_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// BASIC_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// BASIC_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// BASIC_FAST-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// BASIC_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// BASIC_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// BASIC_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AC]], [[MUL_BD]]
+// BASIC_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AD]], [[MUL_BC]]
+// BASIC_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// BASIC_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// BASIC_FAST-NEXT: store x86_fp80 [[MUL_R]], ptr [[DOTREALP1]], align 16
+// BASIC_FAST-NEXT: store x86_fp80 [[MUL_I]], ptr [[DOTIMAGP2]], align 16
+// BASIC_FAST-NEXT: ret void
+//
+// FULL_FAST-LABEL: define dso_local void @mulassignld(
+// FULL_FAST-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR1]] {
+// FULL_FAST-NEXT: entry:
+// FULL_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// FULL_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// FULL_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// FULL_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// FULL_FAST-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// FULL_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_REAL]]
+// FULL_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// FULL_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// FULL_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// FULL_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AC]], [[MUL_BD]]
+// FULL_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AD]], [[MUL_BC]]
+// FULL_FAST-NEXT: [[ISNAN_CMP:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno x86_fp80 [[MUL_R]], [[MUL_R]]
+// FULL_FAST-NEXT: br i1 [[ISNAN_CMP]], label [[COMPLEX_MUL_IMAG_NAN:%.*]], label [[COMPLEX_MUL_CONT:%.*]], !prof [[PROF2]]
+// FULL_FAST: complex_mul_imag_nan:
+// FULL_FAST-NEXT: [[ISNAN_CMP1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn uno x86_fp80 [[MUL_I]], [[MUL_I]]
+// FULL_FAST-NEXT: br i1 [[ISNAN_CMP1]], 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) { x86_fp80, x86_fp80 } @__mulxc3(x86_fp80 noundef nofpclass(nan inf) [[DOTREAL]], x86_fp80 noundef nofpclass(nan inf) [[DOTIMAG]], x86_fp80 noundef nofpclass(nan inf) [[B_REAL]], x86_fp80 noundef nofpclass(nan inf) [[B_IMAG]]) #[[ATTR2]]
+// FULL_FAST-NEXT: [[TMP1:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 0
+// FULL_FAST-NEXT: [[TMP2:%.*]] = extractvalue { x86_fp80, x86_fp80 } [[CALL]], 1
+// 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 x86_fp80 [ [[MUL_R]], [[ENTRY:%.*]] ], [ [[MUL_R]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP1]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL_FAST-NEXT: [[IMAG_MUL_PHI:%.*]] = phi reassoc nnan ninf nsz arcp afn x86_fp80 [ [[MUL_I]], [[ENTRY]] ], [ [[MUL_I]], [[COMPLEX_MUL_IMAG_NAN]] ], [ [[TMP2]], [[COMPLEX_MUL_LIBCALL]] ]
+// FULL_FAST-NEXT: [[DOTREALP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// FULL_FAST-NEXT: [[DOTIMAGP3:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// FULL_FAST-NEXT: store x86_fp80 [[REAL_MUL_PHI]], ptr [[DOTREALP2]], align 16
+// FULL_FAST-NEXT: store x86_fp80 [[IMAG_MUL_PHI]], ptr [[DOTIMAGP3]], align 16
+// FULL_FAST-NEXT: ret void
+//
+// IMPRVD_FAST-LABEL: define dso_local void @mulassignld(
+// IMPRVD_FAST-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// IMPRVD_FAST-NEXT: entry:
+// IMPRVD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// IMPRVD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// IMPRVD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// IMPRVD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// IMPRVD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// IMPRVD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// IMPRVD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AC]], [[MUL_BD]]
+// IMPRVD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AD]], [[MUL_BC]]
+// IMPRVD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// IMPRVD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// IMPRVD_FAST-NEXT: store x86_fp80 [[MUL_R]], ptr [[DOTREALP1]], align 16
+// IMPRVD_FAST-NEXT: store x86_fp80 [[MUL_I]], ptr [[DOTIMAGP2]], align 16
+// IMPRVD_FAST-NEXT: ret void
+//
+// PRMTD_FAST-LABEL: define dso_local void @mulassignld(
+// PRMTD_FAST-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR2]] {
+// PRMTD_FAST-NEXT: entry:
+// PRMTD_FAST-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_FAST-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// 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: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_FAST-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTREAL:%.*]] = load x86_fp80, ptr [[DOTREALP]], align 16
+// PRMTD_FAST-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_FAST-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// PRMTD_FAST-NEXT: [[MUL_AC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[MUL_BD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[MUL_AD:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTREAL]], [[B_IMAG]]
+// PRMTD_FAST-NEXT: [[MUL_BC:%.*]] = fmul reassoc nnan ninf nsz arcp afn x86_fp80 [[DOTIMAG]], [[B_REAL]]
+// PRMTD_FAST-NEXT: [[MUL_R:%.*]] = fsub reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AC]], [[MUL_BD]]
+// PRMTD_FAST-NEXT: [[MUL_I:%.*]] = fadd reassoc nnan ninf nsz arcp afn x86_fp80 [[MUL_AD]], [[MUL_BC]]
+// PRMTD_FAST-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_FAST-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_FAST-NEXT: store x86_fp80 [[MUL_R]], ptr [[DOTREALP1]], align 16
+// PRMTD_FAST-NEXT: store x86_fp80 [[MUL_I]], ptr [[DOTIMAGP2]], align 16
+// PRMTD_FAST-NEXT: ret void
+//
+// X86WINPRMTD_STRICT-LABEL: define dso_local void @mulassignld(
+// X86WINPRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]]) #[[ATTR0]] {
+// X86WINPRMTD_STRICT-NEXT: entry:
+// X86WINPRMTD_STRICT-NEXT: [[B_INDIRECT_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[B]], ptr [[B_INDIRECT_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load double, ptr [[B_REALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[B]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load double, ptr [[B_IMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8
+// X86WINPRMTD_STRICT-NEXT: [[MUL_AC:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_BD:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_AD:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTREAL]], double [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_BC:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DOTIMAG]], double [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_R:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[MUL_AC]], double [[MUL_BD]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[MUL_I:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[MUL_AD]], double [[MUL_BC]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// X86WINPRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 0
+// X86WINPRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[TMP0]], i32 0, i32 1
+// X86WINPRMTD_STRICT-NEXT: store double [[MUL_R]], ptr [[DOTREALP1]], align 8
+// X86WINPRMTD_STRICT-NEXT: store double [[MUL_I]], ptr [[DOTIMAGP2]], align 8
+// X86WINPRMTD_STRICT-NEXT: ret void
+//
+// PRMTD_STRICT-LABEL: define dso_local void @mulassignld(
+// PRMTD_STRICT-SAME: ptr noundef [[A:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]]) #[[ATTR3]] {
+// PRMTD_STRICT-NEXT: entry:
+// PRMTD_STRICT-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8
+// PRMTD_STRICT-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8
+// PRMTD_STRICT-NEXT: [[B_REALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[B_REAL:%.*]] = load x86_fp80, ptr [[B_REALP]], align 16
+// PRMTD_STRICT-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[B]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: [[B_IMAG:%.*]] = load x86_fp80, ptr [[B_IMAGP]], align 16
+// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+// PRMTD_STRICT-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], 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 [[TMP0]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16
+// PRMTD_STRICT-NEXT: [[MUL_AC:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[DOTREAL]], x86_fp80 [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_BD:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[DOTIMAG]], x86_fp80 [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_AD:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[DOTREAL]], x86_fp80 [[B_IMAG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_BC:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[DOTIMAG]], x86_fp80 [[B_REAL]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_R:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[MUL_AC]], x86_fp80 [[MUL_BD]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[MUL_I:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[MUL_AD]], x86_fp80 [[MUL_BC]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR4]]
+// PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 0
+// PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[TMP0]], i32 0, i32 1
+// PRMTD_STRICT-NEXT: store x86_fp80 [[MUL_R]], ptr [[DOTREALP1]], align 16
+// PRMTD_STRICT-NEXT: store x86_fp80 [[MUL_I]], ptr [[DOTIMAGP2]], align 16
+// PRMTD_STRICT-NEXT: ret void
+//
+void mulassignld(_Complex long double *a, _Complex long double b) {
+ *a *= b;
+}
+
// FULL-LABEL: define dso_local <2 x float> @f1(
// FULL-SAME: <2 x float> noundef [[A_COERCE:%.*]], ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 [[B:%.*]], <2 x float> noundef [[C_COERCE:%.*]]) #[[ATTR0]] {
// FULL-NEXT: entry:
More information about the cfe-commits
mailing list