Skip to content

Commit 7c49142

Browse files
[CodeGen] Add preliminary plumbing for samesign flag
Extend recently-added poison-generating IR flag to codegen as well.
1 parent 6f973fd commit 7c49142

16 files changed

+116
-11
lines changed

llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace llvm {
2828
class GenericMachineInstr : public MachineInstr {
2929
constexpr static unsigned PoisonFlags = NoUWrap | NoSWrap | NoUSWrap |
3030
IsExact | Disjoint | NonNeg |
31-
FmNoNans | FmNoInfs;
31+
FmNoNans | FmNoInfs | SameSign;
3232

3333
public:
3434
GenericMachineInstr() = delete;

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,8 @@ class MachineIRBuilder {
12551255
///
12561256
/// \return a MachineInstrBuilder for the newly created instruction.
12571257
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res,
1258-
const SrcOp &Op0, const SrcOp &Op1);
1258+
const SrcOp &Op0, const SrcOp &Op1,
1259+
std::optional<unsigned> Flags = std::nullopt);
12591260

12601261
/// Build and insert a \p Res = G_FCMP \p Pred\p Op0, \p Op1
12611262
///

llvm/include/llvm/CodeGen/MachineInstr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class MachineInstr
119119
Disjoint = 1 << 19, // Each bit is zero in at least one of the inputs.
120120
NoUSWrap = 1 << 20, // Instruction supports geps
121121
// no unsigned signed wrap.
122+
SameSign = 1 << 21, // Compare instruction has same sign.
122123
};
123124

124125
private:

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,12 +410,14 @@ struct SDNodeFlags {
410410
NoFPExcept = 1 << 12,
411411
// Instructions with attached 'unpredictable' metadata on IR level.
412412
Unpredictable = 1 << 13,
413+
// Compare instructions which may carry the samesign flag.
414+
SameSign = 1 << 14,
413415

414416
// NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
415417
// the class definition when adding new flags.
416418

417419
PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
418-
NonNeg | NoNaNs | NoInfs,
420+
NonNeg | NoNaNs | NoInfs | SameSign,
419421
};
420422

