@@ -141,6 +141,72 @@ macro_rules! simple_op {
141141 } ;
142142}
143143
144+ // shl and shr allow different types as their operands
145+ macro_rules! simple_shift_op {
146+ (
147+ $func_name: ident
148+ $( , int: $inst_int: ident) ?
149+ $( , uint: $inst_uint: ident) ?
150+ $( , sint: $inst_sint: ident) ?
151+ $( , fold_const {
152+ $( int( $int_lhs: ident, $int_rhs: ident) => $fold_int: expr; ) ?
153+ $( uint( $uint_lhs: ident, $uint_rhs: ident) => $fold_uint: expr; ) ?
154+ $( sint( $sint_lhs: ident, $sint_rhs: ident) => $fold_sint: expr; ) ?
155+ } ) ?
156+ ) => {
157+ fn $func_name( & mut self , lhs: Self :: Value , rhs: Self :: Value ) -> Self :: Value {
158+ let result_type = lhs. ty;
159+
160+ $(
161+ #[ allow( unreachable_patterns, clippy:: collapsible_match) ]
162+ if let Some ( const_lhs) = self . try_get_const_value( lhs)
163+ && let Some ( const_rhs) = self . try_get_const_value( rhs)
164+ {
165+ #[ allow( unreachable_patterns) ]
166+ match ( const_lhs, const_rhs) {
167+ $(
168+ ( ConstValue :: Unsigned ( $int_lhs) , ConstValue :: Unsigned ( $int_rhs) ) => return self . const_uint_big( result_type, $fold_int) ,
169+ ( ConstValue :: Unsigned ( $int_lhs) , ConstValue :: Signed ( $int_rhs) ) => return self . const_uint_big( result_type, $fold_int) ,
170+ ( ConstValue :: Signed ( $int_lhs) , ConstValue :: Unsigned ( $int_rhs) ) => return self . const_uint_big( result_type, $fold_int as u128 ) ,
171+ ( ConstValue :: Signed ( $int_lhs) , ConstValue :: Signed ( $int_rhs) ) => return self . const_uint_big( result_type, $fold_int as u128 ) ,
172+ ) ?
173+ $(
174+ ( ConstValue :: Unsigned ( $uint_lhs) , ConstValue :: Unsigned ( $uint_rhs) ) => return self . const_uint_big( result_type, $fold_uint) ,
175+ ( ConstValue :: Unsigned ( $uint_lhs) , ConstValue :: Signed ( $uint_rhs) ) => return self . const_uint_big( result_type, $fold_uint) ,
176+ ) ?
177+ $(
178+ ( ConstValue :: Signed ( $sint_lhs) , ConstValue :: Unsigned ( $sint_rhs) ) => return self . const_uint_big( result_type, $fold_sint as u128 ) ,
179+ ( ConstValue :: Signed ( $sint_lhs) , ConstValue :: Signed ( $sint_rhs) ) => return self . const_uint_big( result_type, $fold_sint as u128 ) ,
180+ ) ?
181+ _ => ( ) ,
182+ }
183+ }
184+ ) ?
185+
186+ match self . lookup_type( result_type) {
187+ $( SpirvType :: Integer ( _, _) => {
188+ self . emit( )
189+ . $inst_int( result_type, None , lhs. def( self ) , rhs. def( self ) )
190+ } ) ?
191+ $( SpirvType :: Integer ( _, false ) => {
192+ self . emit( )
193+ . $inst_uint( result_type, None , lhs. def( self ) , rhs. def( self ) )
194+ } ) ?
195+ $( SpirvType :: Integer ( _, true ) => {
196+ self . emit( )
197+ . $inst_sint( result_type, None , lhs. def( self ) , rhs. def( self ) )
198+ } ) ?
199+ o => self . fatal( format!(
200+ concat!( stringify!( $func_name) , "() not implemented for type {}" ) ,
201+ o. debug( result_type, self )
202+ ) ) ,
203+ }
204+ . unwrap( )
205+ . with_type( result_type)
206+ }
207+ } ;
208+ }
209+
144210macro_rules! simple_uni_op {
145211 (
146212 $func_name: ident
@@ -1533,24 +1599,24 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
15331599 simple_op ! { frem_algebraic, float: f_rem} // algebraic=normal
15341600 simple_shift_op ! {
15351601 shl,
1536- int: shift_left_logical
1537- // fold_const {
1538- // int(a, b) => a.wrapping_shl(b as u32);
1539- // }
1602+ int: shift_left_logical,
1603+ fold_const {
1604+ int( a, b) => a. wrapping_shl( b as u32 ) ;
1605+ }
15401606 }
15411607 simple_shift_op ! {
15421608 lshr,
1543- int : shift_right_logical
1544- // fold_const {
1545- // int (a, b) => a.wrapping_shr(b as u32);
1546- // }
1609+ uint : shift_right_logical,
1610+ fold_const {
1611+ uint ( a, b) => a. wrapping_shr( b as u32 ) ;
1612+ }
15471613 }
15481614 simple_shift_op ! {
15491615 ashr,
1550- int : shift_right_arithmetic
1551- // fold_const {
1552- // int (a, b) => a.wrapping_shr(b as u32);
1553- // }
1616+ sint : shift_right_arithmetic,
1617+ fold_const {
1618+ sint ( a, b) => a. wrapping_shr( b as u32 ) ;
1619+ }
15541620 }
15551621 simple_uni_op ! {
15561622 neg,
0 commit comments