Skip to content

Commit da6cc4a

Browse files
author
Thorsten Schütt
authored
[CodeGen] Add nneg and disjoint flags (#86650)
MachineInstr learned the new flags.
1 parent d0e97fe commit da6cc4a

File tree

8 files changed

+173
-2
lines changed

8 files changed

+173
-2
lines changed

llvm/include/llvm/CodeGen/MachineInstr.h

+2
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ class MachineInstr
115115
// this instruction.
116116
Unpredictable = 1 << 16, // Instruction with unpredictable condition.
117117
NoConvergent = 1 << 17, // Call does not require convergence guarantees.
118+
NonNeg = 1 << 18, // The operand is non-negative.
119+
Disjoint = 1 << 19, // Each bit is zero in at least one of the inputs.
118120
};
119121

120122
private:

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -1562,9 +1562,14 @@ bool IRTranslator::translateCast(unsigned Opcode, const User &U,
15621562
if (U.getType()->getScalarType()->isBFloatTy() ||
15631563
U.getOperand(0)->getType()->getScalarType()->isBFloatTy())
15641564
return false;
1565+
1566+
uint32_t Flags = 0;
1567+
if (const Instruction *I = dyn_cast<Instruction>(&U))
1568+
Flags = MachineInstr::copyFlagsFromInstruction(*I);
1569+
15651570
Register Op = getOrCreateVReg(*U.getOperand(0));
15661571
Register Res = getOrCreateVReg(U);
1567-
MIRBuilder.buildInstr(Opcode, {Res}, {Op});
1572+
MIRBuilder.buildInstr(Opcode, {Res}, {Op}, Flags);
15681573
return true;
15691574
}
15701575

llvm/lib/CodeGen/MIRParser/MILexer.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
213213
.Case("nuw", MIToken::kw_nuw)
214214
.Case("nsw", MIToken::kw_nsw)
215215
.Case("exact", MIToken::kw_exact)
216+
.Case("nneg", MIToken::kw_nneg)
217+
.Case("disjoint", MIToken::kw_disjoint)
216218
.Case("nofpexcept", MIToken::kw_nofpexcept)
217219
.Case("unpredictable", MIToken::kw_unpredictable)
218220
.Case("debug-location", MIToken::kw_debug_location)

llvm/lib/CodeGen/MIRParser/MILexer.h

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ struct MIToken {
7474
kw_exact,
7575
kw_nofpexcept,
7676
kw_unpredictable,
77+
kw_nneg,
78+
kw_disjoint,
7779
kw_debug_location,
7880
kw_debug_instr_number,
7981
kw_dbg_instr_ref,

llvm/lib/CodeGen/MIRParser/MIParser.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -1471,7 +1471,9 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
14711471
Token.is(MIToken::kw_exact) ||
14721472
Token.is(MIToken::kw_nofpexcept) ||
14731473
Token.is(MIToken::kw_noconvergent) ||
1474-
Token.is(MIToken::kw_unpredictable)) {
1474+
Token.is(MIToken::kw_unpredictable) ||
1475+
Token.is(MIToken::kw_nneg) ||
1476+
Token.is(MIToken::kw_disjoint)) {
14751477
// clang-format on
14761478
// Mine frame and fast math flags
14771479
if (Token.is(MIToken::kw_frame_setup))
@@ -1504,6 +1506,10 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
15041506
Flags |= MachineInstr::Unpredictable;
15051507
if (Token.is(MIToken::kw_noconvergent))
15061508
Flags |= MachineInstr::NoConvergent;
1509+
if (Token.is(MIToken::kw_nneg))
1510+
Flags |= MachineInstr::NonNeg;
1511+
if (Token.is(MIToken::kw_disjoint))
1512+
Flags |= MachineInstr::Disjoint;
15071513

15081514
lex();
15091515
}

