@@ -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,33 @@ 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
+
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
+ }
243
270
sym:: bswap => {
244
271
// https://github.com/KhronosGroup/SPIRV-LLVM/pull/221/files
245
272
// TODO: Definitely add tests to make sure this impl is right.
0 commit comments