Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6333679

Browse filesBrowse files
committed
[FPEnv] Default NoFPExcept SDNodeFlag to false
The NoFPExcept bit in SDNodeFlags currently defaults to true, unlike all other such flags. This is a problem, because it implies that all code that transforms SDNodes without copying flags can introduce a correctness bug, not just a missed optimization. This patch changes the default to false. This makes it necessary to move setting the (No)FPExcept flag for constrained intrinsics from the visitConstrainedIntrinsic routine to the generic visit routine at the place where the other flags are set, or else the intersectFlagsWith call would erase the NoFPExcept flag again. In order to avoid making non-strict FP code worse, whenever SelectionDAGISel::SelectCodeCommon matches on a set of orignal nodes none of which can raise FP exceptions, it will preserve this property on all results nodes generated, by setting the NoFPExcept flag on those result nodes that would otherwise be considered as raising an FP exception. To check whether or not an SD node should be considered as raising an FP exception, the following logic applies: - For machine nodes, check the mayRaiseFPException property of the underlying MI instruction - For regular nodes, check isStrictFPOpcode - For target nodes, check a newly introduced isTargetStrictFPOpcode The latter is implemented by reserving a range of target opcodes, similarly to how memory opcodes are identified. (Note that there a bit of a quirk in identifying target nodes that are both memory nodes and strict FP nodes. To simplify the logic, right now all target memory nodes are automatically also considered strict FP nodes -- this could be fixed by adding one more range.) Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D71841
1 parent 24ab9b5 commit 6333679
Copy full SHA for 6333679
Expand file treeCollapse file tree

13 files changed

+126
-46
lines changed

‎llvm/include/llvm/CodeGen/ISDOpcodes.h

Copy file name to clipboardExpand all lines: llvm/include/llvm/CodeGen/ISDOpcodes.h
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,11 +937,16 @@ namespace ISD {
937937
BUILTIN_OP_END
938938
};
939939

940+
/// FIRST_TARGET_STRICTFP_OPCODE - Target-specific pre-isel operations
941+
/// which cannot raise FP exceptions should be less than this value.
942+
/// Those that do must not be less than this value.
943+
static const int FIRST_TARGET_STRICTFP_OPCODE = BUILTIN_OP_END+400;
944+
940945
/// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
941946
/// which do not reference a specific memory location should be less than
942947
/// this value. Those that do must not be less than this value, and can
943948
/// be used with SelectionDAG::getMemIntrinsicNode.
944-
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+400;
949+
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+500;
945950

946951
//===--------------------------------------------------------------------===//
947952
/// MemIndexedMode enum - This enum defines the load / store indexed

‎llvm/include/llvm/CodeGen/SelectionDAGISel.h

Copy file name to clipboardExpand all lines: llvm/include/llvm/CodeGen/SelectionDAGISel.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ class SelectionDAGISel : public MachineFunctionPass {
310310
return false;
311311
}
312312

313+
/// Return whether the node may raise an FP exception.
314+
bool mayRaiseFPException(SDNode *Node) const;
315+
313316
bool isOrEquivalentToAdd(const SDNode *N) const;
314317

315318
private:

‎llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Copy file name to clipboardExpand all lines: llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+13-4Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ struct SDNodeFlags {
387387
Exact(false), NoNaNs(false), NoInfs(false),
388388
NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false),
389389
AllowContract(false), ApproximateFuncs(false),
390-
AllowReassociation(false), NoFPExcept(true) {}
390+
AllowReassociation(false), NoFPExcept(false) {}
391391

