@@ -9,7 +9,7 @@ use crate::custom_insts::CustomInst;
99use crate :: spirv_type:: SpirvType ;
1010use rspirv:: dr:: Operand ;
1111use rspirv:: spirv:: GLOp ;
12- use rustc_codegen_ssa:: mir:: operand:: OperandRef ;
12+ use rustc_codegen_ssa:: mir:: operand:: { OperandRef , OperandValue } ;
1313use rustc_codegen_ssa:: mir:: place:: PlaceRef ;
1414use rustc_codegen_ssa:: traits:: { BuilderMethods , IntrinsicCallBuilderMethods } ;
1515use rustc_middle:: ty:: layout:: LayoutOf ;
@@ -240,6 +240,33 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
240240
241241 sym:: ctpop => self . count_ones ( args[ 0 ] . immediate ( ) ) ,
242242 sym:: bitreverse => self . bit_reverse ( args[ 0 ] . immediate ( ) ) ,
243+ sym:: black_box => {
244+ // TODO(LegNeato): do something more sophisticated that prevents DCE
245+ self . tcx
246+ . dcx ( )
247+ . warn ( "black_box intrinsic does not prevent optimization in Rust GPU" ) ;
248+
249+ let layout = self . layout_of ( arg_tys[ 0 ] ) ;
250+ let llty = layout. spirv_type ( self . span ( ) , self ) ;
251+
252+ match args[ 0 ] . val {
253+ // Pass through scalars
254+ OperandValue :: Immediate ( v) => v,
255+
256+ // Preserve both elements by spilling + reloading
257+ OperandValue :: Pair ( ..) => {
258+ let tmp = self . alloca ( layout. size , layout. align . abi ) ;
259+ self . store ( args[ 0 ] . immediate ( ) , tmp, layout. align . abi ) ;
260+ self . load ( llty, tmp, layout. align . abi )
261+ }
262+
263+ // For lvalues, load
264+ OperandValue :: Ref ( place) => self . load ( llty, place. llval , place. align ) ,
265+
266+ // For ZSTs, return undef of the right type
267+ OperandValue :: ZeroSized => self . undef ( llty) ,
268+ }
269+ }
243270 sym:: bswap => {
244271 // https://github.com/KhronosGroup/SPIRV-LLVM/pull/221/files
245272 // TODO: Definitely add tests to make sure this impl is right.
0 commit comments