-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GlobalISel] Import samesign flag #114267
Conversation
Credits: llvm#111419 Fixes icmp-flags.mir First attempt: llvm#113090 Revert: llvm#114256
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-llvm-globalisel Author: Thorsten Schütt (tschuett) ChangesCredits: #111419 Fixes icmp-flags.mir First attempt: #113090 Revert: #114256 Full diff: https://github.com/llvm/llvm-project/pull/114267.diff 12 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index b6309a9ea0ec78..cd7ebcf54c9e1e 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -28,7 +28,7 @@ namespace llvm {
class GenericMachineInstr : public MachineInstr {
constexpr static unsigned PoisonFlags = NoUWrap | NoSWrap | NoUSWrap |
IsExact | Disjoint | NonNeg |
- FmNoNans | FmNoInfs;
+ FmNoNans | FmNoInfs | SameSign;
public:
GenericMachineInstr() = delete;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index c41e74ec7ebdcc..14a641512a67d6 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -1266,7 +1266,8 @@ class MachineIRBuilder {
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res,
- const SrcOp &Op0, const SrcOp &Op1);
+ const SrcOp &Op0, const SrcOp &Op1,
+ std::optional<unsigned> Flgs = std::nullopt);
/// Build and insert a \p Res = G_FCMP \p Pred\p Op0, \p Op1
///
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index 36051732474634..ead6bbe1d5f641 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -119,6 +119,7 @@ class MachineInstr
Disjoint = 1 << 19, // Each bit is zero in at least one of the inputs.
NoUSWrap = 1 << 20, // Instruction supports geps
// no unsigned signed wrap.
+ SameSign = 1 << 21 // Both operands have the same sign.
};
private:
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 5381dce58f9e65..a87754389cc8ed 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -340,20 +340,17 @@ bool IRTranslator::translateCompare(const User &U,
Register Op1 = getOrCreateVReg(*U.getOperand(1));
Register Res = getOrCreateVReg(U);
CmpInst::Predicate Pred = CI->getPredicate();
+ uint32_t Flags = MachineInstr::copyFlagsFromInstruction(*CI);
if (CmpInst::isIntPredicate(Pred))
- MIRBuilder.buildICmp(Pred, Res, Op0, Op1);
+ MIRBuilder.buildICmp(Pred, Res, Op0, Op1, Flags);
else if (Pred == CmpInst::FCMP_FALSE)
MIRBuilder.buildCopy(
Res, getOrCreateVReg(*Constant::getNullValue(U.getType())));
else if (Pred == CmpInst::FCMP_TRUE)
MIRBuilder.buildCopy(
Res, getOrCreateVReg(*Constant::getAllOnesValue(U.getType())));
- else {
- uint32_t Flags = 0;
- if (CI)
- Flags = MachineInstr::copyFlagsFromInstruction(*CI);
+ else
MIRBuilder.buildFCmp(Pred, Res, Op0, Op1, Flags);
- }
return true;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 59f2fc633f5de7..15b9164247846c 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -898,8 +898,9 @@ MachineIRBuilder::buildFPTrunc(const DstOp &Res, const SrcOp &Op,
MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
const DstOp &Res,
const SrcOp &Op0,
- const SrcOp &Op1) {
- return buildInstr(TargetOpcode::G_ICMP, Res, {Pred, Op0, Op1});
+ const SrcOp &Op1,
+ std::optional<unsigned> Flags) {
+ return buildInstr(TargetOpcode::G_ICMP, Res, {Pred, Op0, Op1}, Flags);
}
MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index 5a3806ce57335a..1c450b05f49e93 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -216,6 +216,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("exact", MIToken::kw_exact)
.Case("nneg", MIToken::kw_nneg)
.Case("disjoint", MIToken::kw_disjoint)
+ .Case("samesign", MIToken::kw_samesign)
.Case("nofpexcept", MIToken::kw_nofpexcept)
.Case("unpredictable", MIToken::kw_unpredictable)
.Case("debug-location", MIToken::kw_debug_location)
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index 3931da3eaae1d3..d7cd06759cfbb8 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -77,6 +77,7 @@ struct MIToken {
kw_unpredictable,
kw_nneg,
kw_disjoint,
+ kw_samesign,
kw_debug_location,
kw_debug_instr_number,
kw_dbg_instr_ref,
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 45847b5830da65..059814c70f828d 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -1476,7 +1476,8 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
Token.is(MIToken::kw_noconvergent) ||
Token.is(MIToken::kw_unpredictable) ||
Token.is(MIToken::kw_nneg) ||
- Token.is(MIToken::kw_disjoint)) {
+ Token.is(MIToken::kw_disjoint) ||
+ Token.is(MIToken::kw_samesign)) {
// clang-format on
// Mine frame and fast math flags
if (Token.is(MIToken::kw_frame_setup))
@@ -1513,6 +1514,8 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
Flags |= MachineInstr::NonNeg;
if (Token.is(MIToken::kw_disjoint))
Flags |= MachineInstr::Disjoint;
+ if (Token.is(MIToken::kw_samesign))
+ Flags |= MachineInstr::SameSign;
lex();
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index a015cd3c2a55f9..658bbe0e577e5c 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -837,6 +837,8 @@ void MIPrinter::print(const MachineInstr &MI) {
OS << "disjoint ";
if (MI.getFlag(MachineInstr::NoUSWrap))
OS << "nusw ";
+ if (MI.getFlag(MachineInstr::SameSign))
+ OS << "samesign ";
OS << TII->getName(MI.getOpcode());
if (I < E)
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index c1bd0bb5b7162e..941861da5c5693 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -596,6 +596,11 @@ uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) {
MIFlags |= MachineInstr::MIFlag::Disjoint;
}
+ // Copy the samesign flag.
+ if (const ICmpInst *ICmp = dyn_cast<ICmpInst>(&I))
+ if (ICmp->hasSameSign())
+ MIFlags |= MachineInstr::MIFlag::SameSign;
+
// Copy the exact flag.
if (const PossiblyExactOperator *PE = dyn_cast<PossiblyExactOperator>(&I))
if (PE->isExact())
@@ -1770,6 +1775,8 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
OS << "nneg ";
if (getFlag(MachineInstr::Disjoint))
OS << "disjoint ";
+ if (getFlag(MachineInstr::SameSign))
+ OS << "samesign ";
// Print the opcode name.
if (TII)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/icmp-flags.mir b/llvm/test/CodeGen/AArch64/GlobalISel/icmp-flags.mir
new file mode 100644
index 00000000000000..59e4de9440416f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/icmp-flags.mir
@@ -0,0 +1,45 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple aarch64 -run-pass=none -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: icmp_samesign
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: icmp_samesign
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $w0
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: %cmp:_(s1) = samesign G_ICMP intpred(eq), %y(s32), %y
+ ; CHECK-NEXT: %zext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %zext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %cmp:_(s1) = samesign G_ICMP intpred(eq), %y:_(s32), %y:_
+ %zext:_(s32) = G_ZEXT %cmp:_(s1)
+ $w0 = COPY %zext
+ RET_ReallyLR implicit $w0
+...
+---
+name: icmp_differentsign
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: icmp_differentsign
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $w0
+ ; CHECK-NEXT: %y:_(s32) = COPY $w1
+ ; CHECK-NEXT: %cmp:_(s1) = G_ICMP intpred(eq), %y(s32), %y
+ ; CHECK-NEXT: %zext:_(s32) = G_ZEXT %cmp(s1)
+ ; CHECK-NEXT: $w0 = COPY %zext(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %x:_(s32) = COPY $w0
+ %y:_(s32) = COPY $w1
+ %cmp:_(s1) = G_ICMP intpred(eq), %y:_(s32), %y:_
+ %zext:_(s32) = G_ZEXT %cmp:_(s1)
+ $w0 = COPY %zext
+ RET_ReallyLR implicit $w0
+---
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslater-samesign.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslater-samesign.ll
new file mode 100644
index 00000000000000..0173f92c982203
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslater-samesign.ll
@@ -0,0 +1,69 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -global-isel -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator < %s | FileCheck %s
+
+
+define <2 x i1> @call_icmp_samesign_vector(<2 x i32> %a, <2 x i32> %b) {
+ ; CHECK-LABEL: name: call_icmp_samesign_vector
+ ; CHECK: bb.1.entry:
+ ; CHECK-NEXT: liveins: $d0, $d1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
+ ; CHECK-NEXT: %2:_(<2 x s1>) = samesign G_ICMP intpred(ult), [[COPY]](<2 x s32>), [[COPY1]]
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<2 x s32>) = G_ANYEXT %2(<2 x s1>)
+ ; CHECK-NEXT: $d0 = COPY [[ANYEXT]](<2 x s32>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+entry:
+ %result = icmp samesign ult <2 x i32> %a, %b
+ ret <2 x i1> %result
+}
+
+define <2 x i1> @call_icmp_vector(<2 x i32> %a, <2 x i32> %b) {
+ ; CHECK-LABEL: name: call_icmp_vector
+ ; CHECK: bb.1.entry:
+ ; CHECK-NEXT: liveins: $d0, $d1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[COPY]](<2 x s32>), [[COPY1]]
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<2 x s32>) = G_ANYEXT [[ICMP]](<2 x s1>)
+ ; CHECK-NEXT: $d0 = COPY [[ANYEXT]](<2 x s32>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+entry:
+ %result = icmp ult <2 x i32> %a, %b
+ ret <2 x i1> %result
+}
+
+define i1 @call_icmp(i32 %a) {
+ ; CHECK-LABEL: name: call_icmp
+ ; CHECK: bb.1.entry:
+ ; CHECK-NEXT: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), [[COPY]](s32), [[C]]
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[ICMP]](s1)
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
+ ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+entry:
+ %result = icmp ult i32 %a, 3
+ ret i1 %result
+}
+
+define i1 @call_icmp_samesign(i32 %a) {
+ ; CHECK-LABEL: name: call_icmp_samesign
+ ; CHECK: bb.1.entry:
+ ; CHECK-NEXT: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: %2:_(s1) = samesign G_ICMP intpred(ult), [[COPY]](s32), [[C]]
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT %2(s1)
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
+ ; CHECK-NEXT: $w0 = COPY [[ANYEXT]](s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+entry:
+ %result = icmp samesign ult i32 %a, 3
+ ret i1 %result
+}
|
@@ -0,0 +1,69 @@ | |||
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 | |||
; RUN: llc -global-isel -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator < %s | FileCheck %s | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop second attempt from the title, it's not relevant. Please put some love in the commit description (no need to credit any PR, this is a relanding rather than reverting, maybe punctualize this has been extended to MI parsing, not just GISel). Please, exercize some due diligence verifying no similar effort has been carried out by somebody else (the MI changes had been already added in the other PR; at the very least, please add yourself in the ongoing tracking related issue). |
Credits: #111419
Fixes icmp-flags.mir
First attempt: #113090
Revert: #114256