392392
/// Propagate the fast-math-flags from an IR FPMathOperator.
393393
void copyFMF(const FPMathOperator &FPMO) {
@@ -450,9 +450,9 @@ struct SDNodeFlags {
450450
setDefined();
451451
AllowReassociation = b;
452452
}
453-
void setFPExcept(bool b) {
453+
void setNoFPExcept(bool b) {
454454
setDefined();
455-
NoFPExcept = !b;
455+
NoFPExcept = b;
456456
}
457457

458458
// These are accessors for each flag.
@@ -467,7 +467,7 @@ struct SDNodeFlags {
467467
bool hasAllowContract() const { return AllowContract; }
468468
bool hasApproximateFuncs() const { return ApproximateFuncs; }
469469
bool hasAllowReassociation() const { return AllowReassociation; }
470-
bool hasFPExcept() const { return !NoFPExcept; }
470+
bool hasNoFPExcept() const { return NoFPExcept; }
471471

472472
bool isFast() const {
473473
return NoSignedZeros && AllowReciprocal && NoNaNs && NoInfs && NoFPExcept &&
@@ -666,6 +666,15 @@ END_TWO_BYTE_PACK()
666666
/// \<target\>ISD namespace).
667667
bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
668668

669+
/// Test if this node has a target-specific opcode that may raise
670+
/// FP exceptions (in the \<target\>ISD namespace and greater than
671+
/// FIRST_TARGET_STRICTFP_OPCODE). Note that all target memory
672+
/// opcode are currently automatically considered to possibly raise
673+
/// FP exceptions as well.
674+
bool isTargetStrictFPOpcode() const {
675+
return NodeType >= ISD::FIRST_TARGET_STRICTFP_OPCODE;
676+
}
677+
669678
/// Test if this node has a target-specific
670679
/// memory-referencing opcode (in the \<target\>ISD namespace and
671680
/// greater than FIRST_TARGET_MEMORY_OPCODE).

‎llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp

Copy file name to clipboardExpand all lines: llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
882882
if (Flags.hasExact())
883883
MI->setFlag(MachineInstr::MIFlag::IsExact);
884884

885-
if (Flags.hasFPExcept())
885+
if (MI->getDesc().mayRaiseFPException() && !Flags.hasNoFPExcept())
886886
MI->setFlag(MachineInstr::MIFlag::FPExcept);
887887
}
888888

‎llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Copy file name to clipboardExpand all lines: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+9-6Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,15 @@ void SelectionDAGBuilder::visit(const Instruction &I) {
11081108
Node->intersectFlagsWith(IncomingFlags);
11091109
}
11101110
}
1111+
// Constrained FP intrinsics with fpexcept.ignore should also get
1112+
// the NoFPExcept flag.
1113+
if (auto *FPI = dyn_cast<ConstrainedFPIntrinsic>(&I))
1114+
if (FPI->getExceptionBehavior() == fp::ExceptionBehavior::ebIgnore)
1115+
if (SDNode *Node = getNodeForIRValue(&I)) {
1116+
SDNodeFlags Flags = Node->getFlags();
1117+
Flags.setNoFPExcept(true);
1118+
Node->setFlags(Flags);
1119+
}
11111120

11121121
if (!I.isTerminator() && !HasTailCall &&
11131122
!isStatepoint(&I)) // statepoints handle their exports internally
@@ -6972,12 +6981,6 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
69726981
SDVTList VTs = DAG.getVTList(ValueVTs);
69736982
SDValue Result = DAG.getNode(Opcode, sdl, VTs, Opers);
69746983

6975-
if (FPI.getExceptionBehavior() != fp::ExceptionBehavior::ebIgnore) {
6976-
SDNodeFlags Flags;
6977-
Flags.setFPExcept(true);
6978-
Result->setFlags(Flags);
6979-
}
6980-
69816984
assert(Result.getNode()->getNumValues() == 2);
69826985
// See above -- chain is handled like for loads here.
69836986
SDValue OutChain = Result.getValue(1);

‎llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

Copy file name to clipboardExpand all lines: llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,8 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
547547
if (getFlags().hasVectorReduction())
548548
OS << " vector-reduction";
549549

550-
if (getFlags().hasFPExcept())
551-
OS << " fpexcept";
550+
if (getFlags().hasNoFPExcept())
551+
OS << " nofpexcept";
552552

553553
if (const MachineSDNode *MN = dyn_cast<MachineSDNode>(this)) {
554554
if (!MN->memoperands_empty()) {

‎llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Copy file name to clipboardExpand all lines: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3458,6 +3458,17 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
34583458
if ((EmitNodeInfo & OPFL_GlueInput) && InputGlue.getNode() != nullptr)
34593459
Ops.push_back(InputGlue);
34603460

3461+
// Check whether any matched node could raise an FP exception. Since all
3462+
// such nodes must have a chain, it suffices to check ChainNodesMatched.
3463+
// We need to perform this check before potentially modifying one of the
3464+
// nodes via MorphNode.
3465+
bool MayRaiseFPException = false;
3466+
for (auto *N : ChainNodesMatched)
3467+
if (mayRaiseFPException(N) && !N->getFlags().hasNoFPExcept()) {
3468+
MayRaiseFPException = true;
3469+
break;
3470+
}
3471+
34613472
// Create the node.
34623473
MachineSDNode *Res = nullptr;
34633474
bool IsMorphNodeTo = Opcode == OPC_MorphNodeTo ||
@@ -3489,6 +3500,14 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
34893500
Ops, EmitNodeInfo));
34903501
}
34913502

3503+
// Set the NoFPExcept flag when no original matched node could
3504+
// raise an FP exception, but the new node potentially might.
3505+
if (!MayRaiseFPException && mayRaiseFPException(Res)) {
3506+
SDNodeFlags Flags = Res->getFlags();
3507+
Flags.setNoFPExcept(true);
3508+
Res->setFlags(Flags);
3509+
}
3510+
34923511
// If the node had chain/glue results, update our notion of the current
34933512
// chain and glue.
34943513
if (EmitNodeInfo & OPFL_GlueOutput) {
@@ -3644,6 +3663,21 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
36443663
}
36453664
}
36463665

