Skip to content

PCL lowering of bool.xor leaves downstream users wired to the pcl.iff intermediate #570

Description

@1sgtpepper

Summary

-llzk-to-pcl emits pcl.iff followed by pcl.not for bool.xor, but a downstream use of the XOR result can still consume the pcl.iff value.

Reproduction

Reproducer run:
https://github.com/Kuhai9801/llzk-lib/actions/runs/28180228869

!F = !felt.type<"goldilocks">

function.def @constrain(%self: !struct.type<@A>, %a: !F, %b: !F, %c: !F) attributes {function.allow_constraint, function.allow_non_native_field_ops} {
  %eq1 = bool.cmp eq(%a, %b) : !F, !F
  %eq2 = bool.cmp eq(%b, %c) : !F, !F
  %xor = bool.xor %eq1, %eq2
  %use = bool.and %xor, %eq1
  function.return
}

Run: llzk-opt -llzk-to-pcl -verify-diagnostics repro.llzk

Expected shape:

%2 = pcl.iff %0, %1
%3 = pcl.not %2
%4 = pcl.and %3, %0

Actual shape:

%2 = pcl.iff %0, %1
%3 = pcl.not %2
%4 = pcl.and %2, %0

Expected

Uses of the LLZK bool.xor result consume the lowered pcl.not result.

Actual

The later pcl.and consumes the pcl.iff result.

Notes

The relevant lowering is in backends/pcl-conv/lib/Transforms/PCLLoweringPass.cpp. The CmpOp NE case has a similar two-step lowering shape.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions