Skip to content

Commit b4f1994

Browse files
authored
DAG: Add AssertNoFPClass from call return attributes (#167264)
This defends against regressions in future patches. This excludes the target intrinsic case for now; I'm worried introducing an intermediate AssertNoFPClass is likely to break combines.
1 parent 20a22a4 commit b4f1994

File tree

3 files changed

+25
-12
lines changed

3 files changed

+25
-12
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4638,6 +4638,12 @@ static std::optional<ConstantRange> getRange(const Instruction &I) {
46384638
return std::nullopt;
46394639
}
46404640

4641+
static FPClassTest getNoFPClass(const Instruction &I) {
4642+
if (const auto *CB = dyn_cast<CallBase>(&I))
4643+
return CB->getRetNoFPClass();
4644+
return fcNone;
4645+
}
4646+
46414647
void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
46424648
if (I.isAtomic())
46434649
return visitAtomicLoad(I);
@@ -9132,6 +9138,7 @@ void SelectionDAGBuilder::LowerCallTo(const CallBase &CB, SDValue Callee,
91329138

91339139
if (Result.first.getNode()) {
91349140
Result.first = lowerRangeToAssertZExt(DAG, CB, Result.first);
9141+
Result.first = lowerNoFPClassToAssertNoFPClass(DAG, CB, Result.first);
91359142
setValue(&CB, Result.first);
91369143
}
91379144

@@ -10718,6 +10725,16 @@ SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
1071810725
return DAG.getMergeValues(Ops, SL);
1071910726
}
1072010727

10728+
SDValue SelectionDAGBuilder::lowerNoFPClassToAssertNoFPClass(
10729+
SelectionDAG &DAG, const Instruction &I, SDValue Op) {
10730+
FPClassTest Classes = getNoFPClass(I);
10731+
if (Classes == fcNone)
10732+
return Op;
10733+
10734+
return DAG.getNode(ISD::AssertNoFPClass, SDLoc(Op), Op.getValueType(), Op,
10735+
DAG.getTargetConstant(Classes, SDLoc(), MVT::i32));
10736+
}
10737+
1072110738
/// Populate a CallLowerinInfo (into \p CLI) based on the properties of
1072210739
/// the call being lowered.
1072310740
///

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,10 @@ class SelectionDAGBuilder {
429429
SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I,
430430
SDValue Op);
431431

432+
// Lower nofpclass attributes to AssertNoFPClass
433+
SDValue lowerNoFPClassToAssertNoFPClass(SelectionDAG &DAG,
434+
const Instruction &I, SDValue Op);
435+
432436
void populateCallLoweringInfo(TargetLowering::CallLoweringInfo &CLI,
433437
const CallBase *Call, unsigned ArgIdx,
434438
unsigned NumArgs, SDValue Callee,

llvm/test/CodeGen/AMDGPU/nofpclass-call.ll

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ define float @call_nofpclass_funcs_f32(ptr addrspace(1) %ptr) {
3535
; CHECK-NEXT: v_mov_b32_e32 v3, v0
3636
; CHECK-NEXT: v_mov_b32_e32 v0, v2
3737
; CHECK-NEXT: s_swappc_b64 s[30:31], s[16:17]
38-
; CHECK-NEXT: v_max_f32_e32 v1, v3, v3
39-
; CHECK-NEXT: v_max_f32_e32 v0, v0, v0
40-
; CHECK-NEXT: v_min_f32_e32 v0, v1, v0
38+
; CHECK-NEXT: v_min_f32_e32 v0, v3, v0
4139
; CHECK-NEXT: v_readlane_b32 s31, v4, 1
4240
; CHECK-NEXT: v_readlane_b32 s30, v4, 0
4341
; CHECK-NEXT: s_mov_b32 s32, s33
@@ -87,12 +85,8 @@ define <2 x float> @call_nofpclass_funcs_v2f32(ptr addrspace(1) %ptr) {
8785
; CHECK-NEXT: v_mov_b32_e32 v0, v3
8886
; CHECK-NEXT: v_mov_b32_e32 v1, v2
8987
; CHECK-NEXT: s_swappc_b64 s[30:31], s[16:17]
90-
; CHECK-NEXT: v_max_f32_e32 v2, v4, v4
91-
; CHECK-NEXT: v_max_f32_e32 v0, v0, v0
92-
; CHECK-NEXT: v_min_f32_e32 v0, v2, v0
93-
; CHECK-NEXT: v_max_f32_e32 v2, v5, v5
94-
; CHECK-NEXT: v_max_f32_e32 v1, v1, v1
95-
; CHECK-NEXT: v_min_f32_e32 v1, v2, v1
88+
; CHECK-NEXT: v_min_f32_e32 v0, v4, v0
89+
; CHECK-NEXT: v_min_f32_e32 v1, v5, v1
9690
; CHECK-NEXT: v_readlane_b32 s31, v6, 1
9791
; CHECK-NEXT: v_readlane_b32 s30, v6, 0
9892
; CHECK-NEXT: s_mov_b32 s32, s33
@@ -142,12 +136,10 @@ define double @call_nofpclass_funcs_f64(ptr addrspace(1) %ptr) {
142136
; CHECK-NEXT: v_mov_b32_e32 v0, v5
143137
; CHECK-NEXT: v_mov_b32_e32 v1, v4
144138
; CHECK-NEXT: s_swappc_b64 s[30:31], s[16:17]
145-
; CHECK-NEXT: v_max_f64 v[2:3], v[2:3], v[2:3]
146-
; CHECK-NEXT: v_max_f64 v[0:1], v[0:1], v[0:1]
139+
; CHECK-NEXT: v_min_f64 v[0:1], v[2:3], v[0:1]
147140
; CHECK-NEXT: v_readlane_b32 s31, v6, 1
148141
; CHECK-NEXT: v_readlane_b32 s30, v6, 0
149142
; CHECK-NEXT: s_mov_b32 s32, s33
150-
; CHECK-NEXT: v_min_f64 v[0:1], v[2:3], v[0:1]
151143
; CHECK-NEXT: s_xor_saveexec_b64 s[4:5], -1
152144
; CHECK-NEXT: buffer_load_dword v6, off, s[0:3], s33 ; 4-byte Folded Reload
153145
; CHECK-NEXT: s_mov_b64 exec, s[4:5]

0 commit comments

Comments
 (0)