diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c
index 4614ed18f95a6aeff3475c429c1ef84bc5f526c6..1127e9f4d80f041d2564fecbf24ac9f3e8537052 100644
--- a/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d-shader/dxil.c
@@ -306,6 +306,36 @@ enum dxil_cast_code
     CAST_ADDRSPACECAST = 12,
 };
 
+enum dxil_predicate
+{
+    FCMP_FALSE =  0,
+    FCMP_OEQ   =  1,
+    FCMP_OGT   =  2,
+    FCMP_OGE   =  3,
+    FCMP_OLT   =  4,
+    FCMP_OLE   =  5,
+    FCMP_ONE   =  6,
+    FCMP_ORD   =  7,
+    FCMP_UNO   =  8,
+    FCMP_UEQ   =  9,
+    FCMP_UGT   = 10,
+    FCMP_UGE   = 11,
+    FCMP_ULT   = 12,
+    FCMP_ULE   = 13,
+    FCMP_UNE   = 14,
+    FCMP_TRUE  = 15,
+    ICMP_EQ    = 32,
+    ICMP_NE    = 33,
+    ICMP_UGT   = 34,
+    ICMP_UGE   = 35,
+    ICMP_ULT   = 36,
+    ICMP_ULE   = 37,
+    ICMP_SGT   = 38,
+    ICMP_SGE   = 39,
+    ICMP_SLT   = 40,
+    ICMP_SLE   = 41,
+};
+
 struct sm6_pointer_info
 {
     const struct sm6_type *type;
@@ -514,6 +544,7 @@ struct sm6_parser
 
     struct sm6_type *types;
     size_t type_count;
+    struct sm6_type *bool_type;
     struct sm6_type *metadata_type;
     struct sm6_type *handle_type;
 
@@ -1388,6 +1419,8 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6)
                 switch ((width = record->operands[0]))
                 {
                     case 1:
+                        sm6->bool_type = type;
+                        break;
                     case 8:
                     case 16:
                     case 32:
@@ -3416,6 +3449,140 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor
         src_param->reg.data_type = dst->u.reg.data_type;
 }
 
