[clang-tools-extra] [lldb] [libc] [llvm] [clang] [libcxxabi] [libunwind] [libcxx] [flang] [lld] [compiler-rt] Fix a bug in Smith's algorithm used in complex div/mul. (PR #78330)
Simon Pilgrim via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 18 07:44:49 PST 2024
https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/78330
>From 8f8917528e30d2ba67f669cfd1a893bc85c21121 Mon Sep 17 00:00:00 2001
From: Ammarguellat <zahira.ammarguellat at intel.com>
Date: Tue, 16 Jan 2024 11:24:03 -0800
Subject: [PATCH 1/4] Fixed a bug in Smith's algorithm and made sure last
option in command line rules.
---
clang/lib/CodeGen/CGExprComplex.cpp | 8 ++++++--
clang/lib/Driver/ToolChains/Clang.cpp | 19 ++++++++++---------
clang/test/CodeGen/cx-complex-range.c | 16 ++++++++++++++++
clang/test/Driver/range.c | 7 +++++++
4 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index e532794b71bdb4a..6fbd8f19eeb50a4 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -936,7 +936,7 @@ ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
llvm::Value *RC = Builder.CreateFMul(CdD, RHSr); // rc
llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC); // tmp=d+rc
- llvm::Value *T7 = Builder.CreateFMul(LHSr, RC); // ar
+ llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD); // ar
llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi); // ar+b
llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC); // (ar+b)/tmp
@@ -978,7 +978,11 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);
else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Limited)
return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
- else if (!CGF.getLangOpts().FastMath) {
+ else if (!CGF.getLangOpts().FastMath ||
+ // '-ffast-math' is used in the command line but followed by an
+ // '-fno-cx-limited-range'.
+ (CGF.getLangOpts().FastMath &&
+ Op.FPFeatures.getComplexRange() == LangOptions::CX_Full)) {
LHSi = OrigLHSi;
// If we have a complex operand on the RHS and FastMath is not allowed, we
// delegate to a libcall to handle all of the complexities and minimize
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 9edae3fec91a87f..0c05d1db3960718 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2753,6 +2753,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
StringRef Float16ExcessPrecision = "";
StringRef BFloat16ExcessPrecision = "";
LangOptions::ComplexRangeKind Range = LangOptions::ComplexRangeKind::CX_Full;
+ std::string ComplexRangeStr = "";
if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
CmdArgs.push_back("-mlimit-float-precision");
@@ -2768,24 +2769,24 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
case options::OPT_fcx_limited_range: {
EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Limited);
Range = LangOptions::ComplexRangeKind::CX_Limited;
- std::string ComplexRangeStr = RenderComplexRangeOption("limited");
- if (!ComplexRangeStr.empty())
- CmdArgs.push_back(Args.MakeArgString(ComplexRangeStr));
+ ComplexRangeStr = RenderComplexRangeOption("limited");
break;
}
case options::OPT_fno_cx_limited_range:
+ EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full);
Range = LangOptions::ComplexRangeKind::CX_Full;
+ ComplexRangeStr = RenderComplexRangeOption("full");
break;
case options::OPT_fcx_fortran_rules: {
EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Fortran);
Range = LangOptions::ComplexRangeKind::CX_Fortran;
- std::string ComplexRangeStr = RenderComplexRangeOption("fortran");
- if (!ComplexRangeStr.empty())
- CmdArgs.push_back(Args.MakeArgString(ComplexRangeStr));
+ ComplexRangeStr = RenderComplexRangeOption("fortran");
break;
}
case options::OPT_fno_cx_fortran_rules:
+ EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full);
Range = LangOptions::ComplexRangeKind::CX_Full;
+ ComplexRangeStr = RenderComplexRangeOption("full");
break;
case options::OPT_ffp_model_EQ: {
// If -ffp-model= is seen, reset to fno-fast-math
@@ -3056,9 +3057,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
SeenUnsafeMathModeOption = true;
// ffast-math enables fortran rules for complex multiplication and
// division.
- std::string ComplexRangeStr = RenderComplexRangeOption("limited");
- if (!ComplexRangeStr.empty())
- CmdArgs.push_back(Args.MakeArgString(ComplexRangeStr));
+ ComplexRangeStr = RenderComplexRangeOption("limited");
break;
}
case options::OPT_fno_fast_math:
@@ -3215,6 +3214,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
options::OPT_fstrict_float_cast_overflow, false))
CmdArgs.push_back("-fno-strict-float-cast-overflow");
+ if (!ComplexRangeStr.empty())
+ CmdArgs.push_back(Args.MakeArgString(ComplexRangeStr));
if (Args.hasArg(options::OPT_fcx_limited_range))
CmdArgs.push_back("-fcx-limited-range");
if (Args.hasArg(options::OPT_fcx_fortran_rules))
diff --git a/clang/test/CodeGen/cx-complex-range.c b/clang/test/CodeGen/cx-complex-range.c
index 8368fa611335cca..2d8507c710f2021 100644
--- a/clang/test/CodeGen/cx-complex-range.c
+++ b/clang/test/CodeGen/cx-complex-range.c
@@ -15,9 +15,25 @@
// RUN: -ffast-math -complex-range=limited -emit-llvm -o - %s \
// RUN: | FileCheck %s --check-prefix=LMTD-FAST
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu \
+// RUN: -ffast-math -complex-range=full -emit-llvm -o - %s \
+// RUN: | FileCheck %s --check-prefix=FULL
+
// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
// RUN: -fno-cx-fortran-rules -o - | FileCheck %s --check-prefix=FULL
+// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
+// RUN: -fcx-limited-range -fno-cx-limited-range -o - \
+// RUN: | FileCheck %s --check-prefix=FULL
+
+// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
+// RUN: -fno-cx-limited-range -fcx-limited-range -o - \
+// RUN: | FileCheck %s --check-prefix=FULL
+
+// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
+// RUN: -fno-cx-fortran-rules -fcx-fortran-rules -o - \
+// RUN: | FileCheck %s --check-prefix=FULL
+
_Complex float div(_Complex float a, _Complex float b) {
// LABEL: define {{.*}} @div(
// FULL: call {{.*}} @__divsc3
diff --git a/clang/test/Driver/range.c b/clang/test/Driver/range.c
index 8d456a997d6967e..045d9c7d3d802ae 100644
--- a/clang/test/Driver/range.c
+++ b/clang/test/Driver/range.c
@@ -6,6 +6,9 @@
// RUN: %clang -### -target x86_64 -fno-cx-limited-range -c %s 2>&1 \
// RUN: | FileCheck %s
+// RUN: %clang -### -target x86_64 -fcx-limited-range -fno-cx-limited-range \
+// RUN: -c %s 2>&1 | FileCheck --check-prefix=FULL %s
+
// RUN: %clang -### -target x86_64 -fcx-fortran-rules -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=FRTRN %s
@@ -29,7 +32,11 @@
// RUN: %clang -### -target x86_64 -fcx-limited-range -ffast-math -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=LMTD %s
+// RUN: %clang -### -target x86_64 -ffast-math -fno-cx-limited-range -c %s 2>&1 \
+// RUN: | FileCheck --check-prefix=FULL %s
+
// LMTD: -complex-range=limited
+// FULL: -complex-range=full
// LMTD-NOT: -complex-range=fortran
// CHECK-NOT: -complex-range=limited
// FRTRN: -complex-range=fortran
>From 989659aabd773abea9d0061e74ed2341d272548f Mon Sep 17 00:00:00 2001
From: Ammarguellat <zahira.ammarguellat at intel.com>
Date: Wed, 17 Jan 2024 05:05:51 -0800
Subject: [PATCH 2/4] Testing.
---
clang/test/CodeGen/test.c | 1 +
1 file changed, 1 insertion(+)
create mode 100644 clang/test/CodeGen/test.c
diff --git a/clang/test/CodeGen/test.c b/clang/test/CodeGen/test.c
new file mode 100644
index 000000000000000..1a4baf536d705b9
--- /dev/null
+++ b/clang/test/CodeGen/test.c
@@ -0,0 +1 @@
+
>From aefa66113b2dce1babd8e87c0c64de0dd0503991 Mon Sep 17 00:00:00 2001
From: Ammarguellat <zahira.ammarguellat at intel.com>
Date: Wed, 17 Jan 2024 05:06:59 -0800
Subject: [PATCH 3/4] Deleted test.c added by mistake.
---
clang/test/CodeGen/test.c | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 clang/test/CodeGen/test.c
diff --git a/clang/test/CodeGen/test.c b/clang/test/CodeGen/test.c
deleted file mode 100644
index 1a4baf536d705b9..000000000000000
--- a/clang/test/CodeGen/test.c
+++ /dev/null
@@ -1 +0,0 @@
-
>From f6918d4223370f6dd038cac8c1d12224afa46eb4 Mon Sep 17 00:00:00 2001
From: Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 18 Jan 2024 07:44:18 -0800
Subject: [PATCH 4/4] Addressed review comments.
---
clang/include/clang/Basic/LangOptions.def | 2 +-
clang/include/clang/Basic/LangOptions.h | 2 +-
clang/lib/CodeGen/CGExprComplex.cpp | 3 +-
clang/lib/Driver/ToolChains/Clang.cpp | 27 ++++++++---
clang/test/CodeGen/smiths-complex-div.c | 59 +++++++++++++++++++++++
5 files changed, 81 insertions(+), 12 deletions(-)
create mode 100644 clang/test/CodeGen/smiths-complex-div.c
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 0428b70c602062e..0564a012abe632a 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -220,7 +220,7 @@ BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization wit
BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")
-ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 2, CX_Full, "Enable use of range reduction for complex arithmetics.")
+ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 2, CX_None, "Enable use of range reduction for complex arithmetics.")
BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 9f986fce2d44188..4d59bcd44cef381 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -392,7 +392,7 @@ class LangOptions : public LangOptionsBase {
IncompleteOnly = 3,
};
- enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran };
+ enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran, CX_None };
public:
/// The used language standard.
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 6fbd8f19eeb50a4..804eb8c9c6542fb 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -981,8 +981,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
else if (!CGF.getLangOpts().FastMath ||
// '-ffast-math' is used in the command line but followed by an
// '-fno-cx-limited-range'.
- (CGF.getLangOpts().FastMath &&
- Op.FPFeatures.getComplexRange() == LangOptions::CX_Full)) {
+ Op.FPFeatures.getComplexRange() == LangOptions::CX_Full) {
LHSi = OrigLHSi;
// If we have a complex operand on the RHS and FastMath is not allowed, we
// delegate to a libcall to handle all of the complexities and minimize
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 7e25347677e23e8..b6d3345e2567864 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2712,9 +2712,22 @@ static void EmitComplexRangeDiag(const Driver &D,
<< EnumComplexRangeToStr(Range1) << EnumComplexRangeToStr(Range2);
}
-static std::string RenderComplexRangeOption(std::string Range) {
+static std::string
+RenderComplexRangeOption(LangOptions::ComplexRangeKind Range) {
std::string ComplexRangeStr = "-complex-range=";
- ComplexRangeStr += Range;
+ switch (Range) {
+ case LangOptions::ComplexRangeKind::CX_Full:
+ ComplexRangeStr += "full";
+ break;
+ case LangOptions::ComplexRangeKind::CX_Limited:
+ ComplexRangeStr += "limited";
+ break;
+ case LangOptions::ComplexRangeKind::CX_Fortran:
+ ComplexRangeStr += "fortran";
+ break;
+ case LangOptions::ComplexRangeKind::CX_None:
+ ComplexRangeStr = "";
+ }
return ComplexRangeStr;
}
@@ -2764,7 +2777,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
bool StrictFPModel = false;
StringRef Float16ExcessPrecision = "";
StringRef BFloat16ExcessPrecision = "";
- LangOptions::ComplexRangeKind Range = LangOptions::ComplexRangeKind::CX_Full;
+ LangOptions::ComplexRangeKind Range = LangOptions::ComplexRangeKind::CX_None;
std::string ComplexRangeStr = "";
if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
@@ -2781,24 +2794,20 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
case options::OPT_fcx_limited_range: {
EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Limited);
Range = LangOptions::ComplexRangeKind::CX_Limited;
- ComplexRangeStr = RenderComplexRangeOption("limited");
break;
}
case options::OPT_fno_cx_limited_range:
EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full);
Range = LangOptions::ComplexRangeKind::CX_Full;
- ComplexRangeStr = RenderComplexRangeOption("full");
break;
case options::OPT_fcx_fortran_rules: {
EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Fortran);
Range = LangOptions::ComplexRangeKind::CX_Fortran;
- ComplexRangeStr = RenderComplexRangeOption("fortran");
break;
}
case options::OPT_fno_cx_fortran_rules:
EmitComplexRangeDiag(D, Range, LangOptions::ComplexRangeKind::CX_Full);
Range = LangOptions::ComplexRangeKind::CX_Full;
- ComplexRangeStr = RenderComplexRangeOption("full");
break;
case options::OPT_ffp_model_EQ: {
// If -ffp-model= is seen, reset to fno-fast-math
@@ -3069,7 +3078,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
SeenUnsafeMathModeOption = true;
// ffast-math enables fortran rules for complex multiplication and
// division.
- ComplexRangeStr = RenderComplexRangeOption("limited");
+ Range = LangOptions::ComplexRangeKind::CX_Limited;
break;
}
case options::OPT_fno_fast_math:
@@ -3226,6 +3235,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
options::OPT_fstrict_float_cast_overflow, false))
CmdArgs.push_back("-fno-strict-float-cast-overflow");
+ if (Range != LangOptions::ComplexRangeKind::CX_None)
+ ComplexRangeStr = RenderComplexRangeOption(Range);
if (!ComplexRangeStr.empty())
CmdArgs.push_back(Args.MakeArgString(ComplexRangeStr));
if (Args.hasArg(options::OPT_fcx_limited_range))
diff --git a/clang/test/CodeGen/smiths-complex-div.c b/clang/test/CodeGen/smiths-complex-div.c
new file mode 100644
index 000000000000000..75775675c923811
--- /dev/null
+++ b/clang/test/CodeGen/smiths-complex-div.c
@@ -0,0 +1,59 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
+// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
+// RUN: -complex-range=fortran -o - | FileCheck %s --check-prefix=FRTRN
+
+// FRTRN-LABEL: define dso_local <2 x float> @div(
+// FRTRN-SAME: <2 x float> noundef [[A_COERCE:%.*]], <2 x float> noundef [[B_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// FRTRN-NEXT: entry:
+// FRTRN-NEXT: [[RETVAL:%.*]] = alloca { float, float }, align 4
+// FRTRN-NEXT: [[A:%.*]] = alloca { float, float }, align 4
+// FRTRN-NEXT: [[B:%.*]] = alloca { float, float }, align 4
+// FRTRN-NEXT: store <2 x float> [[A_COERCE]], ptr [[A]], align 4
+// FRTRN-NEXT: store <2 x float> [[B_COERCE]], ptr [[B]], align 4
+// FRTRN-NEXT: [[A_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 0
+// FRTRN-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
+// FRTRN-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[A]], i32 0, i32 1
+// FRTRN-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
+// FRTRN-NEXT: [[B_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 0
+// FRTRN-NEXT: [[B_REAL:%.*]] = load float, ptr [[B_REALP]], align 4
+// FRTRN-NEXT: [[B_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[B]], i32 0, i32 1
+// FRTRN-NEXT: [[B_IMAG:%.*]] = load float, ptr [[B_IMAGP]], align 4
+// FRTRN-NEXT: [[TMP0:%.*]] = call float @llvm.fabs.f32(float [[B_REAL]])
+// FRTRN-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[B_IMAG]])
+// FRTRN-NEXT: [[ABS_CMP:%.*]] = fcmp ugt float [[TMP0]], [[TMP1]]
+// FRTRN-NEXT: br i1 [[ABS_CMP]], label [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI:%.*]], label [[ABS_RHSR_LESS_THAN_ABS_RHSI:%.*]]
+// FRTRN: abs_rhsr_greater_or_equal_abs_rhsi:
+// FRTRN-NEXT: [[TMP2:%.*]] = fdiv float [[B_IMAG]], [[B_REAL]]
+// FRTRN-NEXT: [[TMP3:%.*]] = fmul float [[TMP2]], [[B_IMAG]]
+// FRTRN-NEXT: [[TMP4:%.*]] = fadd float [[B_REAL]], [[TMP3]]
+// FRTRN-NEXT: [[TMP5:%.*]] = fmul float [[A_IMAG]], [[TMP2]]
+// FRTRN-NEXT: [[TMP6:%.*]] = fadd float [[A_REAL]], [[TMP5]]
+// FRTRN-NEXT: [[TMP7:%.*]] = fdiv float [[TMP6]], [[TMP4]]
+// FRTRN-NEXT: [[TMP8:%.*]] = fmul float [[A_REAL]], [[TMP2]]
+// FRTRN-NEXT: [[TMP9:%.*]] = fsub float [[A_IMAG]], [[TMP8]]
+// FRTRN-NEXT: [[TMP10:%.*]] = fdiv float [[TMP9]], [[TMP4]]
+// FRTRN-NEXT: br label [[COMPLEX_DIV:%.*]]
+// FRTRN: abs_rhsr_less_than_abs_rhsi:
+// FRTRN-NEXT: [[TMP11:%.*]] = fdiv float [[B_REAL]], [[B_IMAG]]
+// FRTRN-NEXT: [[TMP12:%.*]] = fmul float [[TMP11]], [[B_REAL]]
+// FRTRN-NEXT: [[TMP13:%.*]] = fadd float [[B_IMAG]], [[TMP12]]
+// FRTRN-NEXT: [[TMP14:%.*]] = fmul float [[A_REAL]], [[TMP11]]
+// FRTRN-NEXT: [[TMP15:%.*]] = fadd float [[TMP14]], [[A_IMAG]]
+// FRTRN-NEXT: [[TMP16:%.*]] = fdiv float [[TMP15]], [[TMP13]]
+// FRTRN-NEXT: [[TMP17:%.*]] = fmul float [[A_IMAG]], [[TMP11]]
+// FRTRN-NEXT: [[TMP18:%.*]] = fsub float [[TMP17]], [[A_REAL]]
+// FRTRN-NEXT: [[TMP19:%.*]] = fdiv float [[TMP18]], [[TMP13]]
+// FRTRN-NEXT: br label [[COMPLEX_DIV]]
+// FRTRN: complex_div:
+// FRTRN-NEXT: [[TMP20:%.*]] = phi float [ [[TMP7]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP16]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// FRTRN-NEXT: [[TMP21:%.*]] = phi float [ [[TMP10]], [[ABS_RHSR_GREATER_OR_EQUAL_ABS_RHSI]] ], [ [[TMP19]], [[ABS_RHSR_LESS_THAN_ABS_RHSI]] ]
+// FRTRN-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0
+// FRTRN-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1
+// FRTRN-NEXT: store float [[TMP20]], ptr [[RETVAL_REALP]], align 4
+// FRTRN-NEXT: store float [[TMP21]], ptr [[RETVAL_IMAGP]], align 4
+// FRTRN-NEXT: [[TMP22:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
+// FRTRN-NEXT: ret <2 x float> [[TMP22]]
+//
+_Complex float div(_Complex float a, _Complex float b) {
+ return a / b;
+}
More information about the cfe-commits
mailing list