Skip to content
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

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
///
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/MachineInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
9 changes: 3 additions & 6 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRParser/MILexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRParser/MILexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/CodeGen/MIRParser/MIParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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();
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/CodeGen/MIRPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/CodeGen/MachineInstr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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)
Expand Down
45 changes: 45 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/icmp-flags.mir
Original file line number Diff line number Diff line change
@@ -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
---
69 changes: 69 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/irtranslater-samesign.ll
Original file line number Diff line number Diff line change
@@ -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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change


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
}
Loading