Skip to content

Commit 2df2373

Browse files
authored
DAG/GlobalISel: Set disjoint for or in copysign lowering (#97057)
We masked out the sign bit from one value, and the non-sign bits from the other so there should be no common bits set. No idea how to test this on the DAG path, other than scraping the debug logs. A few targets hit this path with f16 values, but the resulting i16 ors get anyext promoted and lose the disjoint flag. In the fp128 case, PPC gets further and the or loses the flag somewhere else later. Adding a haveNoCommonBits assert shows this works though.
1 parent a9c12e4 commit 2df2373

File tree

5 files changed

+248
-239
lines changed

5 files changed

+248
-239
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7210,6 +7210,10 @@ LegalizerHelper::lowerFCopySign(MachineInstr &MI) {
72107210
// constants are a nan and -0.0, but the final result should preserve
72117211
// everything.
72127212
unsigned Flags = MI.getFlags();
7213+
7214+
// We masked the sign bit and the not-sign bit, so these are disjoint.
7215+
Flags |= MachineInstr::Disjoint;
7216+
72137217
MIRBuilder.buildOr(Dst, And0, And1, Flags);
72147218

72157219
MI.eraseFromParent();

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1681,8 +1681,13 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
16811681
SignBit = DAG.getNode(ISD::TRUNCATE, DL, MagVT, SignBit);
16821682
}
16831683

1684+
SDNodeFlags Flags;
1685+
Flags.setDisjoint(true);
1686+
16841687
// Store the part with the modified sign and convert back to float.
1685-
SDValue CopiedSign = DAG.getNode(ISD::OR, DL, MagVT, ClearedSign, SignBit);
1688+
SDValue CopiedSign =
1689+
DAG.getNode(ISD::OR, DL, MagVT, ClearedSign, SignBit, Flags);
1690+
16861691
return modifySignAsInt(MagAsInt, DL, CopiedSign);
16871692
}
16881693

llvm/test/CodeGen/AArch64/GlobalISel/legalize-fcopysign.mir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ body: |
2222
; CHECK-NEXT: [[BUILD_VECTOR3:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C1]](s32)
2323
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s32>) = G_AND [[BUILD_VECTOR]], [[BUILD_VECTOR3]]
2424
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[BUILD_VECTOR1]], [[BUILD_VECTOR2]]
25-
; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s32>) = G_OR [[AND]], [[AND1]]
26-
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[OR]](<2 x s32>)
25+
; CHECK-NEXT: %6:_(<2 x s32>) = disjoint G_OR [[AND]], [[AND1]]
26+
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %6(<2 x s32>)
2727
; CHECK-NEXT: %fcopysign:_(s32) = COPY [[UV]](s32)
2828
; CHECK-NEXT: $s0 = COPY %fcopysign(s32)
2929
; CHECK-NEXT: RET_ReallyLR implicit $s0
@@ -54,8 +54,8 @@ body: |
5454
; CHECK-NEXT: [[BUILD_VECTOR3:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C1]](s64), [[C1]](s64)
5555
; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[BUILD_VECTOR]], [[BUILD_VECTOR3]]
5656
; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s64>) = G_AND [[BUILD_VECTOR1]], [[BUILD_VECTOR2]]
57-
; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND1]]
58-
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[OR]](<2 x s64>)
57+
; CHECK-NEXT: %6:_(<2 x s64>) = disjoint G_OR [[AND]], [[AND1]]
58+
; CHECK-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES %6(<2 x s64>)
5959
; CHECK-NEXT: %fcopysign:_(s64) = COPY [[UV]](s64)
6060
; CHECK-NEXT: $d0 = COPY %fcopysign(s64)
6161
; CHECK-NEXT: RET_ReallyLR implicit $d0

0 commit comments

Comments
 (0)