+struct sm6_cmp_info
+{
+    enum vkd3d_shader_opcode handler_idx;
+    bool src_swap;
+};
+
+static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code)
+{
+    static const struct sm6_cmp_info cmp_op_table[] =
+    {
+        [FCMP_FALSE] = {VKD3DSIH_INVALID},
+        [FCMP_OEQ]   = {VKD3DSIH_EQ},
+        [FCMP_OGT]   = {VKD3DSIH_LT, true},
+        [FCMP_OGE]   = {VKD3DSIH_GE},
+        [FCMP_OLT]   = {VKD3DSIH_LT},
+        [FCMP_OLE]   = {VKD3DSIH_GE, true},
+        [FCMP_ONE]   = {VKD3DSIH_NE},
+        [FCMP_ORD]   = {VKD3DSIH_INVALID},
+        [FCMP_UNO]   = {VKD3DSIH_INVALID},
+        [FCMP_UEQ]   = {VKD3DSIH_EQ},
+        [FCMP_UGT]   = {VKD3DSIH_LT, true},
+        [FCMP_UGE]   = {VKD3DSIH_GE},
+        [FCMP_ULT]   = {VKD3DSIH_LT},
+        [FCMP_ULE]   = {VKD3DSIH_GE, true},
+        [FCMP_UNE]   = {VKD3DSIH_NE},
+        [FCMP_TRUE]  = {VKD3DSIH_INVALID},
+
+        [ICMP_EQ]    = {VKD3DSIH_IEQ},
+        [ICMP_NE]    = {VKD3DSIH_INE},
+        [ICMP_UGT]   = {VKD3DSIH_ULT, true},
+        [ICMP_UGE]   = {VKD3DSIH_UGE},
+        [ICMP_ULT]   = {VKD3DSIH_ULT},
+        [ICMP_ULE]   = {VKD3DSIH_UGE, true},
+        [ICMP_SGT]   = {VKD3DSIH_ILT, true},
+        [ICMP_SGE]   = {VKD3DSIH_IGE},
+        [ICMP_SLT]   = {VKD3DSIH_ILT},
+        [ICMP_SLE]   = {VKD3DSIH_IGE, true},
+    };
+
+    return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL;
+}
+
+static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_record *record,
+        struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
+{
+    struct vkd3d_shader_src_param *src_params;
+    const struct sm6_type *type_a, *type_b;
+    const struct sm6_cmp_info *cmp;
+    const struct sm6_value *a, *b;
+    unsigned int i = 0;
+    bool is_int, is_fp;
+    uint64_t code;
+
+    if (!(dst->type = sm6->bool_type))
+    {
+        WARN("Bool type not found.\n");
+        vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
+                "Module does not define a boolean type for comparison results.");
+        return;
+    }
+
+    a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i);
+    b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i);
+    if (!a || !b)
+        return;
+
+    if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6))
+        return;
+
+    type_a = a->type;
+    type_b = b->type;
+    is_int = sm6_type_is_bool_i16_i32_i64(type_a);
+    is_fp = sm6_type_is_floating_point(type_a);
+
+    code = record->operands[i++];
+
+    if ((!is_int && !is_fp) || is_int != (code >= ICMP_EQ))
+    {
+        FIXME("Invalid operation %"PRIu64" on type class %u.\n", code, type_a->class);
+        vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+                "Comparison operation %"PRIu64" on type class %u is invalid.", code, type_a->class);
+        return;
+    }
+
+    if (type_a != type_b)
+    {
+        WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type_a->class,
+                type_a->u.width, type_b->class, type_b->u.width);
+        vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
+                "Type mismatch in comparison operation arguments.");
+    }
+
+    if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VKD3DSIH_INVALID)
+    {
+        FIXME("Unhandled operation %"PRIu64".\n", code);
+        vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+                "Comparison operation %"PRIu64" is unhandled.", code);
+        return;
+    }
+
+    vsir_instruction_init(ins, &sm6->p.location, cmp->handler_idx);
+
+    if (record->operand_count > i)
+    {
+        uint64_t flags = record->operands[i];
+        bool silence_warning = false;
+
+        if (is_fp)
+        {
+            if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA))
+                ins->flags |= VKD3DSI_PRECISE_X;
+            flags &= ~FP_ALLOW_UNSAFE_ALGEBRA;
+            /* SPIR-V FPFastMathMode is only available in the Kernel executon model. */
+            silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL));
+        }
+        if (flags && silence_warning)
+        {
+            TRACE("Ignoring fast FP modifier %#"PRIx64".\n", flags);
+        }
+        else if (flags)
+        {
+            WARN("Ignoring flags %#"PRIx64".\n", flags);
+            vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
+                    "Ignoring flags %#"PRIx64" for a comparison operation.", flags);
+        }
+    }
+
+    src_params = instruction_src_params_alloc(ins, 2, sm6);
+    src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a);
+    src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b);
+
+    instruction_dst_param_init_ssa_scalar(ins, sm6);
+}
+
 static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record,
         struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
 {
@@ -3635,6 +3802,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
             case FUNC_CODE_INST_CAST:
                 sm6_parser_emit_cast(sm6, record, ins, dst);
                 break;
+            case FUNC_CODE_INST_CMP2:
+                sm6_parser_emit_cmp2(sm6, record, ins, dst);
+                break;
             case FUNC_CODE_INST_EXTRACTVAL:
                 sm6_parser_emit_extractval(sm6, record, ins, dst);
                 break;
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 30fda1362f40f2cdfc17decb019d0d79e2ea540e..a38aaf3ef60c534bf9cc2bd643fd2ab4f9ab8c8d 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1411,6 +1411,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty
             return VKD3D_SHADER_COMPONENT_INT;
         case VKD3D_DATA_DOUBLE:
             return VKD3D_SHADER_COMPONENT_DOUBLE;
+        case VKD3D_DATA_BOOL:
+            return VKD3D_SHADER_COMPONENT_BOOL;
         default:
             FIXME("Unhandled data type %#x.\n", data_type);
             /* fall-through */
diff --git a/tests/hlsl/all.shader_test b/tests/hlsl/all.shader_test
index 564cc5b00d7644996c0b96c5153211b0734b95b0..7bdb0dc8291e666cb9b39282fcc3c8c76a3469b3 100644
--- a/tests/hlsl/all.shader_test
+++ b/tests/hlsl/all.shader_test
@@ -11,17 +11,17 @@ float4 main() : sv_target
 
 [test]
 uniform 0 float4 -1.1 1.6 1.3 0.5
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 
 [test]
 uniform 0 float4 0.0 1.6 1.3 0.5
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
 
 [test]
 uniform 0 float4 1.0 0.0 1.3 0.5
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
 
 [pixel shader]
@@ -34,12 +34,12 @@ float4 main() : sv_target
 
 [test]
 uniform 0 float4 1.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 
 [test]
 uniform 0 float4 0.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
 
 [pixel shader]
@@ -53,11 +53,11 @@ float4 main() : sv_target
 [test]
 uniform 0 float4 1.0 2.0 0.0 0.0
 uniform 4 float4 3.0 4.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 
 [test]
 uniform 0 float4 1.0 2.0 0.0 0.0
 uniform 4 float4 0.0 4.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/hlsl/any.shader_test b/tests/hlsl/any.shader_test
index 9b8b922c97a1e8e18d79200c2dc06f5750a630e6..f2298d3a3cf0cce628ce0e93e5aab52d76a04bbc 100644
--- a/tests/hlsl/any.shader_test
+++ b/tests/hlsl/any.shader_test
@@ -8,25 +8,25 @@ float4 main() : sv_target
 
 [test]
 uniform 0 float4 1.0 1.0 1.0 1.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 float4 1.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 float4 0.0 1.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 float4 0.0 0.0 1.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 float4 0.0 0.0 0.0 1.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 float4 0.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
 uniform 0 float4 -1.0 -1.0 -1.0 -1.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 
 [pixel shader]
@@ -39,13 +39,13 @@ float4 main() : sv_target
 
 [test]
 uniform 0 float4 1.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 float4 0.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
 uniform 0 float4 -1.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 
 [require]
@@ -61,22 +61,22 @@ float4 main() : sv_target
 
 [test]
 uniform 0 uint4 1 1 1 1
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 uint4 1 0 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 uint4 0 1 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 uint4 0 0 1 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 uint4 0 0 0 1
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 uint4 0 0 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
 
 [pixel shader]
@@ -89,8 +89,8 @@ float4 main() : sv_target
 
 [test]
 uniform 0 uint4 1 0 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 uint4 0 0 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/hlsl/bool-cast.shader_test b/tests/hlsl/bool-cast.shader_test
index dc75ea376aa8216803ce7a940f362e3f5bbb217b..09ca12e2b7b0ca12611972925611303b5a1f941e 100644
--- a/tests/hlsl/bool-cast.shader_test
+++ b/tests/hlsl/bool-cast.shader_test
@@ -30,7 +30,7 @@ float4 main() : SV_TARGET
 [test]
 uniform 0 float4 0.0 0.0 2.0 4.0
 uniform 4 int4 0 1 0 10
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 10.0, 1.0, 11.0)
 
 
@@ -44,5 +44,5 @@ float4 main() : sv_target
 
 [test]
 uniform 0 uint4 0x00000001 0x00000002 0x80000000 0x00000000
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (2.0, 2.0, 2.0, 0.0)
diff --git a/tests/hlsl/cast-to-float.shader_test b/tests/hlsl/cast-to-float.shader_test
index 7c32acfa36d552345e3a12632f9085afeebc6510..caaf98c0235c04c6b8283f98db120b5c63ccc9f3 100644
--- a/tests/hlsl/cast-to-float.shader_test
+++ b/tests/hlsl/cast-to-float.shader_test
@@ -17,7 +17,7 @@ uniform 0 int -1
 uniform 1 uint 3
 uniform 2 int -2
 uniform 3 float 0.5
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.5, 0.5, 0.5, 0.5)
 
 [pixel shader]