llvm/lib/CodeGen/MIRPrinter.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,10 @@ void MIPrinter::print(const MachineInstr &MI) {
806806
OS << "unpredictable ";
807807
if (MI.getFlag(MachineInstr::NoConvergent))
808808
OS << "noconvergent ";
809+
if (MI.getFlag(MachineInstr::NonNeg))
810+
OS << "nneg ";
811+
if (MI.getFlag(MachineInstr::Disjoint))
812+
OS << "disjoint ";
809813

810814
OS << TII->getName(MI.getOpcode());
811815
if (I < E)

llvm/lib/CodeGen/MachineInstr.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,17 @@ uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) {
555555
MIFlags |= MachineInstr::MIFlag::NoUWrap;
556556
}
557557

558+
// Copy the nonneg flag.
559+
if (const PossiblyNonNegInst *PNI = dyn_cast<PossiblyNonNegInst>(&I)) {
560+
if (PNI->hasNonNeg())
561+
MIFlags |= MachineInstr::MIFlag::NonNeg;
562+
// Copy the disjoint flag.
563+
} else if (const PossiblyDisjointInst *PD =
564+
dyn_cast<PossiblyDisjointInst>(&I)) {
565+
if (PD->isDisjoint())
566+
MIFlags |= MachineInstr::MIFlag::Disjoint;
567+
}
568+
558569
// Copy the exact flag.
559570
if (const PossiblyExactOperator *PE = dyn_cast<PossiblyExactOperator>(&I))
560571
if (PE->isExact())
@@ -1706,6 +1717,10 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
17061717
OS << "nofpexcept ";
17071718
if (getFlag(MachineInstr::NoMerge))
17081719
OS << "nomerge ";
1720+
if (getFlag(MachineInstr::NonNeg))
1721+
OS << "nneg ";
1722+
if (getFlag(MachineInstr::Disjoint))
1723+
OS << "disjoint ";
17091724

