Skip to content

Commit c14c34d

Browse files
committed
[clang][Interp] Implement __builtin_fmin
Differential Revision: https://reviews.llvm.org/D155546
1 parent 3240ae7 commit c14c34d

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

clang/lib/AST/Interp/InterpBuiltin.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,25 @@ static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC,
143143
return true;
144144
}
145145

146+
static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC,
147+
const InterpFrame *Frame, const Function *F) {
148+
const Floating &LHS = getParam<Floating>(Frame, 0);
149+
const Floating &RHS = getParam<Floating>(Frame, 1);
150+
151+
Floating Result;
152+
153+
// When comparing zeroes, return -0.0 if one of the zeroes is negative.
154+
if (LHS.isZero() && RHS.isZero() && RHS.isNegative())
155+
Result = RHS;
156+
else if (LHS.isNan() || RHS < LHS)
157+
Result = RHS;
158+
else
159+
Result = LHS;
160+
161+
S.Stk.push<Floating>(Result);
162+
return true;
163+
}
164+
146165
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) {
147166
InterpFrame *Frame = S.Current;
148167
APValue Dummy;
@@ -195,6 +214,15 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) {
195214
return Ret<PT_Float>(S, OpPC, Dummy);
196215
break;
197216

217+
case Builtin::BI__builtin_fmin:
218+
case Builtin::BI__builtin_fminf:
219+
case Builtin::BI__builtin_fminl:
220+
case Builtin::BI__builtin_fminf16:
221+
case Builtin::BI__builtin_fminf128:
222+
if (interp__builtin_fmin(S, OpPC, Frame, F))
223+
return Ret<PT_Float>(S, OpPC, Dummy);
224+
break;
225+
198226
default:
199227
return false;
200228
}

clang/test/AST/Interp/builtin-functions.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,15 @@ namespace nan {
6060
// expected-note {{read of dereferenced one-past-the-end pointer}} \
6161
// expected-note {{in call to}}
6262
}
63+
64+
namespace fmin {
65+
constexpr float f1 = __builtin_fmin(1.0, 2.0f);
66+
static_assert(f1 == 1.0f, "");
67+
68+
constexpr float min = __builtin_fmin(__builtin_nan(""), 1);
69+
static_assert(min == 1, "");
70+
constexpr float min2 = __builtin_fmin(1, __builtin_nan(""));
71+
static_assert(min2 == 1, "");
72+
constexpr float min3 = __builtin_fmin(__builtin_inf(), __builtin_nan(""));
73+
static_assert(min3 == __builtin_inf(), "");
74+
}

0 commit comments

Comments
 (0)