diff --git a/tests/hlsl/cast-to-half.shader_test b/tests/hlsl/cast-to-half.shader_test
index 1579c63f3f23d18eab15a1419291d02bf3de46cc..b8feb67608bdbf34d5cd0c46916fca9fa14daacc 100644
--- a/tests/hlsl/cast-to-half.shader_test
+++ b/tests/hlsl/cast-to-half.shader_test
@@ -17,7 +17,7 @@ uniform 0 int -1
 uniform 1 uint 3
 uniform 2 int -2
 uniform 3 float 0.5
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.5, 0.5, 0.5, 0.5)
 
 [pixel shader]
diff --git a/tests/hlsl/cast-to-int.shader_test b/tests/hlsl/cast-to-int.shader_test
index ae566a0394198d5ebd1d17799dad66d113c4296c..3e850fb5bfd244d79f239f07531066751598e214 100644
--- a/tests/hlsl/cast-to-int.shader_test
+++ b/tests/hlsl/cast-to-int.shader_test
@@ -23,7 +23,7 @@ uniform 0 float 2.6
 uniform 1 int -2
 uniform 2 int -2
 uniform 3 float -3.6
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.5, 0.5, 0.5, 0.5)
 
 [pixel shader]
diff --git a/tests/hlsl/cast-to-uint.shader_test b/tests/hlsl/cast-to-uint.shader_test
index dece99b7525d09091b68d9002cea8c897f5bafbd..07479984a1507b2e78e9ba2c917fa8a4455ed1e5 100644
--- a/tests/hlsl/cast-to-uint.shader_test
+++ b/tests/hlsl/cast-to-uint.shader_test
@@ -23,7 +23,7 @@ uniform 0 float 2.6
 uniform 1 int 2
 uniform 2 int -2
 uniform 3 float -3.6
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.5, 0.5, 0.5, 0.5)
 
 [pixel shader]
