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