17101725
// Print the opcode name.
17111726
if (TII)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
3+
4+
define i32 @call_nneg(i16 %a) {
5+
; CHECK-LABEL: name: call_nneg
6+
; CHECK: bb.1.entry:
7+
; CHECK-NEXT: liveins: $w0
8+
; CHECK-NEXT: {{ $}}
9+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
10+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
11+
; CHECK-NEXT: %2:_(s32) = nneg G_ZEXT [[TRUNC]](s16)
12+
; CHECK-NEXT: $w0 = COPY %2(s32)
13+
; CHECK-NEXT: RET_ReallyLR implicit $w0
14+
entry:
15+
%result = zext nneg i16 %a to i32
16+
ret i32 %result
17+
}
18+
19+
define i32 @call_not_nneg(i16 %a) {
20+
; CHECK-LABEL: name: call_not_nneg
21+
; CHECK: bb.1.entry:
22+
; CHECK-NEXT: liveins: $w0
23+
; CHECK-NEXT: {{ $}}
24+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
25+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
26+
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s16)
27+
; CHECK-NEXT: $w0 = COPY [[ZEXT]](s32)
28+
; CHECK-NEXT: RET_ReallyLR implicit $w0
29+
entry:
30+
%result = zext i16 %a to i32
31+
ret i32 %result
32+
}
33+
34+
define i32 @call_disjoint(i32 %a, i32 %b) {
35+
; CHECK-LABEL: name: call_disjoint
36+
; CHECK: bb.1.entry:
37+
; CHECK-NEXT: liveins: $w0, $w1
38+
; CHECK-NEXT: {{ $}}
39+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
40+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
41+
; CHECK-NEXT: %2:_(s32) = disjoint G_OR [[COPY]], [[COPY1]]
42+
; CHECK-NEXT: $w0 = COPY %2(s32)
43+
; CHECK-NEXT: RET_ReallyLR implicit $w0
44+
entry:
45+
%result = or disjoint i32 %a, %b
46+
ret i32 %result
47+
}
48+
49+
define i32 @call_add(i32 %a, i32 %b) {
50+
; CHECK-LABEL: name: call_add
51+
; CHECK: bb.1.entry:
52+
; CHECK-NEXT: liveins: $w0, $w1
53+
; CHECK-NEXT: {{ $}}
54+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
55+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
56+
; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[COPY]], [[COPY1]]
57+
; CHECK-NEXT: $w0 = COPY [[ADD]](s32)
58+
; CHECK-NEXT: RET_ReallyLR implicit $w0
59+
entry:
60+
%result = add nsw i32 %a, %b
61+
ret i32 %result
62+
}
63+
64+
define i32 @call_not_disjoint(i32 %a, i32 %b) {
65+
; CHECK-LABEL: name: call_not_disjoint
66+
; CHECK: bb.1.entry:
67+
; CHECK-NEXT: liveins: $w0, $w1
68+
; CHECK-NEXT: {{ $}}
69+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
70+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
71+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR [[COPY]], [[COPY1]]
72+
; CHECK-NEXT: $w0 = COPY [[OR]](s32)
73+
; CHECK-NEXT: RET_ReallyLR implicit $w0
74+
entry:
75+
%result = or i32 %a, %b
76+
ret i32 %result
77+
}
78+
79+
define <2 x i64> @call_not_disjoint_vector(<2 x i64> %a, <2 x i64> %b) {
80+
; CHECK-LABEL: name: call_not_disjoint_vector
81+
; CHECK: bb.1.entry:
82+
; CHECK-NEXT: liveins: $q0, $q1
83+
; CHECK-NEXT: {{ $}}
84+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
85+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
86+
; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[COPY]], [[COPY1]]
87+
; CHECK-NEXT: $q0 = COPY [[OR]](<2 x s64>)
88+
; CHECK-NEXT: RET_ReallyLR implicit $q0
89+
entry:
90+
%result = or <2 x i64> %a, %b
91+
ret <2 x i64> %result
92+
}
93+
94+
define <2 x i64> @call_disjoint_vector(<2 x i64> %a, <2 x i64> %b) {
95+
; CHECK-LABEL: name: call_disjoint_vector
96+
; CHECK: bb.1.entry:
97+
; CHECK-NEXT: liveins: $q0, $q1
98+
; CHECK-NEXT: {{ $}}
99+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
100+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
101+
; CHECK-NEXT: %2:_(<2 x s64>) = disjoint G_OR [[COPY]], [[COPY1]]
102+
; CHECK-NEXT: $q0 = COPY %2(<2 x s64>)
103+
; CHECK-NEXT: RET_ReallyLR implicit $q0
104+
entry:
105+
%result = or disjoint <2 x i64> %a, %b
106+
ret <2 x i64> %result
107+
}
108+
109+
define <2 x i64> @call_nneg_vector(<2 x i32> %a) {
110+
; CHECK-LABEL: name: call_nneg_vector
111+
; CHECK: bb.1.entry:
112+
; CHECK-NEXT: liveins: $d0
113+
; CHECK-NEXT: {{ $}}
114+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
115+
; CHECK-NEXT: %1:_(<2 x s64>) = nneg G_ZEXT [[COPY]](<2 x s32>)
116+
; CHECK-NEXT: $q0 = COPY %1(<2 x s64>)
117+
; CHECK-NEXT: RET_ReallyLR implicit $q0
118+
entry:
119+
%result = zext nneg <2 x i32> %a to <2 x i64>
120+
ret <2 x i64> %result
121+
}
122+
123+
define <2 x i64> @call_not_nneg_vector(<2 x i32> %a) {
124+
; CHECK-LABEL: name: call_not_nneg_vector
125+
; CHECK: bb.1.entry:
126+
; CHECK-NEXT: liveins: $d0
127+
; CHECK-NEXT: {{ $}}
128+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
129+
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(<2 x s64>) = G_ZEXT [[COPY]](<2 x s32>)
130+
; CHECK-NEXT: $q0 = COPY [[ZEXT]](<2 x s64>)
131+
; CHECK-NEXT: RET_ReallyLR implicit $q0
132+
entry:
133+
%result = zext <2 x i32> %a to <2 x i64>
134+
ret <2 x i64> %result
135+
}

0 commit comments

Comments
 (0)