@@ -13,7 +13,7 @@ use crate::ast::contract::function::expression::ExpressionEmitter;
1313use crate :: ast:: contract:: function:: expression:: operator:: Operator ;
1414
1515impl < ' state , ' context , ' block > ExpressionEmitter < ' state , ' context , ' block > {
16- /// Emits a `sol.cmp` comparison, cast to `ui256` via `sol.cast` .
16+ /// Emits a `sol.cmp` comparison.
1717 ///
1818 /// # Errors
1919 ///
@@ -27,7 +27,6 @@ impl<'state, 'context, 'block> ExpressionEmitter<'state, 'context, 'block> {
2727 ) -> anyhow:: Result < ( Value < ' context , ' block > , BlockRef < ' context , ' block > ) > {
2828 let ( lhs, block) = self . emit_value ( left, block) ?;
2929 let ( rhs, block) = self . emit_value ( right, block) ?;
30- // Cast both operands to a common type for comparison.
3130 let common_type = if lhs. r#type ( ) == rhs. r#type ( ) {
3231 lhs. r#type ( )
3332 } else {
@@ -37,14 +36,13 @@ impl<'state, 'context, 'block> ExpressionEmitter<'state, 'context, 'block> {
3736 let rhs = self . state . builder . emit_sol_cast ( rhs, common_type, & block) ;
3837 let predicate = Operator :: from_str ( operator) ?. cmp_predicate ( ) ;
3938 let comparison = self . state . builder . emit_sol_cmp ( lhs, rhs, predicate, & block) ;
40- let ui256 = self . state . builder . get_type ( solx_mlir:: Builder :: UI256 ) ;
41- let value = self . state . builder . emit_sol_cast ( comparison, ui256, & block) ;
42- Ok ( ( value, block) )
39+ Ok ( ( comparison, block) )
4340 }
4441
45- /// Emits short-circuit `&&` using value-producing `scf .if`.
42+ /// Emits short-circuit `&&` using `sol .if` with an `i1` alloca .
4643 ///
47- /// Result is always a canonical boolean (0 or 1).
44+ /// Matches solc's pattern: allocate a boolean result variable, default to
45+ /// `false`, and only evaluate the RHS when the LHS is true.
4846 ///
4947 /// # Errors
5048 ///
@@ -58,28 +56,39 @@ impl<'state, 'context, 'block> ExpressionEmitter<'state, 'context, 'block> {
5856 let ( lhs, block) = self . emit_value ( left, block) ?;
5957 let lhs_bool = self . emit_is_nonzero ( lhs, & block) ;
6058
61- let ui256 = self . state . builder . get_type ( solx_mlir:: Builder :: UI256 ) ;
62- let ( then_block, else_block, result) =
63- self . state . builder . emit_scf_if ( lhs_bool, ui256, & block) ?;
59+ let i1_type = self . state . builder . get_type ( solx_mlir:: Builder :: I1 ) ;
60+ let result_ptr = self . state . builder . emit_sol_alloca ( i1_type, & block) ;
61+ // TODO: solc uses `arith.constant false` here; consider switching to
62+ // arith dialect for i1 constants to match solc output exactly.
63+ let false_val = self . state . builder . emit_sol_constant ( 0 , i1_type, & block) ;
64+ self . state
65+ . builder
66+ . emit_sol_store ( false_val, result_ptr, & block) ;
6467
65- // Then: LHS was true — evaluate RHS and yield normalized result.
68+ let ( then_block, else_block) = self . state . builder . emit_sol_if ( lhs_bool, & block) ;
69+
70+ // Then: LHS was true — evaluate RHS and store result.
6671 let ( rhs, then_end) = self . emit_value ( right, then_block) ?;
6772 let rhs_bool = self . emit_is_nonzero ( rhs, & then_end) ;
68- let rhs_normalized = self . state . builder . emit_sol_cast ( rhs_bool, ui256, & then_end) ;
6973 self . state
7074 . builder
71- . emit_scf_yield ( & [ rhs_normalized] , & then_end) ;
75+ . emit_sol_store ( rhs_bool, result_ptr, & then_end) ;
76+ self . state . builder . emit_sol_yield ( & then_end) ;
7277
73- // Else: LHS was false — yield 0.
74- let zero = self . state . builder . emit_sol_constant ( 0 , ui256, & else_block) ;
75- self . state . builder . emit_scf_yield ( & [ zero] , & else_block) ;
78+ // Else: LHS was false — result stays false.
79+ self . state . builder . emit_sol_yield ( & else_block) ;
7680
81+ let result = self
82+ . state
83+ . builder
84+ . emit_sol_load ( result_ptr, i1_type, & block) ?;
7785 Ok ( ( result, block) )
7886 }
7987
80- /// Emits short-circuit `||` using value-producing `scf .if`.
88+ /// Emits short-circuit `||` using `sol .if` with an `i1` alloca .
8189 ///
82- /// Result is always a canonical boolean (0 or 1).
90+ /// Matches solc's pattern: allocate a boolean result variable, default to
91+ /// `true`, and only evaluate the RHS when the LHS is false.
8392 ///
8493 /// # Errors
8594 ///
@@ -93,22 +102,30 @@ impl<'state, 'context, 'block> ExpressionEmitter<'state, 'context, 'block> {
93102 let ( lhs, block) = self . emit_value ( left, block) ?;
94103 let lhs_bool = self . emit_is_nonzero ( lhs, & block) ;
95104
96- let ui256 = self . state . builder . get_type ( solx_mlir:: Builder :: UI256 ) ;
97- let ( then_block, else_block, result) =
98- self . state . builder . emit_scf_if ( lhs_bool, ui256, & block) ?;
105+ let i1_type = self . state . builder . get_type ( solx_mlir:: Builder :: I1 ) ;
106+ let result_ptr = self . state . builder . emit_sol_alloca ( i1_type, & block) ;
107+ let true_val = self . state . builder . emit_sol_constant ( 1 , i1_type, & block) ;
108+ self . state
109+ . builder
110+ . emit_sol_store ( true_val, result_ptr, & block) ;
99111
100- // Then: LHS was true — yield 1.
101- let one = self . state . builder . emit_sol_constant ( 1 , ui256, & then_block) ;
102- self . state . builder . emit_scf_yield ( & [ one] , & then_block) ;
112+ let ( then_block, else_block) = self . state . builder . emit_sol_if ( lhs_bool, & block) ;
103113
104- // Else: LHS was false — evaluate RHS and yield normalized result.
114+ // Then: LHS was true — result stays true.
115+ self . state . builder . emit_sol_yield ( & then_block) ;
116+
117+ // Else: LHS was false — evaluate RHS and store result.
105118 let ( rhs, else_end) = self . emit_value ( right, else_block) ?;
106119 let rhs_bool = self . emit_is_nonzero ( rhs, & else_end) ;
107- let rhs_normalized = self . state . builder . emit_sol_cast ( rhs_bool, ui256, & else_end) ;
108120 self . state
109121 . builder
110- . emit_scf_yield ( & [ rhs_normalized] , & else_end) ;
122+ . emit_sol_store ( rhs_bool, result_ptr, & else_end) ;
123+ self . state . builder . emit_sol_yield ( & else_end) ;
111124
125+ let result = self
126+ . state
127+ . builder
128+ . emit_sol_load ( result_ptr, i1_type, & block) ?;
112129 Ok ( ( result, block) )
113130 }
114131}
0 commit comments