Skip to content

Commit 72b1153

Browse files
author
Thorsten Schütt
authored
[GlobalISel] Import samesign flag (#113090)
Credits: #111419
1 parent 475e736 commit 72b1153

File tree

12 files changed

+144
-11
lines changed

12 files changed

+144
-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
@@ -1266,7 +1266,8 @@ class MachineIRBuilder {
12661266
///
12671267
/// \return a MachineInstrBuilder for the newly created instruction.
12681268
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res,
1269-
const SrcOp &Op0, const SrcOp &Op1);
1269+
const SrcOp &Op0, const SrcOp &Op1,
1270+
std::optional<unsigned> Flags = std::nullopt);
12701271

12711272
/// Build and insert a \p Res = G_FCMP \p Pred\p Op0, \p Op1
12721273
///

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 // Both operands have the same sign.
122123
};
123124

124125
private:

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -340,20 +340,17 @@ 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 = MachineInstr::copyFlagsFromInstruction(*CI);
343344
if (CmpInst::isIntPredicate(Pred))
344-
MIRBuilder.buildICmp(Pred, Res, Op0, Op1);
345+
MIRBuilder.buildICmp(Pred, Res, Op0, Op1, Flags);
345346
else if (Pred == CmpInst::FCMP_FALSE)
346347
MIRBuilder.buildCopy(
347348
Res, getOrCreateVReg(*Constant::getNullValue(U.getType())));
348349
else if (Pred == CmpInst::FCMP_TRUE)
349350
MIRBuilder.buildCopy(
350351
Res, getOrCreateVReg(*Constant::getAllOnesValue(U.getType())));
351-
else {
352-
uint32_t Flags = 0;
353-
if (CI)
354-
Flags = MachineInstr::copyFlagsFromInstruction(*CI);
352+
else
355353
MIRBuilder.buildFCmp(Pred, Res, Op0, Op1, Flags);
356-
}
357354

358355
return true;
359356
}

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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,11 @@ uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) {
596596
MIFlags |= MachineInstr::MIFlag::Disjoint;
597597
}
598598

599+
// Copy the samesign flag.
600+
if (const ICmpInst *ICmp = dyn_cast<ICmpInst>(&I))
601+
if (ICmp->hasSameSign())
602+
MIFlags |= MachineInstr::MIFlag::SameSign;
603+
599604
// Copy the exact flag.
600605
if (const PossiblyExactOperator *PE = dyn_cast<PossiblyExactOperator>(&I))
601606
if (PE->isExact())
@@ -1770,6 +1775,8 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
17701775
OS << "nneg ";
17711776
if (getFlag(MachineInstr::Disjoint))
17721777
OS << "disjoint ";
1778+
if (getFlag(MachineInstr::SameSign))
1779+
OS << "samesign ";
17731780

