Skip to content

Commit 84d8fa3

Browse files
committed
[FPEnv][LegalizeTypes][LegalizeDAG][AArch64] Few fixes/improvements for legalizing fp<->int conversion nodes.
This started with adding a test to support get code coverage on ScalarizeVecOp_UnaryOp_StrictFP by copying an existing AArch64 test and using constrained sitofp/uitofp intrinsics. This found 3 separate issues: -ScalarizeVecOp_UnaryOp_StrictFP needs to do its own replacement because the caller can't handle replacing multiple results. -Missing integer promotion support for sitofp/uitofp -Chain result not always assigned in ExpandLegalINT_TO_FP. Committing them together so I can add the test case.
1 parent be88a20 commit 84d8fa3

File tree

5 files changed

+73
-2
lines changed

5 files changed

+73
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2399,10 +2399,11 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(SDNode *Node,
23992399
if (Node->isStrictFPOpcode()) {
24002400
Sub = DAG.getNode(ISD::STRICT_FSUB, dl, {MVT::f64, MVT::Other},
24012401
{Node->getOperand(0), Load, Bias});
2402+
Chain = Sub.getValue(1);
24022403
if (DestVT != Sub.getValueType()) {
24032404
std::pair<SDValue, SDValue> ResultPair;
24042405
ResultPair =
2405-
DAG.getStrictFPExtendOrRound(Sub, SDValue(Node, 1), dl, DestVT);
2406+
DAG.getStrictFPExtendOrRound(Sub, Chain, dl, DestVT);
24062407
Result = ResultPair.first;
24072408
Chain = ResultPair.second;
24082409
}

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,7 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
12021202
case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break;
12031203
case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break;
12041204
case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break;
1205+
case ISD::STRICT_SINT_TO_FP: Res = PromoteIntOp_STRICT_SINT_TO_FP(N); break;
12051206
case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
12061207
OpNo); break;
12071208
case ISD::MSTORE: Res = PromoteIntOp_MSTORE(cast<MaskedStoreSDNode>(N),
@@ -1215,6 +1216,7 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
12151216
case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break;
12161217
case ISD::FP16_TO_FP:
12171218
case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break;
1219+
case ISD::STRICT_UINT_TO_FP: Res = PromoteIntOp_STRICT_UINT_TO_FP(N); break;
12181220
case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
12191221
case ISD::EXTRACT_SUBVECTOR: Res = PromoteIntOp_EXTRACT_SUBVECTOR(N); break;
12201222

@@ -1491,6 +1493,11 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) {
14911493
SExtPromotedInteger(N->getOperand(0))), 0);
14921494
}
14931495

1496+
SDValue DAGTypeLegalizer::PromoteIntOp_STRICT_SINT_TO_FP(SDNode *N) {
1497+
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
1498+
SExtPromotedInteger(N->getOperand(1))), 0);
1499+
}
1500+
14941501
SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
14951502
assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
14961503
SDValue Ch = N->getChain(), Ptr = N->getBasePtr();
@@ -1590,6 +1597,11 @@ SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
15901597
ZExtPromotedInteger(N->getOperand(0))), 0);
15911598
}
15921599

1600+
SDValue DAGTypeLegalizer::PromoteIntOp_STRICT_UINT_TO_FP(SDNode *N) {
1601+
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
1602+
ZExtPromotedInteger(N->getOperand(1))), 0);
1603+
}
1604+
15931605
SDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
15941606
SDLoc dl(N);
15951607
SDValue Op = GetPromotedInteger(N->getOperand(0));

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,11 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
354354
SDValue PromoteIntOp_Shift(SDNode *N);
355355
SDValue PromoteIntOp_SIGN_EXTEND(SDNode *N);
356356
SDValue PromoteIntOp_SINT_TO_FP(SDNode *N);
357+
SDValue PromoteIntOp_STRICT_SINT_TO_FP(SDNode *N);
357358
SDValue PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo);
358359
SDValue PromoteIntOp_TRUNCATE(SDNode *N);
359360
SDValue PromoteIntOp_UINT_TO_FP(SDNode *N);
361+
SDValue PromoteIntOp_STRICT_UINT_TO_FP(SDNode *N);
360362
SDValue PromoteIntOp_ZERO_EXTEND(SDNode *N);
361363
SDValue PromoteIntOp_MSTORE(MaskedStoreSDNode *N, unsigned OpNo);
362364
SDValue PromoteIntOp_MLOAD(MaskedLoadSDNode *N, unsigned OpNo);

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,12 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(SDNode *N) {
667667
ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
668668
// Revectorize the result so the types line up with what the uses of this
669669
// expression expect.
670-
return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
670+
Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
671+
672+
// Do our own replacement and return SDValue() to tell the caller that we
673+
// handled all replacements since caller can only handle a single result.
674+
ReplaceValueWith(SDValue(N, 0), Res);
675+
return SDValue();
671676
}
672677

