[llvm] [CodeGen] Add preliminary plumbing for `samesign` flag (PR #112354)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 31 11:10:29 PDT 2024


https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/112354

>From 4f95fbdac9b5ed8352979d9d2422419acff6eea8 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Thu, 31 Oct 2024 11:58:28 +0100
Subject: [PATCH] [SelectionDAG] Add preliminary plumbing for `samesign` flag

Extend recently-added poison-generating IR flag to codegen as well.
---
 .../CodeGen/GlobalISel/MachineIRBuilder.h     |  2 +-
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h |  8 +++--
 .../lib/CodeGen/SelectionDAG/InstrEmitter.cpp |  3 ++
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  4 +++
 .../SelectionDAG/SelectionDAGDumper.cpp       |  3 ++
 .../AArch64/dag-preserve-icmp-samesign.ll     | 31 +++++++++++++++++++
 6 files changed, 48 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/dag-preserve-icmp-samesign.ll

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 14a641512a67d6..a38dd34a17097a 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -1267,7 +1267,7 @@ class MachineIRBuilder {
   /// \return a MachineInstrBuilder for the newly created instruction.
   MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res,
                                 const SrcOp &Op0, const SrcOp &Op1,
-                                std::optional<unsigned> Flgs = std::nullopt);
+                                std::optional<unsigned> Flags = std::nullopt);
 
   /// Build and insert a \p Res = G_FCMP \p Pred\p Op0, \p Op1
   ///
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index ae07420479e14e..739ce05e947346 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -411,12 +411,14 @@ struct SDNodeFlags {
     NoFPExcept = 1 << 12,
     // Instructions with attached 'unpredictable' metadata on IR level.
     Unpredictable = 1 << 13,
+    // Compare instructions which may carry the samesign flag.
+    SameSign = 1 << 14,
 
     // NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
     // the class definition when adding new flags.
 
     PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
-                            NonNeg | NoNaNs | NoInfs,
+                            NonNeg | NoNaNs | NoInfs | SameSign,
   };
 
   /// Default constructor turns off all optimization flags.
@@ -438,6 +440,7 @@ struct SDNodeFlags {
   void setNoSignedWrap(bool b) { setFlag<NoSignedWrap>(b); }
   void setExact(bool b) { setFlag<Exact>(b); }
   void setDisjoint(bool b) { setFlag<Disjoint>(b); }
+  void setSameSign(bool b) { setFlag<SameSign>(b); }
   void setNonNeg(bool b) { setFlag<NonNeg>(b); }
   void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
   void setNoInfs(bool b) { setFlag<NoInfs>(b); }
@@ -454,6 +457,7 @@ struct SDNodeFlags {
   bool hasNoSignedWrap() const { return Flags & NoSignedWrap; }
   bool hasExact() const { return Flags & Exact; }
   bool hasDisjoint() const { return Flags & Disjoint; }
+  bool hasSameSign() const { return Flags & SameSign; }
   bool hasNonNeg() const { return Flags & NonNeg; }
   bool hasNoNaNs() const { return Flags & NoNaNs; }
   bool hasNoInfs() const { return Flags & NoInfs; }
@@ -473,7 +477,7 @@ struct SDNodeFlags {
 };
 
 LLVM_DECLARE_ENUM_AS_BITMASK(decltype(SDNodeFlags::None),
-                             SDNodeFlags::Unpredictable);
+                             SDNodeFlags::SameSign);
 
 inline SDNodeFlags operator|(SDNodeFlags LHS, SDNodeFlags RHS) {
   LHS |= RHS;
diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 281d1578d0173a..9c7085cc7e7a83 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -1105,6 +1105,9 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
 
     if (Flags.hasDisjoint())
       MI->setFlag(MachineInstr::MIFlag::Disjoint);
+
+    if (Flags.hasSameSign())
+      MI->setFlag(MachineInstr::MIFlag::SameSign);
   }
 
   // Emit all of the actual operands of this instruction, adding them to the
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 95125928cdc66f..f41dbe81434c7e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3652,6 +3652,10 @@ void SelectionDAGBuilder::visitICmp(const ICmpInst &I) {
     Op2 = DAG.getPtrExtOrTrunc(Op2, getCurSDLoc(), MemVT);
   }
 
+  SDNodeFlags Flags;
+  Flags.setSameSign(I.hasSameSign());
+  SelectionDAG::FlagInserter FlagsInserter(DAG, Flags);
+
   EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
                                                         I.getType());
   setValue(&I, DAG.getSetCC(getCurSDLoc(), DestVT, Op1, Op2, Opcode));
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 703efb70089742..580ff19065557b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -653,6 +653,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
   if (getFlags().hasDisjoint())
     OS << " disjoint";
 
+  if (getFlags().hasSameSign())
+    OS << " samesign";
+
   if (getFlags().hasNonNeg())
     OS << " nneg";
 
diff --git a/llvm/test/CodeGen/AArch64/dag-preserve-icmp-samesign.ll b/llvm/test/CodeGen/AArch64/dag-preserve-icmp-samesign.ll
new file mode 100644
index 00000000000000..9192e31be8ba97
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/dag-preserve-icmp-samesign.ll
@@ -0,0 +1,31 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -march=aarch64 -stop-after=finalize-isel -simplify-mir -o - %s | FileCheck %s
+
+define i1 @icmp_samesign(i32 %a, i32 %b) {
+  ; CHECK-LABEL: name: icmp_samesign
+  ; CHECK: bb.0 (%ir-block.0):
+  ; CHECK-NEXT:   liveins: $w0, $w1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32 = COPY $w1
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
+  ; CHECK-NEXT:   [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr [[COPY1]], [[COPY]], implicit-def $nzcv
+  ; CHECK-NEXT:   [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv
+  ; CHECK-NEXT:   $w0 = COPY [[CSINCWr]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+    %res = icmp samesign ult i32 %a, %b
+    ret i1 %res
+}
+
+define <2 x i1> @icmp_samesign_vec(<2 x i32> %a, <2 x i32> %b) {
+  ; CHECK-LABEL: name: icmp_samesign_vec
+  ; CHECK: bb.0 (%ir-block.0):
+  ; CHECK-NEXT:   liveins: $d0, $d1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:fpr64 = COPY $d1
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:fpr64 = COPY $d0
+  ; CHECK-NEXT:   [[CMHIv2i32_:%[0-9]+]]:fpr64 = CMHIv2i32 [[COPY]], [[COPY1]]
+  ; CHECK-NEXT:   $d0 = COPY [[CMHIv2i32_]]
+  ; CHECK-NEXT:   RET_ReallyLR implicit $d0
+  %res = icmp samesign ult <2 x i32> %a, %b
+  ret <2 x i1> %res
+}



More information about the llvm-commits mailing list