17741781
// Print the opcode name.
17751782
if (TII)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -global-isel -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator < %s | FileCheck %s
3+
4+
5+
define <2 x i1> @call_icmp_samesign_vector(<2 x i32> %a, <2 x i32> %b) {
6+
; CHECK-LABEL: name: call_icmp_samesign_vector
7+
; CHECK: bb.1.entry:
8+
; CHECK-NEXT: liveins: $d0, $d1
9+
; CHECK-NEXT: {{ $}}
10+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
11+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
12+
; CHECK-NEXT: %2:_(<2 x s1>) = samesign G_ICMP intpred(ult), [[COPY]](<2 x s32>), [[COPY1]]
13+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<2 x s32>) = G_ANYEXT %2(<2 x s1>)
14+
; CHECK-NEXT: $d0 = COPY [[ANYEXT]](<2 x s32>)
15+
; CHECK-NEXT: RET_ReallyLR implicit $d0
16+
entry:
17+
%result = icmp samesign ult <2 x i32> %a, %b
18+
ret <2 x i1> %result
19+
}
20+
21+
define <2 x i1> @call_icmp_vector(<2 x i32> %a, <2 x i32> %b) {
22+
; CHECK-LABEL: name: call_icmp_vector
23+
; CHECK: bb.1.entry:
24+
; CHECK-NEXT: liveins: $d0, $d1
25+
; CHECK-NEXT: {{ $}}
26+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
27+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
28+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[COPY]](<2 x s32>), [[COPY1]]
29+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<2 x s32>) = G_ANYEXT [[ICMP]](<2 x s1>)
30+
; CHECK-NEXT: $d0 = COPY [[ANYEXT]](<2 x s32>)
31+
; CHECK-NEXT: RET_ReallyLR implicit $d0
32+
entry:
33+
%result = icmp ult <2 x i32> %a, %b
34+
ret <2 x i1> %result
35+
}
36+
37+
define i1 @call_icmp(i32 %a) {
38+
; CHECK-LABEL: name: call_icmp
39+
; CHECK: bb.1.entry:
40+
; CHECK-NEXT: liveins: $w0
41+
; CHECK-NEXT: {{ $}}
42+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
43+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
44+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), [[COPY]](s32), [[C]]
45+
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[ICMP]](s1)
46+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
47+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
48+
; CHECK-NEXT: RET_ReallyLR implicit $w0
49+
entry:
50+
%result = icmp ult i32 %a, 3
51+
ret i1 %result
52+
}
53+
54+
define i1 @call_icmp_samesign(i32 %a) {
55+
; CHECK-LABEL: name: call_icmp_samesign
56+
; CHECK: bb.1.entry:
57+
; CHECK-NEXT: liveins: $w0
58+
; CHECK-NEXT: {{ $}}
59+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
60+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
61+
; CHECK-NEXT: %2:_(s1) = samesign G_ICMP intpred(ult), [[COPY]](s32), [[C]]
62+
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT %2(s1)
63+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
64+
; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
65+
; CHECK-NEXT: RET_ReallyLR implicit $w0
66+
entry:
67+
%result = icmp samesign ult i32 %a, 3
68+
ret i1 %result
69+
}

llvm/test/CodeGen/MIR/icmp-flags.mir

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple aarch64 -run-pass=none -verify-machineinstrs %s -o - | FileCheck %s
3+
4+
5+
---
6+
name: icmp_samesign
7+
body: |
8+
bb.0:
9+
liveins: $w0, $w1
10+
11+
; CHECK-LABEL: name: icmp_samesign
12+
; CHECK: liveins: $w0, $w1
13+
; CHECK-NEXT: {{ $}}
14+
; CHECK-NEXT: %x:_(s32) = COPY $w0
15+
; CHECK-NEXT: %y:_(s32) = COPY $w1
16+
; CHECK-NEXT: %cmp:_(s1) = samesign G_ICMP intpred(eq), %y(s32), %y
17+
; CHECK-NEXT: %zext:_(s32) = G_ZEXT %cmp(s1)
18+
; CHECK-NEXT: $w0 = COPY %zext(s32)
19+
; CHECK-NEXT: RET_ReallyLR implicit $w0
20+
%x:_(s32) = COPY $w0
21+
%y:_(s32) = COPY $w1
22+
%cmp:_(s1) = samesign G_ICMP intpred(eq), %y:_(s32), %y:_
23+
%zext:_(s32) = G_ZEXT %cmp:_(s1)
24+
$w0 = COPY %zext
25+
RET_ReallyLR implicit $w0
26+
27+
28+
...
29+
---
30+
name: icmp_differentsign
31+
body: |
32+
bb.0:
33+
liveins: $w0, $w1
34+
35+
; CHECK-LABEL: name: icmp_differentsign
36+
; CHECK: liveins: $w0, $w1
37+
; CHECK-NEXT: {{ $}}
38+
; CHECK-NEXT: %x:_(s32) = COPY $w0
39+
; CHECK-NEXT: %y:_(s32) = COPY $w1
40+
; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), %y
41+
; CHECK-NEXT: %zext:_(s32) = G_ZEXT %cmp(s1)
42+
; CHECK-NEXT: $w0 = COPY %zext(s32)
43+
; CHECK-NEXT: RET_ReallyLR implicit $w0
44+
%x:_(s32) = COPY $w0
45+
%y:_(s32) = COPY $w1
46+
%cmp:_(s1) = G_ICMP intpred(eq), %y:_(s32), %y:_
47+
%zext:_(s32) = G_ZEXT %cmp:_(s1)
48+
$w0 = COPY %zext
49+
RET_ReallyLR implicit $w0
50+
---

0 commit comments

Comments
 (0)