3666+
/// Return whether the node may raise an FP exception.
3667+
bool SelectionDAGISel::mayRaiseFPException(SDNode *N) const {
3668+
// For machine opcodes, consult the MCID flag.
3669+
if (N->isMachineOpcode()) {
3670+
const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
3671+
return MCID.mayRaiseFPException();
3672+
}
3673+
3674+
// For ISD opcodes, only StrictFP opcodes may raise an FP
3675+
// exception.
3676+
if (N->isTargetOpcode())
3677+
return N->isTargetStrictFPOpcode();
3678+
return N->isStrictFPOpcode();
3679+
}
3680+
36473681
bool SelectionDAGISel::isOrEquivalentToAdd(const SDNode *N) const {
36483682
assert(N->getOpcode() == ISD::OR && "Unexpected opcode");
36493683
auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1));

‎llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Copy file name to clipboardExpand all lines: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6190,8 +6190,10 @@ bool TargetLowering::expandUINT_TO_FP(SDNode *Node, SDValue &Result,
61906190
// incoming STRICT_UINT_TO_FP node; the STRICT_FADD node can
61916191
// never raise any exception.
61926192
SDNodeFlags Flags;
6193-
Flags.setFPExcept(Node->getFlags().hasFPExcept());
6193+
Flags.setNoFPExcept(Node->getFlags().hasNoFPExcept());
61946194
Fast->setFlags(Flags);
6195+
Flags.setNoFPExcept(true);
6196+
Slow->setFlags(Flags);
61956197
} else {
61966198
SDValue SignCvt = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Or);
61976199
Slow = DAG.getNode(ISD::FADD, dl, DstVT, SignCvt, SignCvt);

‎llvm/lib/Target/SystemZ/SystemZISelLowering.h

