[llvm] 3aec021 - [SDAG] add helper for opcodes that are not speculatable

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 26 08:20:24 PDT 2022


Author: Sanjay Patel
Date: 2022-10-26T11:20:14-04:00
New Revision: 3aec0211187b98c4a4e48872df20e86a775e7a8a

URL: https://github.com/llvm/llvm-project/commit/3aec0211187b98c4a4e48872df20e86a775e7a8a
DIFF: https://github.com/llvm/llvm-project/commit/3aec0211187b98c4a4e48872df20e86a775e7a8a.diff

LOG: [SDAG] add helper for opcodes that are not speculatable

This is not quite NFC because one of the users should
now avoid the DIVREM opcodes too, but I'm not sure
how to test that.

I used the same name as an analysis function in IR
in case we want to expand this to include other
operations.

Another potential use is proposed in D136713.

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/SelectionDAG.h
    llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index 7259e6258df40..a2ec7c4ce33a7 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -2256,6 +2256,23 @@ class SelectionDAG {
   SDValue getNeutralElement(unsigned Opcode, const SDLoc &DL, EVT VT,
                             SDNodeFlags Flags);
 
+  /// Some opcodes may create immediate undefined behavior when used with some
+  /// values (integer division-by-zero for example). Therefore, these operations
+  /// are not generally safe to move around or change.
+  bool isSafeToSpeculativelyExecute(unsigned Opcode) const {
+    switch (Opcode) {
+    case ISD::SDIV:
+    case ISD::SREM:
+    case ISD::SDIVREM:
+    case ISD::UDIV:
+    case ISD::UREM:
+    case ISD::UDIVREM:
+      return false;
+    default:
+      return true;
+    }
+  }
+
 private:
   void InsertNode(SDNode *N);
   bool RemoveNodeFromCSEMaps(SDNode *N);

diff  --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 9af878646ded1..a0075cf533518 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2198,8 +2198,7 @@ static SDValue foldSelectWithIdentityConstant(SDNode *N, SelectionDAG &DAG,
 
   // We can't hoist div/rem because of immediate UB (not speculatable).
   unsigned Opcode = N->getOpcode();
-  if (Opcode == ISD::SDIV || Opcode == ISD::UDIV ||
-      Opcode == ISD::SREM || Opcode == ISD::UREM)
+  if (!DAG.isSafeToSpeculativelyExecute(Opcode))
     return SDValue();
 
   EVT VT = N->getValueType(0);
@@ -23978,9 +23977,7 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N, const SDLoc &DL) {
   // same types of operations that are in the original sequence. We do have to
   // restrict ops like integer div that have immediate UB (eg, div-by-zero)
   // though. This code is adapted from the identical transform in instcombine.
-  if (Opcode != ISD::UDIV && Opcode != ISD::SDIV &&
-      Opcode != ISD::UREM && Opcode != ISD::SREM &&
-      Opcode != ISD::UDIVREM && Opcode != ISD::SDIVREM) {
+  if (DAG.isSafeToSpeculativelyExecute(Opcode)) {
     auto *Shuf0 = dyn_cast<ShuffleVectorSDNode>(LHS);
     auto *Shuf1 = dyn_cast<ShuffleVectorSDNode>(RHS);
     if (Shuf0 && Shuf1 && Shuf0->getMask().equals(Shuf1->getMask()) &&


        


More information about the llvm-commits mailing list