diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 5951bdc7bb..20a1a50ef8 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -212,6 +212,103 @@ Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) {
     return value;
 }
 
+Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
+    static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
+        {PredCondition::LessThan, OperationCode::LogicalFLessThan},
+        {PredCondition::Equal, OperationCode::LogicalFEqual},
+        {PredCondition::LessEqual, OperationCode::LogicalFLessEqual},
+        {PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan},
+        {PredCondition::NotEqual, OperationCode::LogicalFNotEqual},
+        {PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual},
+        {PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan},
+        {PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual},
+        {PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual},
+        {PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan},
+        {PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual}};
+
+    const auto comparison{PredicateComparisonTable.find(condition)};
+    UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
+                         "Unknown predicate comparison operation");
+
+    Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b);
+
+    if (condition == PredCondition::LessThanWithNan ||
+        condition == PredCondition::NotEqualWithNan ||
+        condition == PredCondition::LessEqualWithNan ||
+        condition == PredCondition::GreaterThanWithNan ||
+        condition == PredCondition::GreaterEqualWithNan) {
+
+        predicate = Operation(OperationCode::LogicalOr, predicate,
+                              Operation(OperationCode::LogicalFIsNan, op_a));
+        predicate = Operation(OperationCode::LogicalOr, predicate,
+                              Operation(OperationCode::LogicalFIsNan, op_b));
+    }
+
+    return predicate;
+}
+
+Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a,
+                                             Node op_b) {
+    static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
+        {PredCondition::LessThan, OperationCode::LogicalILessThan},
+        {PredCondition::Equal, OperationCode::LogicalIEqual},
+        {PredCondition::LessEqual, OperationCode::LogicalILessEqual},
+        {PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan},
+        {PredCondition::NotEqual, OperationCode::LogicalINotEqual},
+        {PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual},
+        {PredCondition::LessThanWithNan, OperationCode::LogicalILessThan},
+        {PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual},
+        {PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual},
+        {PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan},
+        {PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual}};
+
+    const auto comparison{PredicateComparisonTable.find(condition)};
+    UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
+                         "Unknown predicate comparison operation");
+
+    Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, op_a, op_b);
+
+    UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
+                             condition == PredCondition::NotEqualWithNan ||
+                             condition == PredCondition::LessEqualWithNan ||
+                             condition == PredCondition::GreaterThanWithNan ||
+                             condition == PredCondition::GreaterEqualWithNan,
+                         "NaN comparisons for integers are not implemented");
+    return predicate;
+}
+
+Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition,
+                                          const MetaHalfArithmetic& meta, Node op_a, Node op_b) {
+
+    UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
+                             condition == PredCondition::NotEqualWithNan ||
+                             condition == PredCondition::LessEqualWithNan ||
+                             condition == PredCondition::GreaterThanWithNan ||
+                             condition == PredCondition::GreaterEqualWithNan,
+                         "Unimplemented NaN comparison for half floats");
+
+    static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
+        {PredCondition::LessThan, OperationCode::LogicalHLessThan},
+        {PredCondition::Equal, OperationCode::LogicalHEqual},
+        {PredCondition::LessEqual, OperationCode::LogicalHLessEqual},
+        {PredCondition::GreaterThan, OperationCode::LogicalHGreaterThan},
+        {PredCondition::NotEqual, OperationCode::LogicalHNotEqual},
+        {PredCondition::GreaterEqual, OperationCode::LogicalHGreaterEqual},
+        {PredCondition::LessThanWithNan, OperationCode::LogicalHLessThan},
+        {PredCondition::NotEqualWithNan, OperationCode::LogicalHNotEqual},
+        {PredCondition::LessEqualWithNan, OperationCode::LogicalHLessEqual},
+        {PredCondition::GreaterThanWithNan, OperationCode::LogicalHGreaterThan},
+        {PredCondition::GreaterEqualWithNan, OperationCode::LogicalHGreaterEqual}};
+
+    const auto comparison{PredicateComparisonTable.find(condition)};
+    UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
+                         "Unknown predicate comparison operation");
+
+    const Node predicate = Operation(comparison->second, meta, op_a, op_b);
+
+    return predicate;
+}
+
 void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) {
     bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src));
 }
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index f3b17d2eba..372ed10da9 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -660,6 +660,15 @@ private:
     /// Conditionally absolute/negated half float pair. Absolute is applied first
     Node GetOperandAbsNegHalf(Node value, bool absolute, bool negate);
 
+    /// Returns a predicate comparing two floats
+    Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b);
+    /// Returns a predicate comparing two integers
+    Node GetPredicateComparisonInteger(Tegra::Shader::PredCondition condition, bool is_signed,
+                                       Node op_a, Node op_b);
+    /// Returns a predicate comparing two half floats. meta consumes how both pairs will be compared
+    Node GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition,
+                                    const MetaHalfArithmetic& meta, Node op_a, Node op_b);
+
     template <typename... T>
     inline Node Operation(OperationCode code, const T*... operands) {
         return StoreNode(OperationNode(code, operands...));