Copy file name to clipboardExpand all lines: llvm/lib/Target/SystemZ/SystemZISelLowering.h
+26-10Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ enum NodeType : unsigned {
5858
ICMP,
5959

6060
// Floating-point comparisons. The two operands are the values to compare.
61-
// Regular and strict (quiet and signaling) versions.
62-
FCMP, STRICT_FCMP, STRICT_FCMPS,
61+
FCMP,
6362

6463
// Test under mask. The first operand is ANDed with the second operand
6564
// and the condition codes are set on the result. The third operand is
@@ -249,10 +248,9 @@ enum NodeType : unsigned {
249248
// Compare floating-point vector operands 0 and 1 to produce the usual 0/-1
250249
// vector result. VFCMPE is for "ordered and equal", VFCMPH for "ordered and
251250
// greater than" and VFCMPHE for "ordered and greater than or equal to".
252-
// Regular and strict (quiet and signaling) versions.
253-
VFCMPE, STRICT_VFCMPE, STRICT_VFCMPES,
254-
VFCMPH, STRICT_VFCMPH, STRICT_VFCMPHS,
255-
VFCMPHE, STRICT_VFCMPHE, STRICT_VFCMPHES,
251+
VFCMPE,
252+
VFCMPH,
253+
VFCMPHE,
256254

257255
// Likewise, but also set the condition codes on the result.
258256
VFCMPES,
@@ -263,12 +261,12 @@ enum NodeType : unsigned {
263261
VFTCI,
264262

265263
// Extend the even f32 elements of vector operand 0 to produce a vector
266-
// of f64 elements. Regular and strict versions.
267-
VEXTEND, STRICT_VEXTEND,
264+
// of f64 elements.
265+
VEXTEND,
268266

269267
// Round the f64 elements of vector operand 0 to f32s and store them in the
270-
// even elements of the result. Regular and strict versions.
271-
VROUND, STRICT_VROUND,
268+
// even elements of the result.
269+
VROUND,
272270

273271
// AND the two vector operands together and set CC based on the result.
274272
VTM,
@@ -292,6 +290,24 @@ enum NodeType : unsigned {
292290
// Operand 1: the bit mask
293291
TDC,
294292

293+
// Strict variants of scalar floating-point comparisons.
294+
// Quiet and signaling versions.
295+
STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
296+
STRICT_FCMPS,
297+
298+
// Strict variants of vector floating-point comparisons.
299+
// Quiet and signaling versions.
300+
STRICT_VFCMPE,
301+
STRICT_VFCMPH,
302+
STRICT_VFCMPHE,
303+
STRICT_VFCMPES,
304+
STRICT_VFCMPHS,
305+
STRICT_VFCMPHES,
306+
307+
// Strict variants of VEXTEND and VROUND.
308+
STRICT_VEXTEND,
309+
STRICT_VROUND,
310+
295311
// Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
296312
// ATOMIC_LOAD_<op>.
297313
//

‎llvm/lib/Target/X86/X86ISelLowering.h

Copy file name to clipboardExpand all lines: llvm/lib/Target/X86/X86ISelLowering.h
+14-6Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,6 @@ namespace llvm {
7979
/// X86 compare and logical compare instructions.
8080
CMP, COMI, UCOMI,
8181

82-
/// X86 strict FP compare instructions.
83-
STRICT_FCMP, STRICT_FCMPS,
84-
8582
/// X86 bit-test instructions.
8683
BT,
8784

@@ -325,7 +322,6 @@ namespace llvm {
325322

326323
// Vector packed double/float comparison.
327324
CMPP,
328-
STRICT_CMPP,
329325

330326
// Vector integer comparisons.
331327
PCMPEQ, PCMPGT,
@@ -338,7 +334,6 @@ namespace llvm {
338334
/// Vector comparison generating mask bits for fp and
339335
/// integer signed and unsigned data types.
340336
CMPM,
341-
STRICT_CMPM,
342337
// Vector comparison with SAE for FP values
343338
CMPM_SAE,
344339

@@ -506,7 +501,6 @@ namespace llvm {
506501

507502
// Vector float/double to signed/unsigned integer with truncation.
508503
CVTTP2SI, CVTTP2UI, CVTTP2SI_SAE, CVTTP2UI_SAE,
509-
STRICT_CVTTP2SI, STRICT_CVTTP2UI,
510504
// Scalar float/double to signed/unsigned integer with truncation.
511505
CVTTS2SI, CVTTS2UI, CVTTS2SI_SAE, CVTTS2UI_SAE,
512506

@@ -605,6 +599,20 @@ namespace llvm {
605599
// For avx512-vp2intersect
606600
VP2INTERSECT,
607601

602+
/// X86 strict FP compare instructions.
603+
STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
604+
STRICT_FCMPS,
605+
606+
// Vector packed double/float comparison.
607+
STRICT_CMPP,
608+
609+
/// Vector comparison generating mask bits for fp and
610+
/// integer signed and unsigned data types.
611+
STRICT_CMPM,
612+
613+
// Vector float/double to signed/unsigned integer with truncation.
614+
STRICT_CVTTP2SI, STRICT_CVTTP2UI,
615+
608616
// Compare and swap.
609617
LCMPXCHG_DAG = ISD::FIRST_TARGET_MEMORY_OPCODE,
610618
LCMPXCHG8_DAG,

‎llvm/test/CodeGen/X86/fp-intrinsics-flags-x86_64.ll

Copy file name to clipboardExpand all lines: llvm/test/CodeGen/X86/fp-intrinsics-flags-x86_64.ll
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ define i32 @f20u(double %x) #0 {
44
; CHECK-LABEL: name: f20u
55
; CHECK: liveins: $xmm0
66
; CHECK: [[COPY:%[0-9]+]]:fr64 = COPY $xmm0
7-
; CHECK: [[CVTTSD2SI64rr:%[0-9]+]]:gr64 = CVTTSD2SI64rr [[COPY]], implicit $mxcsr
7+
; CHECK: [[CVTTSD2SI64rr:%[0-9]+]]:gr64 = fpexcept CVTTSD2SI64rr [[COPY]], implicit $mxcsr
88
; CHECK: [[COPY1:%[0-9]+]]:gr32 = COPY [[CVTTSD2SI64rr]].sub_32bit
99
; CHECK: $eax = COPY [[COPY1]]
1010
; CHECK: RET 0, $eax

‎llvm/test/CodeGen/X86/fp-intrinsics-flags.ll

Copy file name to clipboardExpand all lines: llvm/test/CodeGen/X86/fp-intrinsics-flags.ll
+8-8Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ entry:
2929
; CHECK-LABEL: name: f20u64
3030
; CHECK: [[MOVSDrm_alt:%[0-9]+]]:fr64 = MOVSDrm_alt %fixed-stack.0, 1, $noreg, 0, $noreg :: (load 8 from %fixed-stack.0, align 16)
3131
; CHECK: [[MOVSDrm_alt1:%[0-9]+]]:fr64 = MOVSDrm_alt $noreg, 1, $noreg, %const.0, $noreg :: (load 8 from constant-pool)
32-
; CHECK: COMISDrr [[MOVSDrm_alt1]], [[MOVSDrm_alt]], implicit-def $eflags, implicit $mxcsr
32+
; CHECK: fpexcept COMISDrr [[MOVSDrm_alt1]], [[MOVSDrm_alt]], implicit-def $eflags, implicit $mxcsr
3333
; CHECK: [[FsFLD0SD:%[0-9]+]]:fr64 = FsFLD0SD
3434
; CHECK: JCC_1
3535
; CHECK: [[PHI:%[0-9]+]]:fr64 = PHI [[MOVSDrm_alt1]], {{.*}}, [[FsFLD0SD]], {{.*}}
36-
; CHECK: [[SUBSDrr:%[0-9]+]]:fr64 = SUBSDrr [[MOVSDrm_alt]], killed [[PHI]], implicit $mxcsr
36+
; CHECK: [[SUBSDrr:%[0-9]+]]:fr64 = fpexcept SUBSDrr [[MOVSDrm_alt]], killed [[PHI]], implicit $mxcsr
3737
; CHECK: MOVSDmr %stack.0, 1, $noreg, 0, $noreg, killed [[SUBSDrr]] :: (store 8 into %stack.0)
3838
; CHECK: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 6, implicit $eflags
39-
; CHECK: [[LD_Fp64m:%[0-9]+]]:rfp64 = LD_Fp64m %stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load 8 from %stack.0)
39+
; CHECK: [[LD_Fp64m:%[0-9]+]]:rfp64 = fpexcept LD_Fp64m %stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load 8 from %stack.0)
4040
; CHECK: FNSTCW16m %stack.1, 1, $noreg, 0, $noreg, implicit-def $fpsw, implicit $fpcw :: (store 2 into %stack.1)
4141
; CHECK: [[MOVZX32rm16_:%[0-9]+]]:gr32 = MOVZX32rm16 %stack.1, 1, $noreg, 0, $noreg :: (load 2 from %stack.1)
4242
; CHECK: [[OR32ri:%[0-9]+]]:gr32 = OR32ri killed [[MOVZX32rm16_]], 3072, implicit-def $eflags
@@ -59,7 +59,7 @@ entry:
5959
define i8 @f20s8(double %x) #0 {
6060
entry:
6161
; CHECK-LABEL: name: f20s8
62-
; CHECK: [[CVTTSD2SIrm:%[0-9]+]]:gr32 = CVTTSD2SIrm %fixed-stack.0, 1, $noreg, 0, $noreg, implicit $mxcsr :: (load 8 from %fixed-stack.0, align 16)
62+
; CHECK: [[CVTTSD2SIrm:%[0-9]+]]:gr32 = fpexcept CVTTSD2SIrm %fixed-stack.0, 1, $noreg, 0, $noreg, implicit $mxcsr :: (load 8 from %fixed-stack.0, align 16)
6363
; CHECK: [[COPY:%[0-9]+]]:gr32_abcd = COPY [[CVTTSD2SIrm]]
6464
; CHECK: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
6565
; CHECK: $al = COPY [[COPY1]]
@@ -71,7 +71,7 @@ entry:
7171
define i16 @f20s16(double %x) #0 {
7272
entry:
7373
; CHECK-LABEL: name: f20s16
74-
; CHECK: [[CVTTSD2SIrm:%[0-9]+]]:gr32 = CVTTSD2SIrm %fixed-stack.0, 1, $noreg, 0, $noreg, implicit $mxcsr :: (load 8 from %fixed-stack.0, align 16)
74+
; CHECK: [[CVTTSD2SIrm:%[0-9]+]]:gr32 = fpexcept CVTTSD2SIrm %fixed-stack.0, 1, $noreg, 0, $noreg, implicit $mxcsr :: (load 8 from %fixed-stack.0, align 16)
7575
; CHECK: [[COPY:%[0-9]+]]:gr16 = COPY [[CVTTSD2SIrm]].sub_16bit
7676
; CHECK: $ax = COPY [[COPY]]
7777
; CHECK: RET 0, $ax
@@ -84,15 +84,15 @@ entry:
8484
; CHECK-LABEL: name: f20u
8585
; CHECK: [[MOVSDrm_alt:%[0-9]+]]:fr64 = MOVSDrm_alt %fixed-stack.0, 1, $noreg, 0, $noreg :: (load 8 from %fixed-stack.0, align 16)
8686
; CHECK: [[MOVSDrm_alt1:%[0-9]+]]:fr64 = MOVSDrm_alt $noreg, 1, $noreg, %const.0, $noreg :: (load 8 from constant-pool)
87-
; CHECK: COMISDrr [[MOVSDrm_alt1]], [[MOVSDrm_alt]], implicit-def $eflags, implicit $mxcsr
87+
; CHECK: fpexcept COMISDrr [[MOVSDrm_alt1]], [[MOVSDrm_alt]], implicit-def $eflags, implicit $mxcsr
8888
; CHECK: [[FsFLD0SD:%[0-9]+]]:fr64 = FsFLD0SD
8989
; CHECK: JCC_1
9090
; CHECK: [[PHI:%[0-9]+]]:fr64 = PHI [[MOVSDrm_alt1]], {{.*}}, [[FsFLD0SD]], {{.*}}
9191
; CHECK: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 6, implicit $eflags
9292
; CHECK: [[MOVZX32rr8_:%[0-9]+]]:gr32 = MOVZX32rr8 killed [[SETCCr]]
9393
; CHECK: [[SHL32ri:%[0-9]+]]:gr32 = SHL32ri [[MOVZX32rr8_]], 31, implicit-def dead $eflags
94-
; CHECK: [[SUBSDrr:%[0-9]+]]:fr64 = SUBSDrr [[MOVSDrm_alt]], killed [[PHI]], implicit $mxcsr
95-
; CHECK: [[CVTTSD2SIrr:%[0-9]+]]:gr32 = CVTTSD2SIrr killed [[SUBSDrr]], implicit $mxcsr
94+
; CHECK: [[SUBSDrr:%[0-9]+]]:fr64 = fpexcept SUBSDrr [[MOVSDrm_alt]], killed [[PHI]], implicit $mxcsr
95+
; CHECK: [[CVTTSD2SIrr:%[0-9]+]]:gr32 = fpexcept CVTTSD2SIrr killed [[SUBSDrr]], implicit $mxcsr
9696
; CHECK: [[XOR32rr:%[0-9]+]]:gr32 = XOR32rr [[CVTTSD2SIrr]], killed [[SHL32ri]], implicit-def dead $eflags
9797
; CHECK: $eax = COPY [[XOR32rr]]
9898
; CHECK: RET 0, $eax

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.