--- /dev/null
+#ifndef __COCO_IR_RELU_H__
+#define __COCO_IR_RELU_H__
+
+#include "coco/IR/Op.h"
+
+namespace coco
+{
+
+/**
+ * @brief Apply ReLU over elements
+ */
+class ReLU : public Op
+{
+public:
+ explicit ReLU(const PtrLink<Op, Instr> *);
+
+public:
+ ReLU(const ReLU &) = delete;
+ ReLU(ReLU &&) = delete;
+
+public:
+ std::set<Object *> uses(void) const override;
+
+public:
+ ReLU *asReLU(void) override { return this; }
+ const ReLU *asReLU(void) const override { return this; }
+
+private:
+ void get(const PtrLink<Op, Instr> **out) const override { *out = _op_link; }
+
+private:
+ const PtrLink<Op, Instr> *const _op_link;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_RELU_H__
--- /dev/null
+#include "coco/IR/ReLU.h"
+
+namespace coco
+{
+
+ReLU::ReLU(const PtrLink<Op, Instr> *op_link) : _op_link{op_link}
+{
+ // DO NOTHING
+}
+
+std::set<Object *> ReLU::uses(void) const
+{
+ // NOTE ReLU accesses no object
+ std::set<Object *> res;
+ return res;
+}
+
+} // namespace coco
--- /dev/null
+#include "coco/IR/ReLU.h"
+
+#include <memory>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct IsReLU : public coco::Op::DefaultVisitor<bool>
+{
+ bool visit(const coco::ReLU *) override { return true; }
+};
+
+class ReLUTest : public ::testing::Test
+{
+public:
+ ReLUTest()
+ {
+ // DO NOTHING
+ }
+
+protected:
+ coco::ReLU *allocate(void)
+ {
+ auto op = new coco::ReLU{&op_link};
+ _allocated.emplace_back(op);
+ return op;
+ }
+
+protected:
+ coco::PtrLink<coco::Op, coco::Instr> op_link;
+
+private:
+ std::vector<std::unique_ptr<coco::ReLU>> _allocated;
+};
+} // namespace
+
+TEST_F(ReLUTest, initialization)
+{
+ auto op = allocate();
+
+ // uses() should be empty on construction
+ ASSERT_EQ(op->uses().size(), 0);
+ // parent() should be nullptr on construction
+ ASSERT_EQ(op->parent(), nullptr);
+}
+
+TEST_F(ReLUTest, asReLU)
+{
+ auto op = allocate();
+
+ coco::Op *mutable_base = op;
+ const coco::Op *immutable_base = op;
+
+ ASSERT_EQ(mutable_base->asReLU(), op);
+ ASSERT_EQ(mutable_base->asReLU(), immutable_base->asReLU());
+}
+
+TEST_F(ReLUTest, accept)
+{
+ // Test 'ReLU' class
+ auto op = allocate();
+
+ coco::ReLU *mutable_ptr = op;
+ const coco::ReLU *immutable_ptr = op;
+
+ ASSERT_TRUE(mutable_ptr->accept(IsReLU{}));
+ ASSERT_TRUE(immutable_ptr->accept(IsReLU{}));
+}