@@ -573,14 +573,32 @@ fn process_icmp_variables(
573573) -> Result < ( ) , Error > {
574574 let expr_left = expr_from_operand ( variables, operand) ?;
575575 let expr_right = expr_from_operand ( variables, operand1) ?;
576- let expr = eq_expr ( expr_left, expr_right) ?;
577- match condition_code {
578- ConditionCode :: Eq => store_expr_in_variable ( variables, variable, expr) ,
579- ConditionCode :: Ne => store_expr_in_variable ( variables, variable, expr. negate ( ) ) ,
580- condition_code => Err ( Error :: UnsupportedFeature ( format ! (
581- "unsupported condition code in icmp: {condition_code:?}"
582- ) ) ) ,
583- }
576+ let expr = match condition_code {
577+ ConditionCode :: Eq => eq_expr ( expr_left, expr_right) ?,
578+ ConditionCode :: Ne => eq_expr ( expr_left, expr_right) ?. negate ( ) ,
579+ ConditionCode :: Slt => Expr :: Bool ( BoolExpr :: BinOp (
580+ expr_left. into ( ) ,
581+ expr_right. into ( ) ,
582+ ComparisonOp :: Lt ,
583+ ) ) ,
584+ ConditionCode :: Sgt => Expr :: Bool ( BoolExpr :: BinOp (
585+ expr_left. into ( ) ,
586+ expr_right. into ( ) ,
587+ ComparisonOp :: Gt ,
588+ ) ) ,
589+ ConditionCode :: Sle => Expr :: Bool ( BoolExpr :: BinOp (
590+ expr_left. into ( ) ,
591+ expr_right. into ( ) ,
592+ ComparisonOp :: Le ,
593+ ) ) ,
594+ ConditionCode :: Sge => Expr :: Bool ( BoolExpr :: BinOp (
595+ expr_left. into ( ) ,
596+ expr_right. into ( ) ,
597+ ComparisonOp :: Ge ,
598+ ) ) ,
599+ } ;
600+ store_expr_in_variable ( variables, variable, expr) ?;
601+ Ok ( ( ) )
584602}
585603
586604fn process_fcmp_variables (
@@ -595,7 +613,34 @@ fn process_fcmp_variables(
595613 let expr = match condition_code {
596614 FcmpConditionCode :: False => BoolExpr :: LiteralBool ( false ) ,
597615 FcmpConditionCode :: True => BoolExpr :: LiteralBool ( true ) ,
598- cmp => BoolExpr :: BinOp ( expr_left. into ( ) , expr_right. into ( ) , cmp. to_string ( ) ) ,
616+ FcmpConditionCode :: OrderedAndEqual | FcmpConditionCode :: UnorderedOrEqual => {
617+ BoolExpr :: BinOp ( expr_left. into ( ) , expr_right. into ( ) , ComparisonOp :: Eq )
618+ }
619+ FcmpConditionCode :: OrderedAndNotEqual | FcmpConditionCode :: UnorderedOrNotEqual => {
620+ BoolExpr :: BinOp ( expr_left. into ( ) , expr_right. into ( ) , ComparisonOp :: Ne )
621+ }
622+ FcmpConditionCode :: OrderedAndLessThan | FcmpConditionCode :: UnorderedOrLessThan => {
623+ BoolExpr :: BinOp ( expr_left. into ( ) , expr_right. into ( ) , ComparisonOp :: Lt )
624+ }
625+ FcmpConditionCode :: OrderedAndGreaterThan | FcmpConditionCode :: UnorderedOrGreaterThan => {
626+ BoolExpr :: BinOp ( expr_left. into ( ) , expr_right. into ( ) , ComparisonOp :: Gt )
627+ }
628+ FcmpConditionCode :: OrderedAndLessThanOrEqual
629+ | FcmpConditionCode :: UnorderedOrLessThanOrEqual => {
630+ BoolExpr :: BinOp ( expr_left. into ( ) , expr_right. into ( ) , ComparisonOp :: Le )
631+ }
632+ FcmpConditionCode :: OrderedAndGreaterThanOrEqual
633+ | FcmpConditionCode :: UnorderedOrGreaterThanOrEqual => {
634+ BoolExpr :: BinOp ( expr_left. into ( ) , expr_right. into ( ) , ComparisonOp :: Ge )
635+ }
636+ FcmpConditionCode :: Ordered | FcmpConditionCode :: Unordered => {
637+ // These don't map to a simple binary comparison; treat as opaque.
638+ return store_expr_in_variable (
639+ variables,
640+ variable,
641+ Expr :: Rich ( RichExpr :: FunctionOf ( vec ! [ expr_left, expr_right] ) ) ,
642+ ) ;
643+ }
599644 } ;
600645 store_expr_in_variable ( variables, variable, Expr :: Bool ( expr) ) ?;
601646 Ok ( ( ) )
@@ -620,7 +665,7 @@ fn eq_expr(expr_left: Expr, expr_right: Expr) -> Result<Expr, Error> {
620665 filter : ( true , false , false , true ) , // 00 and 11
621666 } )
622667 }
623- ( left, right) => Expr :: Rich ( RichExpr :: FunctionOf ( vec ! [ left, right] ) ) ,
668+ ( left, right) => Expr :: Bool ( BoolExpr :: BinOp ( left. into ( ) , right. into ( ) , ComparisonOp :: Eq ) ) ,
624669 } )
625670}
626671
@@ -660,6 +705,42 @@ enum Expr {
660705 Bool ( BoolExpr ) ,
661706}
662707
708+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
709+ enum ComparisonOp {
710+ Eq ,
711+ Ne ,
712+ Lt ,
713+ Gt ,
714+ Le ,
715+ Ge ,
716+ }
717+
718+ impl ComparisonOp {
719+ fn negate ( self ) -> Self {
720+ match self {
721+ Self :: Eq => Self :: Ne ,
722+ Self :: Ne => Self :: Eq ,
723+ Self :: Lt => Self :: Ge ,
724+ Self :: Gt => Self :: Le ,
725+ Self :: Le => Self :: Gt ,
726+ Self :: Ge => Self :: Lt ,
727+ }
728+ }
729+ }
730+
731+ impl Display for ComparisonOp {
732+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
733+ match self {
734+ Self :: Eq => write ! ( f, "==" ) ,
735+ Self :: Ne => write ! ( f, "!=" ) ,
736+ Self :: Lt => write ! ( f, "<" ) ,
737+ Self :: Gt => write ! ( f, ">" ) ,
738+ Self :: Le => write ! ( f, "<=" ) ,
739+ Self :: Ge => write ! ( f, ">=" ) ,
740+ }
741+ }
742+ }
743+
663744#[ derive( Debug , Clone , PartialEq ) ]
664745enum BoolExpr {
665746 Result ( usize ) ,
@@ -670,7 +751,7 @@ enum BoolExpr {
670751 filter : ( bool , bool , bool , bool ) ,
671752 } ,
672753 LiteralBool ( bool ) ,
673- BinOp ( Box < Expr > , Box < Expr > , String ) ,
754+ BinOp ( Box < Expr > , Box < Expr > , ComparisonOp ) ,
674755}
675756
676757/// These could be of type boolean, we just don't necessary know
@@ -695,6 +776,9 @@ impl Expr {
695776 filter : ( !f00, !f01, !f10, !f11) ,
696777 } )
697778 }
779+ Expr :: Bool ( BoolExpr :: BinOp ( left, right, op) ) => {
780+ Expr :: Bool ( BoolExpr :: BinOp ( left. clone ( ) , right. clone ( ) , op. negate ( ) ) )
781+ }
698782 expr => Expr :: Rich ( RichExpr :: FunctionOf ( expr. flat_exprs ( ) ) ) ,
699783 }
700784 }
@@ -1328,6 +1412,7 @@ fn known_gate_spec(callable_name: &str) -> Option<GateSpec<'static>> {
13281412 "__quantum__qis__z__body" => GateSpec :: single_qubit_gate ( "Z" ) ,
13291413 "__quantum__qis__s__body" => GateSpec :: single_qubit_gate ( "S" ) ,
13301414 "__quantum__qis__s__adj" => GateSpec :: single_qubit_gate_adjoint ( "S" ) ,
1415+ "__quantum__qis__sx__body" => GateSpec :: single_qubit_gate ( "SX" ) ,
13311416 "__quantum__qis__t__body" => GateSpec :: single_qubit_gate ( "T" ) ,
13321417 "__quantum__qis__t__adj" => GateSpec :: single_qubit_gate_adjoint ( "T" ) ,
13331418 "__quantum__qis__h__body" => GateSpec :: single_qubit_gate ( "H" ) ,
0 commit comments