421423
/// Default constructor turns off all optimization flags.
@@ -437,6 +439,7 @@ struct SDNodeFlags {
437439
void setNoSignedWrap(bool b) { setFlag<NoSignedWrap>(b); }
438440
void setExact(bool b) { setFlag<Exact>(b); }
439441
void setDisjoint(bool b) { setFlag<Disjoint>(b); }
442+
void setSameSign(bool b) { setFlag<SameSign>(b); }
440443
void setNonNeg(bool b) { setFlag<NonNeg>(b); }
441444
void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
442445
void setNoInfs(bool b) { setFlag<NoInfs>(b); }
@@ -453,6 +456,7 @@ struct SDNodeFlags {
453456
bool hasNoSignedWrap() const { return Flags & NoSignedWrap; }
454457
bool hasExact() const { return Flags & Exact; }
455458
bool hasDisjoint() const { return Flags & Disjoint; }
459+
bool hasSameSign() const { return Flags & SameSign; }
456460
bool hasNonNeg() const { return Flags & NonNeg; }
457461
bool hasNoNaNs() const { return Flags & NoNaNs; }
458462
bool hasNoInfs() const { return Flags & NoInfs; }
@@ -474,7 +478,7 @@ struct SDNodeFlags {
474478
};
475479

476480
LLVM_DECLARE_ENUM_AS_BITMASK(decltype(SDNodeFlags::None),
477-
SDNodeFlags::Unpredictable);
481+
SDNodeFlags::SameSign);
478482

479483
/// Represents one node in the SelectionDAG.
480484
///

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,18 +340,18 @@ bool IRTranslator::translateCompare(const User &U,
340340
Register Op1 = getOrCreateVReg(*U.getOperand(1));
341341
Register Res = getOrCreateVReg(U);
342342
CmpInst::Predicate Pred = CI->getPredicate();
343+
uint32_t Flags = 0;
344+
if (CI)
345+
Flags = MachineInstr::copyFlagsFromInstruction(*CI);
343346
if (CmpInst::isIntPredicate(Pred))
344-
MIRBuilder.buildICmp(Pred, Res, Op0, Op1);
347+
MIRBuilder.buildICmp(Pred, Res, Op0, Op1, Flags);
345348
else if (Pred == CmpInst::FCMP_FALSE)
346349
MIRBuilder.buildCopy(
347350
Res, getOrCreateVReg(*Constant::getNullValue(U.getType())));
348351
else if (Pred == CmpInst::FCMP_TRUE)
349352
MIRBuilder.buildCopy(
350353
Res, getOrCreateVReg(*Constant::getAllOnesValue(U.getType())));
351354
else {
352-
uint32_t Flags = 0;
353-
if (CI)
354-
Flags = MachineInstr::copyFlagsFromInstruction(*CI);
355355
MIRBuilder.buildFCmp(Pred, Res, Op0, Op1, Flags);
356356
}
357357

llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,8 +898,9 @@ MachineIRBuilder::buildFPTrunc(const DstOp &Res, const SrcOp &Op,
898898
MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
899899
const DstOp &Res,
900900
const SrcOp &Op0,
901-
const SrcOp &Op1) {
902-
return buildInstr(TargetOpcode::G_ICMP, Res, {Pred, Op0, Op1});
901+
const SrcOp &Op1,
902+
std::optional<unsigned> Flags) {
903+
return buildInstr(TargetOpcode::G_ICMP, Res, {Pred, Op0, Op1}, Flags);
903904
}
904905

905906
MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,

llvm/lib/CodeGen/MIRParser/MILexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
216216
.Case("exact", MIToken::kw_exact)
217217
.Case("nneg", MIToken::kw_nneg)
218218
.Case("disjoint", MIToken::kw_disjoint)
219+
.Case("samesign", MIToken::kw_samesign)
219220
.Case("nofpexcept", MIToken::kw_nofpexcept)
220221
.Case("unpredictable", MIToken::kw_unpredictable)
221222
.Case("debug-location", MIToken::kw_debug_location)

llvm/lib/CodeGen/MIRParser/MILexer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct MIToken {
7777
kw_unpredictable,
7878
kw_nneg,
7979
kw_disjoint,
80+
kw_samesign,
8081
kw_debug_location,
8182
kw_debug_instr_number,
8283
kw_dbg_instr_ref,

llvm/lib/CodeGen/MIRParser/MIParser.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,8 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
14761476
Token.is(MIToken::kw_noconvergent) ||
14771477
Token.is(MIToken::kw_unpredictable) ||
14781478
Token.is(MIToken::kw_nneg) ||
1479-
Token.is(MIToken::kw_disjoint)) {
1479+
Token.is(MIToken::kw_disjoint) ||
1480+
Token.is(MIToken::kw_samesign)) {
14801481
// clang-format on
14811482
// Mine frame and fast math flags
14821483
if (Token.is(MIToken::kw_frame_setup))
@@ -1513,6 +1514,8 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
15131514
Flags |= MachineInstr::NonNeg;
15141515
if (Token.is(MIToken::kw_disjoint))
15151516
Flags |= MachineInstr::Disjoint;
1517+
if (Token.is(MIToken::kw_samesign))
1518+
Flags |= MachineInstr::SameSign;
15161519

15171520
lex();
15181521
}

llvm/lib/CodeGen/MIRPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,8 @@ void MIPrinter::print(const MachineInstr &MI) {
837837
OS << "disjoint ";
838838
if (MI.getFlag(MachineInstr::NoUSWrap))
839839
OS << "nusw ";
840+
if (MI.getFlag(MachineInstr::SameSign))
841+
OS << "samesign ";
840842

841843
OS << TII->getName(MI.getOpcode());
842844
if (I < E)

llvm/lib/CodeGen/MachineInstr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,12 @@ uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) {
620620
MIFlags |= MachineInstr::MIFlag::FmReassoc;
621621
}
622622

623+
// Copy the samesign flag.
624+
if (const auto *ICI = dyn_cast<ICmpInst>(&I)) {
625+
if (ICI->hasSameSign())
626+
MIFlags |= MachineInstr::MIFlag::SameSign;
627+
}
628+
623629
if (I.getMetadata(LLVMContext::MD_unpredictable))
624630
MIFlags |= MachineInstr::MIFlag::Unpredictable;
625631

@@ -1770,6 +1776,8 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
17701776
OS << "nneg ";
17711777
if (getFlag(MachineInstr::Disjoint))
17721778
OS << "disjoint ";
1779+
if (getFlag(MachineInstr::SameSign))
1780+
OS << "samesign ";
17731781

17741782
// Print the opcode name.
17751783
if (TII)

llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,9 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
11051105

11061106
if (Flags.hasDisjoint())
11071107
MI->setFlag(MachineInstr::MIFlag::Disjoint);
1108+
1109+
if (Flags.hasSameSign())
1110+
MI->setFlag(MachineInstr::MIFlag::SameSign);
11081111
}
11091112

11101113
// Emit all of the actual operands of this instruction, adding them to the

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3652,6 +3652,10 @@ void SelectionDAGBuilder::visitICmp(const ICmpInst &I) {
36523652
Op2 = DAG.getPtrExtOrTrunc(Op2, getCurSDLoc(), MemVT);
36533653
}
36543654

3655+
SDNodeFlags Flags;
3656+
Flags.setSameSign(I.hasSameSign());
3657+
SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
3658+
36553659
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
36563660
I.getType());
36573661
setValue(&I, DAG.getSetCC(getCurSDLoc(), DestVT, Op1, Op2, Opcode));

llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
653653
if (getFlags().hasDisjoint())
654654
OS << " disjoint";
655655

656+
if (getFlags().hasSameSign())
657+
OS << " samesign";
658+
656659
if (getFlags().hasNonNeg())
657660
OS << " nneg";
658661

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
3+
4+
define i1 @icmp_samesign(i32 %a, i32 %b) {
5+
; CHECK-LABEL: name: icmp_samesign
6+
; CHECK: bb.1 (%ir-block.0):
7+
; CHECK-NEXT: liveins: $w0, $w1
8+
; CHECK-NEXT: {{ $}}
9+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
10+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
11+
; CHECK-NEXT: %2:_(s1) = samesign G_ICMP intpred(ult), [[COPY]](s32), [[COPY1]]
12+
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT %2(s1)
13+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
14+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
15+
; CHECK-NEXT: RET_ReallyLR implicit $w0
16+
%res = icmp samesign ult i32 %a, %b
17+
ret i1 %res
18+
}
19+
20+
define <2 x i1> @icmp_samesign2(<2 x i32> %a, <2 x i32> %b) {
21+
; CHECK-LABEL: name: icmp_samesign2
22+
; CHECK: bb.1 (%ir-block.0):
23+
; CHECK-NEXT: liveins: $d0, $d1
24+
; CHECK-NEXT: {{ $}}
25+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
26+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
27+
; CHECK-NEXT: %2:_(<2 x s1>) = samesign G_ICMP intpred(ult), [[COPY]](<2 x s32>), [[COPY1]]
28+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<2 x s32>) = G_ANYEXT %2(<2 x s1>)
29+
; CHECK-NEXT: $d0 = COPY [[ANYEXT]](<2 x s32>)
30+
; CHECK-NEXT: RET_ReallyLR implicit $d0
31+
%res = icmp samesign ult <2 x i32> %a, %b
32+
ret <2 x i1> %res
33+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -x mir -march=x86-64 -run-pass=none -verify-machineinstrs %s -o - | FileCheck %s
3+
4+
--- |
5+
6+
define i1 @icmp_samesign(i32 %a, i32 %b) {
7+
entry:
8+
%res = icmp samesign ult i32 %a, %b
9+
ret i1 %res
10+
}
11+
12+
...
13+
---
14+
name: icmp_samesign
15+
tracksRegLiveness: true
16+
registers:
17+
- { id: 0, class: gr32 }
18+
- { id: 1, class: gr32 }
19+
liveins:
20+
- { reg: '$edi', virtual-reg: '%0' }
21+
- { reg: '$esi', virtual-reg: '%1' }
22+
body: |
23+
bb.0:
24+
liveins: $edi, $esi
25+
26+
; CHECK-LABEL: name: icmp_samesign
27+
; CHECK: liveins: $edi, $esi
28+
; CHECK-NEXT: {{ $}}
29+
; CHECK-NEXT: %tmp0:_(s32) = COPY $edi
30+
; CHECK-NEXT: %tmp1:_(s32) = COPY $esi
31+
; CHECK-NEXT: %tmp4:_(s8) = samesign G_ICMP intpred(ult), %tmp0(s32), %tmp1
32+
; CHECK-NEXT: $al = COPY %tmp4(s8)
33+
; CHECK-NEXT: RET 0, implicit $al
34+
%tmp0:_(s32) = COPY $edi
35+
%tmp1:_(s32) = COPY $esi
36+
%tmp4:_(s8) = samesign G_ICMP intpred(ult), %tmp0(s32), %tmp1
37+
$al = COPY %tmp4(s8)
38+
RET 0, implicit $al
39+
40+
...

0 commit comments

Comments
 (0)