673678
/// The vectors to concatenate have length one - use a BUILD_VECTOR instead.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=aarch64-apple-darwin | FileCheck %s
3+
4+
; Check that the legalizer doesn't crash when scalarizing FP conversion
5+
; instructions' operands. The operands are all illegal on AArch64,
6+
; ensuring they are legalized. The results are all legal.
7+
8+
define <1 x double> @test_sitofp(<1 x i1> %in) #0 {
9+
; CHECK-LABEL: test_sitofp:
10+
; CHECK: ; %bb.0: ; %entry
11+
; CHECK-NEXT: sub sp, sp, #16 ; =16
12+
; CHECK-NEXT: .cfi_def_cfa_offset 16
13+
; CHECK-NEXT: sbfx w8, w0, #0, #1
14+
; CHECK-NEXT: mov w9, #1127219200
15+
; CHECK-NEXT: eor w8, w8, #0x80000000
16+
; CHECK-NEXT: stp w8, w9, [sp, #8]
17+
; CHECK-NEXT: ldr d0, [sp, #8]
18+
; CHECK-NEXT: mov x8, #2147483648
19+
; CHECK-NEXT: movk x8, #17200, lsl #48
20+
; CHECK-NEXT: fmov d1, x8
21+
; CHECK-NEXT: fsub d0, d0, d1
22+
; CHECK-NEXT: add sp, sp, #16 ; =16
23+
; CHECK-NEXT: ret
24+
entry:
25+
%0 = call <1 x double> @llvm.experimental.constrained.sitofp.v1f64.v1i1(<1 x i1> %in, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
26+
ret <1 x double> %0
27+
}
28+
29+
define <1 x double> @test_uitofp(<1 x i1> %in) #0 {
30+
; CHECK-LABEL: test_uitofp:
31+
; CHECK: ; %bb.0: ; %entry
32+
; CHECK-NEXT: sub sp, sp, #16 ; =16
33+
; CHECK-NEXT: .cfi_def_cfa_offset 16
34+
; CHECK-NEXT: and w8, w0, #0x1
35+
; CHECK-NEXT: mov w9, #1127219200
36+
; CHECK-NEXT: stp w8, w9, [sp, #8]
37+
; CHECK-NEXT: ldr d0, [sp, #8]
38+
; CHECK-NEXT: mov x8, #4841369599423283200
39+
; CHECK-NEXT: fmov d1, x8
40+
; CHECK-NEXT: fsub d0, d0, d1
41+
; CHECK-NEXT: add sp, sp, #16 ; =16
42+
; CHECK-NEXT: ret
43+
entry:
44+
%0 = call <1 x double> @llvm.experimental.constrained.uitofp.v1f64.v1i1(<1 x i1> %in, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
45+
ret <1 x double> %0
46+
}
47+
48+
attributes #0 = { strictfp }
49+
50+
declare <1 x double> @llvm.experimental.constrained.sitofp.v1f64.v1i1(<1 x i1>, metadata, metadata)
51+
declare <1 x double> @llvm.experimental.constrained.uitofp.v1f64.v1i1(<1 x i1>, metadata, metadata)

0 commit comments

Comments
 (0)