[llvm] [IR] Store fast-math flags in subclasses of Instruction (PR #191190)

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 13 01:09:09 PDT 2026


================
@@ -435,6 +440,66 @@ BinaryOperator *BinaryOperator::CreateDisjoint(BinaryOps Opc, Value *V1,
   return BO;
 }
 
+/// Binary operators support fast-math flags, users should not use this
+/// class directly, BinaryOperator can automatic create instructions with
+/// correct type.
+class FPBinaryOperator : public BinaryOperator, public FastMathFlagsStorage {
+  friend class Instruction;
+  friend class BinaryOperator;
+  LLVM_ABI FPBinaryOperator *cloneImpl() const;
+  using BinaryOperator::BinaryOperator;
+
+  LLVM_ABI static FPBinaryOperator *
+  Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name = Twine(),
+         InsertPosition InsertBefore = nullptr);
+
+public:
+  static bool classof(const Instruction *I) {
+    switch (I->getOpcode()) {
+    case Instruction::FAdd:
+    case Instruction::FSub:
+    case Instruction::FMul:
+    case Instruction::FDiv:
+    case Instruction::FRem:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  static bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+#define HANDLE_BINARY_INST(N, OPC, CLASS)                                      \
+  BinaryOperator *BinaryOperator::Create##OPC(Value *V1, Value *V2,            \
+                                              const Twine &Name) {             \
+    if constexpr (Instruction::OPC == Instruction::FAdd ||                     \
+                  Instruction::OPC == Instruction::FSub ||                     \
+                  Instruction::OPC == Instruction::FMul ||                     \
+                  Instruction::OPC == Instruction::FDiv ||                     \
+                  Instruction::OPC == Instruction::FRem)                       \
+      return FPBinaryOperator::Create(Instruction::OPC, V1, V2, Name);         \
+    else                                                                       \
+      return Create(Instruction::OPC, V1, V2, Name);                           \
+  }
+#include "llvm/IR/Instruction.def"
+#define HANDLE_BINARY_INST(N, OPC, CLASS)                                      \
+  BinaryOperator *BinaryOperator::Create##OPC(                                 \
+      Value *V1, Value *V2, const Twine &Name, InsertPosition InsertBefore) {  \
+    if constexpr (Instruction::OPC == Instruction::FAdd ||                     \
+                  Instruction::OPC == Instruction::FSub ||                     \
+                  Instruction::OPC == Instruction::FMul ||                     \
+                  Instruction::OPC == Instruction::FDiv ||                     \
+                  Instruction::OPC == Instruction::FRem)                       \
+      return FPBinaryOperator::Create(Instruction::OPC, V1, V2, Name,          \
+                                      InsertBefore);                           \
----------------
aengelke wrote:

Very ugly, especially in a header that is included ~everywhere. Class name is known from HANDLE_BINARY_INST, just use that? Also add `inline` keyword.

https://github.com/llvm/llvm-project/pull/191190


More information about the llvm-commits mailing list