// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 // RUN: %clang_cc1 %s -O0 -disable-O0-optnone -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -o - | opt -S -passes=sroa | FileCheck %s --check-prefix=FULL // RUN: %clang_cc1 %s -O0 -disable-O0-optnone -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -complex-range=improved -o - | opt -S -passes=sroa | FileCheck %s --check-prefix=IMPRVD // RUN: %clang_cc1 %s -O0 -disable-O0-optnone -emit-llvm -triple x86_64-unknown-unknown \ // RUN: -complex-range=promoted -o - | opt -S -passes=sroa | 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 -disable-O0-optnone \ // RUN: -emit-llvm -o - %s | opt -S -passes=sroa | 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: [[A_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 0 // FULL-NEXT: [[A_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 1 // FULL-NEXT: [[MUL_RL:%.*]] = fmul float [[A_SROA_0_0_VEC_EXTRACT]], [[B]] // FULL-NEXT: [[MUL_IL:%.*]] = fmul float [[A_SROA_0_4_VEC_EXTRACT]], [[B]] // FULL-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[MUL_RL]], i32 0 // FULL-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[MUL_IL]], i32 1 // FULL-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[A_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 0 // IMPRVD-NEXT: [[A_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 1 // IMPRVD-NEXT: [[MUL_RL:%.*]] = fmul float [[A_SROA_0_0_VEC_EXTRACT]], [[B]] // IMPRVD-NEXT: [[MUL_IL:%.*]] = fmul float [[A_SROA_0_4_VEC_EXTRACT]], [[B]] // IMPRVD-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[MUL_RL]], i32 0 // IMPRVD-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[MUL_IL]], i32 1 // IMPRVD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[A_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 0 // PRMTD-NEXT: [[A_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 1 // PRMTD-NEXT: [[MUL_RL:%.*]] = fmul float [[A_SROA_0_0_VEC_EXTRACT]], [[B]] // PRMTD-NEXT: [[MUL_IL:%.*]] = fmul float [[A_SROA_0_4_VEC_EXTRACT]], [[B]] // PRMTD-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[MUL_RL]], i32 0 // PRMTD-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[MUL_IL]], i32 1 // PRMTD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[A_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 0 // PRMTD_STRICT-NEXT: [[A_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 1 // PRMTD_STRICT-NEXT: [[MUL_RL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[A_SROA_0_0_VEC_EXTRACT]], float [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3:[0-9]+]] // PRMTD_STRICT-NEXT: [[MUL_IL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[A_SROA_0_4_VEC_EXTRACT]], float [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[MUL_RL]], i32 0 // PRMTD_STRICT-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[MUL_IL]], i32 1 // PRMTD_STRICT-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // _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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // FULL-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4 // FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // FULL-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4 // FULL-NEXT: [[MUL_RL:%.*]] = fmul float [[DOTREAL]], [[B]] // FULL-NEXT: [[MUL_IL:%.*]] = fmul float [[DOTIMAG]], [[B]] // FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // IMPRVD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4 // IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // IMPRVD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4 // IMPRVD-NEXT: [[MUL_RL:%.*]] = fmul float [[DOTREAL]], [[B]] // IMPRVD-NEXT: [[MUL_IL:%.*]] = fmul float [[DOTIMAG]], [[B]] // IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // PRMTD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4 // PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // PRMTD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4 // PRMTD-NEXT: [[MUL_RL:%.*]] = fmul float [[DOTREAL]], [[B]] // PRMTD-NEXT: [[MUL_IL:%.*]] = fmul float [[DOTIMAG]], [[B]] // PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4 // PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], 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 [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[MUL_IL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[DOTIMAG]], float [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], 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: [[B_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[B_COERCE]], i32 0 // FULL-NEXT: [[B_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[B_COERCE]], i32 1 // FULL-NEXT: [[MUL_RL:%.*]] = fmul float [[A]], [[B_SROA_0_0_VEC_EXTRACT]] // FULL-NEXT: [[MUL_IR:%.*]] = fmul float [[A]], [[B_SROA_0_4_VEC_EXTRACT]] // FULL-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[MUL_RL]], i32 0 // FULL-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[MUL_IR]], i32 1 // FULL-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[B_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[B_COERCE]], i32 0 // IMPRVD-NEXT: [[B_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[B_COERCE]], i32 1 // IMPRVD-NEXT: [[MUL_RL:%.*]] = fmul float [[A]], [[B_SROA_0_0_VEC_EXTRACT]] // IMPRVD-NEXT: [[MUL_IR:%.*]] = fmul float [[A]], [[B_SROA_0_4_VEC_EXTRACT]] // IMPRVD-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[MUL_RL]], i32 0 // IMPRVD-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[MUL_IR]], i32 1 // IMPRVD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[B_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[B_COERCE]], i32 0 // PRMTD-NEXT: [[B_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[B_COERCE]], i32 1 // PRMTD-NEXT: [[MUL_RL:%.*]] = fmul float [[A]], [[B_SROA_0_0_VEC_EXTRACT]] // PRMTD-NEXT: [[MUL_IR:%.*]] = fmul float [[A]], [[B_SROA_0_4_VEC_EXTRACT]] // PRMTD-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[MUL_RL]], i32 0 // PRMTD-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[MUL_IR]], i32 1 // PRMTD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[B_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[B_COERCE]], i32 0 // PRMTD_STRICT-NEXT: [[B_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[B_COERCE]], i32 1 // PRMTD_STRICT-NEXT: [[MUL_RL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[A]], float [[B_SROA_0_0_VEC_EXTRACT]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[MUL_IR:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[A]], float [[B_SROA_0_4_VEC_EXTRACT]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[MUL_RL]], i32 0 // PRMTD_STRICT-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[MUL_IR]], i32 1 // PRMTD_STRICT-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // _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: [[A_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 0 // FULL-NEXT: [[A_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 1 // FULL-NEXT: [[TMP0:%.*]] = fdiv float [[A_SROA_0_0_VEC_EXTRACT]], [[B]] // FULL-NEXT: [[TMP1:%.*]] = fdiv float [[A_SROA_0_4_VEC_EXTRACT]], [[B]] // FULL-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[TMP0]], i32 0 // FULL-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[TMP1]], i32 1 // FULL-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[A_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 0 // IMPRVD-NEXT: [[A_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 1 // IMPRVD-NEXT: [[TMP0:%.*]] = fdiv float [[A_SROA_0_0_VEC_EXTRACT]], [[B]] // IMPRVD-NEXT: [[TMP1:%.*]] = fdiv float [[A_SROA_0_4_VEC_EXTRACT]], [[B]] // IMPRVD-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[TMP0]], i32 0 // IMPRVD-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[TMP1]], i32 1 // IMPRVD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[A_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 0 // PRMTD-NEXT: [[A_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 1 // PRMTD-NEXT: [[TMP0:%.*]] = fdiv float [[A_SROA_0_0_VEC_EXTRACT]], [[B]] // PRMTD-NEXT: [[TMP1:%.*]] = fdiv float [[A_SROA_0_4_VEC_EXTRACT]], [[B]] // PRMTD-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[TMP0]], i32 0 // PRMTD-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[TMP1]], i32 1 // PRMTD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[A_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 0 // PRMTD_STRICT-NEXT: [[A_SROA_0_4_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[A_COERCE]], i32 1 // PRMTD_STRICT-NEXT: [[TMP0:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[A_SROA_0_0_VEC_EXTRACT]], float [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[A_SROA_0_4_VEC_EXTRACT]], float [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[TMP0]], i32 0 // PRMTD_STRICT-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[TMP1]], i32 1 // PRMTD_STRICT-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // _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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // FULL-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4 // FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // FULL-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4 // FULL-NEXT: [[TMP0:%.*]] = fdiv float [[DOTREAL]], [[B]] // FULL-NEXT: [[TMP1:%.*]] = fdiv float [[DOTIMAG]], [[B]] // FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // FULL-NEXT: store float [[TMP0]], ptr [[DOTREALP1]], align 4 // FULL-NEXT: store float [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // IMPRVD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4 // IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // IMPRVD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4 // IMPRVD-NEXT: [[TMP0:%.*]] = fdiv float [[DOTREAL]], [[B]] // IMPRVD-NEXT: [[TMP1:%.*]] = fdiv float [[DOTIMAG]], [[B]] // IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // IMPRVD-NEXT: store float [[TMP0]], ptr [[DOTREALP1]], align 4 // IMPRVD-NEXT: store float [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // PRMTD-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4 // PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // PRMTD-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4 // PRMTD-NEXT: [[TMP0:%.*]] = fdiv float [[DOTREAL]], [[B]] // PRMTD-NEXT: [[TMP1:%.*]] = fdiv float [[DOTIMAG]], [[B]] // PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // PRMTD-NEXT: store float [[TMP0]], ptr [[DOTREALP1]], align 4 // PRMTD-NEXT: store float [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load float, ptr [[DOTREALP]], align 4 // PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load float, ptr [[DOTIMAGP]], align 4 // PRMTD_STRICT-NEXT: [[TMP0:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[DOTREAL]], float [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[DOTIMAG]], float [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 0 // PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1 // PRMTD_STRICT-NEXT: store float [[TMP0]], ptr [[DOTREALP1]], align 4 // PRMTD_STRICT-NEXT: store float [[TMP1]], 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: [[TMP0:%.*]] = fdiv double [[A_COERCE0]], [[B]] // FULL-NEXT: [[TMP1:%.*]] = fdiv double [[A_COERCE1]], [[B]] // FULL-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { double, double } poison, double [[TMP0]], 0 // FULL-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { double, double } [[DOTFCA_0_INSERT]], double [[TMP1]], 1 // FULL-NEXT: ret { double, double } [[DOTFCA_1_INSERT]] // // 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: [[TMP0:%.*]] = fdiv double [[A_COERCE0]], [[B]] // IMPRVD-NEXT: [[TMP1:%.*]] = fdiv double [[A_COERCE1]], [[B]] // IMPRVD-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { double, double } poison, double [[TMP0]], 0 // IMPRVD-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { double, double } [[DOTFCA_0_INSERT]], double [[TMP1]], 1 // IMPRVD-NEXT: ret { double, double } [[DOTFCA_1_INSERT]] // // 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: [[TMP0:%.*]] = fdiv double [[A_COERCE0]], [[B]] // PRMTD-NEXT: [[TMP1:%.*]] = fdiv double [[A_COERCE1]], [[B]] // PRMTD-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { double, double } poison, double [[TMP0]], 0 // PRMTD-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { double, double } [[DOTFCA_0_INSERT]], double [[TMP1]], 1 // PRMTD-NEXT: ret { double, double } [[DOTFCA_1_INSERT]] // // 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: [[TMP0:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A_COERCE0]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A_COERCE1]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { double, double } poison, double [[TMP0]], 0 // PRMTD_STRICT-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { double, double } [[DOTFCA_0_INSERT]], double [[TMP1]], 1 // PRMTD_STRICT-NEXT: ret { double, double } [[DOTFCA_1_INSERT]] // _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: [[CALL:%.*]] = call { double, double } @__divdc3(double noundef [[A]], double noundef 0.000000e+00, double noundef [[B_COERCE0]], double noundef [[B_COERCE1]]) #[[ATTR2:[0-9]+]] // FULL-NEXT: [[TMP0:%.*]] = extractvalue { double, double } [[CALL]], 0 // FULL-NEXT: [[TMP1:%.*]] = extractvalue { double, double } [[CALL]], 1 // FULL-NEXT: [[CONV:%.*]] = fptrunc double [[TMP0]] to float // FULL-NEXT: [[CONV1:%.*]] = fptrunc double [[TMP1]] to float // FULL-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[CONV]], i32 0 // FULL-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[CONV1]], i32 1 // FULL-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[TMP0:%.*]] = call double @llvm.fabs.f64(double [[B_COERCE0]]) // IMPRVD-NEXT: [[TMP1:%.*]] = call double @llvm.fabs.f64(double [[B_COERCE1]]) // IMPRVD-NEXT: [[ABS_CMP:%.*]] = fcmp ugt double [[TMP0]], [[TMP1]] // IMPRVD-NEXT: br i1 [[ABS_CMP]], label %[[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:.*]], label %[[ABS_RHSR_LESS_THAN_ABS_RHSI:.*]] // IMPRVD: [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]]: // IMPRVD-NEXT: [[TMP2:%.*]] = fdiv double [[B_COERCE1]], [[B_COERCE0]] // IMPRVD-NEXT: [[TMP3:%.*]] = fmul double [[TMP2]], [[B_COERCE1]] // IMPRVD-NEXT: [[TMP4:%.*]] = fadd double [[B_COERCE0]], [[TMP3]] // IMPRVD-NEXT: [[TMP5:%.*]] = fmul double 0.000000e+00, [[TMP2]] // IMPRVD-NEXT: [[TMP6:%.*]] = fadd double [[A]], [[TMP5]] // IMPRVD-NEXT: [[TMP7:%.*]] = fdiv double [[TMP6]], [[TMP4]] // IMPRVD-NEXT: [[TMP8:%.*]] = fmul double [[A]], [[TMP2]] // IMPRVD-NEXT: [[TMP9:%.*]] = fsub double 0.000000e+00, [[TMP8]] // IMPRVD-NEXT: [[TMP10:%.*]] = fdiv double [[TMP9]], [[TMP4]] // IMPRVD-NEXT: br label %[[COMPLEX_DIV:.*]] // IMPRVD: [[ABS_RHSR_LESS_THAN_ABS_RHSI]]: // IMPRVD-NEXT: [[TMP11:%.*]] = fdiv double [[B_COERCE0]], [[B_COERCE1]] // IMPRVD-NEXT: [[TMP12:%.*]] = fmul double [[TMP11]], [[B_COERCE0]] // IMPRVD-NEXT: [[TMP13:%.*]] = fadd double [[B_COERCE1]], [[TMP12]] // IMPRVD-NEXT: [[TMP14:%.*]] = fmul double [[A]], [[TMP11]] // IMPRVD-NEXT: [[TMP15:%.*]] = fadd double [[TMP14]], 0.000000e+00 // IMPRVD-NEXT: [[TMP16:%.*]] = fdiv double [[TMP15]], [[TMP13]] // IMPRVD-NEXT: [[TMP17:%.*]] = fmul double 0.000000e+00, [[TMP11]] // IMPRVD-NEXT: [[TMP18:%.*]] = fsub double [[TMP17]], [[A]] // IMPRVD-NEXT: [[TMP19:%.*]] = fdiv double [[TMP18]], [[TMP13]] // IMPRVD-NEXT: br label %[[COMPLEX_DIV]] // IMPRVD: [[COMPLEX_DIV]]: // IMPRVD-NEXT: [[TMP20:%.*]] = phi double [ [[TMP7]], %[[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], %[[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] // IMPRVD-NEXT: [[TMP21:%.*]] = phi double [ [[TMP10]], %[[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], %[[ABS_RHSR_LESS_THAN_ABS_RHSI]] ] // IMPRVD-NEXT: [[CONV:%.*]] = fptrunc double [[TMP20]] to float // IMPRVD-NEXT: [[CONV1:%.*]] = fptrunc double [[TMP21]] to float // IMPRVD-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[CONV]], i32 0 // IMPRVD-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[CONV1]], i32 1 // IMPRVD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[EXT:%.*]] = fpext double [[A]] to x86_fp80 // PRMTD-NEXT: [[EXT1:%.*]] = fpext double [[B_COERCE0]] to x86_fp80 // PRMTD-NEXT: [[EXT2:%.*]] = fpext double [[B_COERCE1]] to x86_fp80 // PRMTD-NEXT: [[TMP0:%.*]] = fmul x86_fp80 [[EXT]], [[EXT1]] // PRMTD-NEXT: [[TMP1:%.*]] = fmul x86_fp80 0xK00000000000000000000, [[EXT2]] // PRMTD-NEXT: [[TMP2:%.*]] = fadd x86_fp80 [[TMP0]], [[TMP1]] // PRMTD-NEXT: [[TMP3:%.*]] = fmul x86_fp80 [[EXT1]], [[EXT1]] // PRMTD-NEXT: [[TMP4:%.*]] = fmul x86_fp80 [[EXT2]], [[EXT2]] // PRMTD-NEXT: [[TMP5:%.*]] = fadd x86_fp80 [[TMP3]], [[TMP4]] // PRMTD-NEXT: [[TMP6:%.*]] = fmul x86_fp80 0xK00000000000000000000, [[EXT1]] // PRMTD-NEXT: [[TMP7:%.*]] = fmul x86_fp80 [[EXT]], [[EXT2]] // PRMTD-NEXT: [[TMP8:%.*]] = fsub x86_fp80 [[TMP6]], [[TMP7]] // PRMTD-NEXT: [[TMP9:%.*]] = fdiv x86_fp80 [[TMP2]], [[TMP5]] // PRMTD-NEXT: [[TMP10:%.*]] = fdiv x86_fp80 [[TMP8]], [[TMP5]] // PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc x86_fp80 [[TMP9]] to double // PRMTD-NEXT: [[UNPROMOTION3:%.*]] = fptrunc x86_fp80 [[TMP10]] to double // PRMTD-NEXT: [[CONV:%.*]] = fptrunc double [[UNPROMOTION]] to float // PRMTD-NEXT: [[CONV4:%.*]] = fptrunc double [[UNPROMOTION3]] to float // PRMTD-NEXT: [[RETVAL_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[CONV]], i32 0 // PRMTD-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[CONV4]], i32 1 // PRMTD-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // // 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: [[EXT:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[A]], metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[EXT1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[B_COERCE0]], metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[EXT2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[B_COERCE1]], metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[EXT]], x86_fp80 [[EXT1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 0xK00000000000000000000, x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fadd.f80(x86_fp80 [[TMP0]], x86_fp80 [[TMP1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[EXT1]], x86_fp80 [[EXT1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[EXT2]], 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 0xK00000000000000000000, x86_fp80 [[EXT1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP7:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmul.f80(x86_fp80 [[EXT]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP8:%.*]] = call x86_fp80 @llvm.experimental.constrained.fsub.f80(x86_fp80 [[TMP6]], x86_fp80 [[TMP7]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP9:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP2]], x86_fp80 [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP10:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[TMP8]], x86_fp80 [[TMP5]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[UNPROMOTION:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP9]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[UNPROMOTION3:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP10]], 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_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x float> undef, float [[CONV]], i32 0 // PRMTD_STRICT-NEXT: [[RETVAL_SROA_0_4_VEC_INSERT:%.*]] = insertelement <2 x float> [[RETVAL_SROA_0_0_VEC_INSERT]], float [[CONV4]], i32 1 // PRMTD_STRICT-NEXT: ret <2 x float> [[RETVAL_SROA_0_4_VEC_INSERT]] // _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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0 // FULL-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8 // FULL-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1 // FULL-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8 // FULL-NEXT: [[TMP0:%.*]] = fdiv double [[DOTREAL]], [[B]] // FULL-NEXT: [[TMP1:%.*]] = fdiv double [[DOTIMAG]], [[B]] // FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0 // FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1 // FULL-NEXT: store double [[TMP0]], ptr [[DOTREALP1]], align 8 // FULL-NEXT: store double [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0 // IMPRVD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8 // IMPRVD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1 // IMPRVD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8 // IMPRVD-NEXT: [[TMP0:%.*]] = fdiv double [[DOTREAL]], [[B]] // IMPRVD-NEXT: [[TMP1:%.*]] = fdiv double [[DOTIMAG]], [[B]] // IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0 // IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1 // IMPRVD-NEXT: store double [[TMP0]], ptr [[DOTREALP1]], align 8 // IMPRVD-NEXT: store double [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0 // PRMTD-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8 // PRMTD-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1 // PRMTD-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8 // PRMTD-NEXT: [[TMP0:%.*]] = fdiv double [[DOTREAL]], [[B]] // PRMTD-NEXT: [[TMP1:%.*]] = fdiv double [[DOTIMAG]], [[B]] // PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0 // PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1 // PRMTD-NEXT: store double [[TMP0]], ptr [[DOTREALP1]], align 8 // PRMTD-NEXT: store double [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0 // PRMTD_STRICT-NEXT: [[DOTREAL:%.*]] = load double, ptr [[DOTREALP]], align 8 // PRMTD_STRICT-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1 // PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load double, ptr [[DOTIMAGP]], align 8 // PRMTD_STRICT-NEXT: [[TMP0:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[DOTREAL]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[DOTIMAG]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 0 // PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1 // PRMTD_STRICT-NEXT: store double [[TMP0]], ptr [[DOTREALP1]], align 8 // PRMTD_STRICT-NEXT: store double [[TMP1]], 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: [[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:%.*]] = fdiv x86_fp80 [[A_REAL]], [[B]] // FULL-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[A_IMAG]], [[B]] // FULL-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { x86_fp80, x86_fp80 } poison, x86_fp80 [[TMP0]], 0 // FULL-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { x86_fp80, x86_fp80 } [[DOTFCA_0_INSERT]], x86_fp80 [[TMP1]], 1 // FULL-NEXT: ret { x86_fp80, x86_fp80 } [[DOTFCA_1_INSERT]] // // 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: [[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:%.*]] = fdiv x86_fp80 [[A_REAL]], [[B]] // IMPRVD-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[A_IMAG]], [[B]] // IMPRVD-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { x86_fp80, x86_fp80 } poison, x86_fp80 [[TMP0]], 0 // IMPRVD-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { x86_fp80, x86_fp80 } [[DOTFCA_0_INSERT]], x86_fp80 [[TMP1]], 1 // IMPRVD-NEXT: ret { x86_fp80, x86_fp80 } [[DOTFCA_1_INSERT]] // // 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: [[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:%.*]] = fdiv x86_fp80 [[A_REAL]], [[B]] // PRMTD-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[A_IMAG]], [[B]] // PRMTD-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { x86_fp80, x86_fp80 } poison, x86_fp80 [[TMP0]], 0 // PRMTD-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { x86_fp80, x86_fp80 } [[DOTFCA_0_INSERT]], x86_fp80 [[TMP1]], 1 // PRMTD-NEXT: ret { x86_fp80, x86_fp80 } [[DOTFCA_1_INSERT]] // // 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: [[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:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[A_REAL]], x86_fp80 [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[A_IMAG]], x86_fp80 [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { x86_fp80, x86_fp80 } poison, x86_fp80 [[TMP0]], 0 // PRMTD_STRICT-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { x86_fp80, x86_fp80 } [[DOTFCA_0_INSERT]], x86_fp80 [[TMP1]], 1 // PRMTD_STRICT-NEXT: ret { x86_fp80, x86_fp80 } [[DOTFCA_1_INSERT]] // _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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], 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 [[A]], i32 0, i32 1 // FULL-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16 // FULL-NEXT: [[TMP0:%.*]] = fdiv x86_fp80 [[DOTREAL]], [[B]] // FULL-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[DOTIMAG]], [[B]] // FULL-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 // FULL-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 // FULL-NEXT: store x86_fp80 [[TMP0]], ptr [[DOTREALP1]], align 16 // FULL-NEXT: store x86_fp80 [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], 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 [[A]], i32 0, i32 1 // IMPRVD-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16 // IMPRVD-NEXT: [[TMP0:%.*]] = fdiv x86_fp80 [[DOTREAL]], [[B]] // IMPRVD-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[DOTIMAG]], [[B]] // IMPRVD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 // IMPRVD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 // IMPRVD-NEXT: store x86_fp80 [[TMP0]], ptr [[DOTREALP1]], align 16 // IMPRVD-NEXT: store x86_fp80 [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], 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 [[A]], i32 0, i32 1 // PRMTD-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16 // PRMTD-NEXT: [[TMP0:%.*]] = fdiv x86_fp80 [[DOTREAL]], [[B]] // PRMTD-NEXT: [[TMP1:%.*]] = fdiv x86_fp80 [[DOTIMAG]], [[B]] // PRMTD-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 // PRMTD-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 // PRMTD-NEXT: store x86_fp80 [[TMP0]], ptr [[DOTREALP1]], align 16 // PRMTD-NEXT: store x86_fp80 [[TMP1]], 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: [[DOTREALP:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], 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 [[A]], i32 0, i32 1 // PRMTD_STRICT-NEXT: [[DOTIMAG:%.*]] = load x86_fp80, ptr [[DOTIMAGP]], align 16 // PRMTD_STRICT-NEXT: [[TMP0:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[DOTREAL]], x86_fp80 [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[DOTIMAG]], x86_fp80 [[B]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] // PRMTD_STRICT-NEXT: [[DOTREALP1:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 0 // PRMTD_STRICT-NEXT: [[DOTIMAGP2:%.*]] = getelementptr inbounds nuw { x86_fp80, x86_fp80 }, ptr [[A]], i32 0, i32 1 // PRMTD_STRICT-NEXT: store x86_fp80 [[TMP0]], ptr [[DOTREALP1]], align 16 // PRMTD_STRICT-NEXT: store x86_fp80 [[TMP1]], ptr [[DOTIMAGP2]], align 16 // PRMTD_STRICT-NEXT: ret void // void divassignld(_Complex long double *a, long double b) { *a /= b; }