diff --git a/src/asahi/compiler/agx_optimizer.c b/src/asahi/compiler/agx_optimizer.c index 915ebb804d6..ac49703b072 100644 --- a/src/asahi/compiler/agx_optimizer.c +++ b/src/asahi/compiler/agx_optimizer.c @@ -292,14 +292,14 @@ agx_optimizer_copyprop(agx_context *ctx, agx_instr **defs, agx_instr *I) /* * Fuse conditions into if. Specifically, acts on if_icmp and fuses: * - * if_icmp(cmp(x, y, *), 0, ne) -> if_cmp(x, y, *) + * if_icmp(cmp(x, y, *), 0, ne/eq) -> if_cmp(x, y, *) */ static void agx_optimizer_if_cmp(agx_instr **defs, agx_instr *I) { /* Check for unfused if */ if (!agx_is_equiv(I->src[1], agx_zero()) || I->icond != AGX_ICOND_UEQ || - !I->invert_cond || I->src[0].type != AGX_INDEX_NORMAL) + I->src[0].type != AGX_INDEX_NORMAL) return; /* Check for condition */ @@ -310,7 +310,7 @@ agx_optimizer_if_cmp(agx_instr **defs, agx_instr *I) /* Fuse */ I->src[0] = def->src[0]; I->src[1] = def->src[1]; - I->invert_cond = def->invert_cond; + I->invert_cond = def->invert_cond ^ !I->invert_cond; if (def->op == AGX_OPCODE_ICMP) { I->op = AGX_OPCODE_IF_ICMP; diff --git a/src/asahi/compiler/test/test-optimizer.cpp b/src/asahi/compiler/test/test-optimizer.cpp index 4dbca759cf0..77b09c120b5 100644 --- a/src/asahi/compiler/test/test-optimizer.cpp +++ b/src/asahi/compiler/test/test-optimizer.cpp @@ -365,3 +365,27 @@ TEST_F(Optimizer, IfInverted) 1, AGX_ICOND_UEQ, false, NULL), agx_if_icmp(b, hx, agx_zero(), 1, AGX_ICOND_UEQ, true, NULL)); } + +TEST_F(Optimizer, IfInvertedCondition) +{ + CASE_NO_RETURN( + agx_if_icmp( + b, + agx_xor(b, agx_icmp(b, wx, wy, AGX_ICOND_UEQ, true), agx_immediate(1)), + agx_zero(), 1, AGX_ICOND_UEQ, true, NULL), + agx_if_icmp(b, wx, wy, 1, AGX_ICOND_UEQ, false, NULL)); + + CASE_NO_RETURN( + agx_if_icmp( + b, + agx_xor(b, agx_fcmp(b, wx, wy, AGX_FCOND_EQ, true), agx_immediate(1)), + agx_zero(), 1, AGX_ICOND_UEQ, true, NULL), + agx_if_fcmp(b, wx, wy, 1, AGX_FCOND_EQ, false, NULL)); + + CASE_NO_RETURN( + agx_if_icmp( + b, + agx_xor(b, agx_fcmp(b, hx, hy, AGX_FCOND_LT, false), agx_immediate(1)), + agx_zero(), 1, AGX_ICOND_UEQ, true, NULL), + agx_if_fcmp(b, hx, hy, 1, AGX_FCOND_LT, true, NULL)); +}