@@ -9,7 +9,7 @@ use crate::custom_insts::CustomInst;
9
9
use crate :: spirv_type:: SpirvType ;
10
10
use rspirv:: dr:: Operand ;
11
11
use rspirv:: spirv:: GLOp ;
12
- use rustc_codegen_ssa:: mir:: operand:: OperandRef ;
12
+ use rustc_codegen_ssa:: mir:: operand:: { OperandRef , OperandValue } ;
13
13
use rustc_codegen_ssa:: mir:: place:: PlaceRef ;
14
14
use rustc_codegen_ssa:: traits:: { BuilderMethods , IntrinsicCallBuilderMethods } ;
15
15
use rustc_middle:: ty:: layout:: LayoutOf ;
@@ -240,6 +240,26 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
240
240
241
241
sym:: ctpop => self . count_ones ( args[ 0 ] . immediate ( ) ) ,
242
242
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
+ match args[ 0 ] . val {
249
+ // Return the value unchanged for immediates
250
+ OperandValue :: Immediate ( v) | OperandValue :: Pair ( v, _) => v,
251
+ // For non-immediates, store and reload
252
+ OperandValue :: Ref ( place) => self . load (
253
+ self . layout_of ( arg_tys[ 0 ] ) . spirv_type ( self . span ( ) , self ) ,
254
+ place. llval ,
255
+ place. align ,
256
+ ) ,
257
+ // For ZSTs, return an undef value that will be optimized away
258
+ OperandValue :: ZeroSized => {
259
+ self . undef ( self . layout_of ( arg_tys[ 0 ] ) . spirv_type ( self . span ( ) , self ) )
260
+ }
261
+ }
262
+ }
243
263
sym:: bswap => {
244
264
// https://github.com/KhronosGroup/SPIRV-LLVM/pull/221/files
245
265
// TODO: Definitely add tests to make sure this impl is right.
0 commit comments