diff --git a/tests/hlsl/sign.shader_test b/tests/hlsl/sign.shader_test
index 54b9536812a80059e84fee1d832f163dd7f38930..5d8b4316848e1673ed1efe4d894e75635449e48d 100644
--- a/tests/hlsl/sign.shader_test
+++ b/tests/hlsl/sign.shader_test
@@ -8,13 +8,13 @@ float4 main() : sv_target
 
 [test]
 uniform 0 float4 1.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 uniform 0 float4 -1.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (-1.0, -1.0, -1.0, -1.0)
 uniform 0 float4 0.0 0.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0.0, 0.0, 0.0, 0.0)
 
 [pixel shader]
@@ -27,7 +27,7 @@ float4 main() : sv_target
 
 [test]
 uniform 0 float4 1.0 2.0 3.0 4.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 
 [pixel shader]
@@ -41,7 +41,7 @@ float4 main() : sv_target
 [test]
 uniform 0 float4 1.0 2.0 0.0 0.0
 uniform 4 float4 3.0 4.0 0.0 0.0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1.0, 1.0, 1.0, 1.0)
 
 [require]
@@ -58,13 +58,13 @@ float4 main() : sv_target
 
 [test]
 uniform 0 int4 1 0 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1, 1, 1, 1)
 uniform 0 int4 -1 0 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (-1, -1, -1, -1)
 uniform 0 int4 0 0 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (0, 0, 0, 0)
 
 [pixel shader]
@@ -77,7 +77,7 @@ float4 main() : sv_target
 
 [test]
 uniform 0 int4 1 2 3 4
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1, 1, 1, 1)
 
 [pixel shader]
@@ -91,5 +91,5 @@ float4 main() : sv_target
 [test]
 uniform 0 int4 1 2 0 0
 uniform 4 int4 3 4 0 0
-todo(sm>=6) draw quad
+draw quad
 probe all rgba (1, 1, 1, 1)