<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p><br>
</p>
<div class="moz-cite-prefix">On 5/5/22 11:58, Philip Reames wrote:<br>
</div>
<blockquote type="cite"
cite="mid:d92712b7-ed8e-1e1a-50bc-3e52ab9fc9a8@philipreames.com">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<p><br>
</p>
<div class="moz-cite-prefix">On 5/5/22 11:17, Serge Pavlov wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CACOhrX6-1EzKTbZjUEN5wOErMhdUcJGUDmP9GGKDfmKtH5ywvQ@mail.gmail.com">
<meta http-equiv="content-type" content="text/html;
charset=UTF-8">
<div dir="ltr">
<div dir="ltr">OK, I reverted the change.</div>
</div>
</blockquote>
Thank you.<br>
<blockquote type="cite"
cite="mid:CACOhrX6-1EzKTbZjUEN5wOErMhdUcJGUDmP9GGKDfmKtH5ywvQ@mail.gmail.com">
<div dir="ltr">
<div dir="ltr"><br>
</div>
<div dir="ltr">
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">For the constant
example, you're correct. If SimplifyCall decided to use
e.g. a weaker side effecting call, you still have the same
problem.<br clear="all">
</blockquote>
<div><br>
</div>
<div>Could you please elaborate on this case? Side effect of
a constrained intrinsic is only the interaction with
floating point environment: dependence on control modes,
including rounding direction, and change of floating point
exception flags. What do you mean by "weaker side
effecting call"?</div>
</div>
</div>
</blockquote>
<p>Ok, I think I talked myself into a corner here and need to back
up a bit. The "weaker side effecting call" point was wrong. I
was thinking about simplifyLibCall (which can replace one call
with a new one), not SimplifyCall which is only allowed to
replace a call with an existing IR Value. <br>
</p>
<p>Given hat, let me stop and explicitly apologize. I explained
this badly and got myself confused in the process. While I do
think it's important to promptly revert changes with potential
correctness bugs noted, I can understand your hesitation given
my comments weren't making sense. Sorry.</p>
<p><br>
</p>
<p>I still think this patch needs some adjustment before
relanding, but the reasoning is a bit different (and not
correctness related).</p>
<p>The structure given in the patch is not idiomatic. The
idiomatic piece would be:</p>
<p>if (sa<ConstrainedFPIntrinsic>(CI)) {<br>
if (Value *V = SimplifyCall(&CI,
SQ.getWithInstruction(&CI))) {<br>
return IC.replaceAllUsesOf(CI, V);<br>
}<br>
}</p>
<p>The key piece here is that using the result of SimplifyX to
remove X without doing a replacement is very non-idiomatic. It
causes readers - like say me - to go "why?". Unless I'm, still,
missing something, the idiomatic usage should cover your case
right?<br>
</p>
</blockquote>
This probably isn't sufficient for reasons nikic pointed out. See
my upcoming response to him. <br>
<blockquote type="cite"
cite="mid:d92712b7-ed8e-1e1a-50bc-3e52ab9fc9a8@philipreames.com">
<p> </p>
<p><br>
</p>
<p>Thinking about this deeper though, I somewhat think you're
solving this problem in the wrong place. Independently of
whether we can simplify the call, being able to figure out
whether the semantics need to be "strict" would seem like an
interesting transform on it's own. Combined with this existing
code from wouldInstructionBeTriviallyDead:<br>
</p>
<p>if (auto *FPI = dyn_cast<ConstrainedFPIntrinsic>(I)) {<br>
Optional<fp::ExceptionBehavior> ExBehavior =
FPI->getExceptionBehavior();<br>
return ExBehavior.getValue() != fp::ebStrict;<br>
}</p>
<p>It seems like you'd end up with something strictly more
powerful than this patch.<br>
</p>
<br>
<blockquote type="cite"
cite="mid:CACOhrX6-1EzKTbZjUEN5wOErMhdUcJGUDmP9GGKDfmKtH5ywvQ@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">
<div>
<div dir="ltr" class="gmail_signature"
data-smartmail="gmail_signature">Thanks,<br>
--Serge<br>
</div>
</div>
<br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Fri, May 6, 2022 at
1:01 AM Philip Reames <<a
href="mailto:listmail@philipreames.com"
moz-do-not-send="true" class="moz-txt-link-freetext">listmail@philipreames.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div>
<p>Serge,</p>
<p>Please revert this change. If you do not, I will. <br>
</p>
<div>On 5/5/22 10:25, Serge Pavlov wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<p>This is the perfect illustration of my point.
Consider what happens when %result is used. <br>
</p>
<p>SimplifyCall returns ConstantFloat(2.0) in your
example. Dropping the call *without* doing
replaceAllUsesWith is a bug. </p>
</blockquote>
<div>This path is executed for calls that have no
uses. In this case call to replaceAllUsesWith does
not make sense.</div>
</div>
</blockquote>
<p>For the constant example, you're correct. If
SimplifyCall decided to use e.g. a weaker side
effecting call, you still have the same problem.</p>
<blockquote type="cite">
<div dir="ltr">
<div><br>
</div>
<div>The resulting transformation in this case may
be considered as merging of two operations:</div>
<div>1. SimplifyCall returns ConstantFloat(2.0) and
the call is replaced by this expression.</div>
<div>2. As this ConstantFloat(2.0) is not used, it
is removed.</div>
<div>Both operations are valid and occur in
InstCombiner. Their combination must be valid
also. It is just what the discussed code does.</div>
<div> </div>
<div>
<div dir="ltr">Thanks,<br>
--Serge<br>
</div>
</div>
<br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Thu, May 5,
2022 at 11:39 PM Philip Reames <<a
href="mailto:listmail@philipreames.com"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">listmail@philipreames.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div>
<p><br>
</p>
<div>On 5/5/22 09:32, Serge Pavlov wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">My
point is that SimplifyCall is allowed to
simplify one side effecting call to
another side effecting call.<br
clear="all">
</blockquote>
<div><br>
</div>
<div>It also may simplify side effecting
call to something that has no side
effect, if the side effect is actually
absent. It takes place for the code: </div>
<div><br>
</div>
<div>define float @f_unused_precise() #0 {<br>
%result = call float
@llvm.experimental.constrained.fadd.f32(float
1.0, float 1.0, metadata !"round.upward",
metadata !"fpexcept.strict") #0<br>
ret float 1.0<br>
}<br>
</div>
<div><br>
</div>
<div>In it experimental.constrained.fadd has
side effect, because exception behavior is
strict, but SimplifyCall can reveal that
actually side effect is absent and
simplifies the call to the constant 2.0.
As the result of the call is not used the
net result is removal of the call.</div>
</div>
</blockquote>
<p>This is the perfect illustration of my
point. Consider what happens when %result is
used. <br>
</p>
<p>SimplifyCall returns ConstantFloat(2.0) in
your example. Dropping the call *without*
doing replaceAllUsesWith is a bug. </p>
<p>Please revert this change. If you want, we
can continue discussing on the review
afterwards, but please revert this change
now. <br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div><br>
</div>
<div>
<div dir="ltr">Thanks,<br>
--Serge<br>
</div>
</div>
<br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Thu,
May 5, 2022 at 11:17 PM Philip Reames <<a
href="mailto:listmail@philipreames.com"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">listmail@philipreames.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div>
<p><br>
</p>
<div>On 5/5/22 09:14, Serge Pavlov
wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">This
looks incorrect to me.
SimplifyCall returns a Value*
for a<br>
simplified expression and you're
interpreting that as a boolean
meaning<br>
"delete call".<br>
</blockquote>
<div><br>
</div>
<div>In this case SimplifyCall is
called for a call, which is not
used and was not removed only
because it has declared side
effect. Non-null replacement
returned by SimplifyCall is used
as an indicator that the call
may be simplified, so its side
effect is absent or may be
ignored. Such unused calls
appear as a result of other
transformations, they are not
removed due to the side effect
and produce useless instructions
in resulting code. <br>
</div>
</div>
</div>
</blockquote>
<p>My point is that SimplifyCall is
allowed to simplify one side effecting
call to another side effecting call.
As in, you can't make assumptions
about *which* simplifications
SimplifyCall has made. If it returns
a nonnull result, you must use it (or
leave the instruction unmodified). <br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">I
would expect this to be in
isInstructionTriviallyDead
anyways.<br>
</blockquote>
<div><br>
</div>
<div>It would be nice but the
concern is that simplifying such
calls is expensive and
isInstructionTriviallyDead is
called often enough, so negative
impact on compile time is
unavoidable. There are many
transformations, not only
constant folding and their
number will increase, so putting
all of them into
isInstructionTriviallyDead does
not look like a good design.</div>
<div><br>
</div>
<div>Probably it is not a perfect
solution, but it seems that we
have no other solution at the
moment. This problem was
discussed in <a
href="https://reviews.llvm.org/D118426"
rel="noreferrer"
target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">https://reviews.llvm.org/D118426</a> and
in some previous
patch reviews. If you have any
ideas you could continue that
discussion.</div>
<div> </div>
<div>
<div dir="ltr">Thanks,<br>
--Serge<br>
</div>
</div>
<br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On
Thu, May 5, 2022 at 10:00 PM
Philip Reames <<a
href="mailto:listmail@philipreames.com"
target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">listmail@philipreames.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex"><br>
On 5/4/22 22:03, Serge Pavlov
via llvm-commits wrote:<br>
> Author: Serge Pavlov<br>
> Date:
2022-05-05T12:02:42+07:00<br>
> New Revision:
83914ee96fc2d828e1cfb8913f5d156d39150e2c<br>
><br>
> URL: <a
href="https://github.com/llvm/llvm-project/commit/83914ee96fc2d828e1cfb8913f5d156d39150e2c"
rel="noreferrer"
target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">https://github.com/llvm/llvm-project/commit/83914ee96fc2d828e1cfb8913f5d156d39150e2c</a><br>
> DIFF: <a
href="https://github.com/llvm/llvm-project/commit/83914ee96fc2d828e1cfb8913f5d156d39150e2c.diff"
rel="noreferrer"
target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">https://github.com/llvm/llvm-project/commit/83914ee96fc2d828e1cfb8913f5d156d39150e2c.diff</a><br>
><br>
> LOG: [InstCombine] Remove
side effect of replaced
constrained intrinsics<br>
><br>
> If a constrained intrinsic
call was replaced by some value,
it was not<br>
> removed in some cases. The
dangling instruction resulted in
useless<br>
> instructions executed in
runtime. It happened because
constrained<br>
> intrinsics usually have
side effect, it is used to model
the interaction<br>
> with floating-point
environment. In some cases it is
correct behavior<br>
> but often the side effect
is actually absent or can be
ignored.<br>
><br>
> This change adds specific
treatment of constrained
intrinsics so that<br>
> their side effect can be
removed if it actually absents.<br>
><br>
> Differential Revision: <a
href="https://reviews.llvm.org/D118426" rel="noreferrer" target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">https://reviews.llvm.org/D118426</a><br>
><br>
> Added:<br>
>
llvm/test/Transforms/InstCombine/constrained.ll<br>
><br>
> Modified:<br>
>
llvm/include/llvm/Analysis/InstructionSimplify.h<br>
>
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
><br>
> Removed:<br>
> <br>
><br>
><br>
>
################################################################################<br>
> diff --git
a/llvm/include/llvm/Analysis/InstructionSimplify.h
b/llvm/include/llvm/Analysis/InstructionSimplify.h<br>
> index
8f6ed3a6a1928..612a73551f720
100644<br>
> ---
a/llvm/include/llvm/Analysis/InstructionSimplify.h<br>
> +++
b/llvm/include/llvm/Analysis/InstructionSimplify.h<br>
> @@ -299,6 +299,10 @@ Value
*SimplifyBinOp(unsigned Opcode,
Value *LHS, Value *RHS,
FastMathFlags FMF,<br>
>
const SimplifyQuery &Q);<br>
> <br>
> /// Given a callsite,
fold the result or return null.<br>
> +///<br>
> +/// \note A call with
declared side effect may be
simplified into a value<br>
> +/// without such. It
happens if simplification code
deduces that side effect<br>
> +/// is actually absent.<br>
> Value
*SimplifyCall(CallBase *Call,
const SimplifyQuery &Q);<br>
> <br>
> /// Given an operand for
a Freeze, see if we can fold the
result.<br>
><br>
> diff --git
a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
> index
c96919caee2b1..6b2ab24b4b746
100644<br>
> ---
a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
> +++
b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
> @@ -1237,6 +1237,16 @@
Instruction
*InstCombinerImpl::visitCallInst(CallInst
&CI) {<br>
> return NewCall;<br>
> }<br>
> <br>
> + // Unused constrained FP
intrinsic calls may have
declared side effect, which<br>
> + // actually absent. If
SimplifyCall returns a
replacement for such call,<br>
> + // assume side effect is
absent and the call may be
removed.<br>
> + if (CI.use_empty()
&&
isa<ConstrainedFPIntrinsic>(CI))
{<br>
> + if
(SimplifyCall(&CI,
SQ.getWithInstruction(&CI)))
{<br>
> +
eraseInstFromFunction(CI);<br>
> + return nullptr;<br>
> + }<br>
> + }<br>
> +<br>
<br>
This looks incorrect to me.
SimplifyCall returns a Value*
for a <br>
simplified expression and you're
interpreting that as a boolean
meaning <br>
"delete call".<br>
<br>
I would expect this to be in
isInstructionTriviallyDead
anyways.<br>
<br>
Please revert unless I'm
misreading.<br>
<br>
> Intrinsic::ID IID =
II->getIntrinsicID();<br>
> switch (IID) {<br>
> case
Intrinsic::objectsize:<br>
><br>
> diff --git
a/llvm/test/Transforms/InstCombine/constrained.ll
b/llvm/test/Transforms/InstCombine/constrained.ll<br>
> new file mode 100644<br>
> index
0000000000000..b5ef71e6edfba<br>
> --- /dev/null<br>
> +++
b/llvm/test/Transforms/InstCombine/constrained.ll<br>
> @@ -0,0 +1,125 @@<br>
> +; NOTE: Assertions have
been autogenerated by
utils/update_test_checks.py<br>
> +; RUN: opt -S -instcombine
%s | FileCheck %s<br>
> +<br>
> +; Treatment of operation
with unused result.<br>
> +<br>
> +; If operation does not
raise exceptions, it may be
removed even in strict mode.<br>
> +define float
@f_unused_precise() #0 {<br>
> +; CHECK-LABEL:
@f_unused_precise(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT: ret float
1.000000e+00<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fadd.f32(float
1.0, float 1.0, metadata
!"round.upward", metadata
!"fpexcept.strict") #0<br>
> + ret float 1.0<br>
> +}<br>
> +<br>
> +; If operation raises
exceptions, it cannot be removed
in strict mode.<br>
> +define float
@f_unused_strict() #0 {<br>
> +; CHECK-LABEL:
@f_unused_strict(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT:
[[RESULT:%.*]] = call float
@llvm.experimental.constrained.fdiv.f32(float
1.000000e+00, float
3.000000e+00, metadata
!"round.tonearest", metadata
!"fpexcept.strict")
#[[ATTR0:[0-9]+]]<br>
> +; CHECK-NEXT: ret float
1.000000e+00<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fdiv.f32(float
1.0, float 3.0, metadata
!"round.tonearest", metadata
!"fpexcept.strict") #0<br>
> + ret float 1.0<br>
> +}<br>
> +<br>
> +; If operation raises
exceptions, it can be removed in
non-strict mode.<br>
> +define float
@f_unused_ignore() #0 {<br>
> +; CHECK-LABEL:
@f_unused_ignore(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT: ret float
1.000000e+00<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fdiv.f32(float
1.0, float 3.0, metadata
!"round.towardzero", metadata
!"fpexcept.ignore") #0<br>
> + ret float 1.0<br>
> +}<br>
> +<br>
> +; If operation raises
exceptions, it can be removed in
non-strict mode even if rounding
mode is dynamic.<br>
> +define float
@f_unused_dynamic_ignore() #0 {<br>
> +; CHECK-LABEL:
@f_unused_dynamic_ignore(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT: ret float
1.000000e+00<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fdiv.f32(float
1.0, float 3.0, metadata
!"round.dynamic", metadata
!"fpexcept.ignore") #0<br>
> + ret float 1.0<br>
> +}<br>
> +<br>
> +; If operation raises
exceptions, it can be removed in
"maytrap" mode.<br>
> +define float
@f_unused_maytrap() #0 {<br>
> +; CHECK-LABEL:
@f_unused_maytrap(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT: ret float
1.000000e+00<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fdiv.f32(float
1.0, float 3.0, metadata
!"round.tonearest", metadata
!"fpexcept.maytrap") #0<br>
> + ret float 1.0<br>
> +}<br>
> +<br>
> +; Constant evaluation.<br>
> +<br>
> +; If operation does not
raise exceptions, it may be
folded even in strict mode.<br>
> +define float
@f_eval_precise() #0 {<br>
> +; CHECK-LABEL:
@f_eval_precise(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT: ret float
2.000000e+00<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fadd.f32(float
1.0, float 1.0, metadata
!"round.upward", metadata
!"fpexcept.strict") #0<br>
> + ret float %result<br>
> +}<br>
> +<br>
> +; If operation raises
exceptions, it cannot be folded
in strict mode.<br>
> +define float
@f_eval_strict() #0 {<br>
> +; CHECK-LABEL:
@f_eval_strict(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT:
[[RESULT:%.*]] = call float
@llvm.experimental.constrained.fdiv.f32(float
1.000000e+00, float
3.000000e+00, metadata
!"round.upward", metadata
!"fpexcept.strict") #[[ATTR0]]<br>
> +; CHECK-NEXT: ret float
[[RESULT]]<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fdiv.f32(float
1.0, float 3.0, metadata
!"round.upward", metadata
!"fpexcept.strict") #0<br>
> + ret float %result<br>
> +}<br>
> +<br>
> +; If operation raises
exceptions, it can be folded in
non-strict mode.<br>
> +define float
@f_eval_ignore() #0 {<br>
> +; CHECK-LABEL:
@f_eval_ignore(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT: ret float
0x3FD5555540000000<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fdiv.f32(float
1.0, float 3.0, metadata
!"round.downward", metadata
!"fpexcept.ignore") #0<br>
> + ret float %result<br>
> +}<br>
> +<br>
> +; if result is imprecise,
it cannot be folded if rounding
mode is dynamic.<br>
> +define float
@f_eval_dynamic_ignore() #0 {<br>
> +; CHECK-LABEL:
@f_eval_dynamic_ignore(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT:
[[RESULT:%.*]] = call float
@llvm.experimental.constrained.fdiv.f32(float
1.000000e+00, float
3.000000e+00, metadata
!"round.dynamic", metadata
!"fpexcept.ignore") #[[ATTR0]]<br>
> +; CHECK-NEXT: ret float
[[RESULT]]<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fdiv.f32(float
1.0, float 3.0, metadata
!"round.dynamic", metadata
!"fpexcept.ignore") #0<br>
> + ret float %result<br>
> +}<br>
> +<br>
> +; If result is imprecise
and rounding mode is not
dynamic, operation can be folded
in "maytrap" mode.<br>
> +define float
@f_eval_maytrap() #0 {<br>
> +; CHECK-LABEL:
@f_eval_maytrap(<br>
> +; CHECK-NEXT: entry:<br>
> +; CHECK-NEXT: ret float
0x3FD5555560000000<br>
> +;<br>
> +entry:<br>
> + %result = call float
@llvm.experimental.constrained.fdiv.f32(float
1.0, float 3.0, metadata
!"round.tonearest", metadata
!"fpexcept.maytrap") #0<br>
> + ret float %result<br>
> +}<br>
> +<br>
> +<br>
> +declare float
@llvm.experimental.constrained.fadd.f32(float,
float, metadata, metadata)<br>
> +declare float
@llvm.experimental.constrained.fdiv.f32(float,
float, metadata, metadata)<br>
> +<br>
> +attributes #0 = { strictfp
}<br>
><br>
><br>
> <br>
>
_______________________________________________<br>
> llvm-commits mailing list<br>
> <a
href="mailto:llvm-commits@lists.llvm.org"
target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">llvm-commits@lists.llvm.org</a><br>
> <a
href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits"
rel="noreferrer"
target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</blockquote>
</blockquote>
</body>
</html>