(&mut self, ty: Self::Type, ptr: Self::Value, idx: u64)
| 1315 | } |
| 1316 | |
| 1317 | fn struct_gep(&mut self, ty: Self::Type, ptr: Self::Value, idx: u64) -> Self::Value { |
| 1318 | let pointee = match self.lookup_type(ptr.ty) { |
| 1319 | SpirvType::Pointer { pointee } => { |
| 1320 | assert_ty_eq!(self, ty, pointee); |
| 1321 | pointee |
| 1322 | } |
| 1323 | other => self.fatal(&format!( |
| 1324 | "struct_gep not on pointer type: {other:?}, index {idx}" |
| 1325 | )), |
| 1326 | }; |
| 1327 | let pointee_kind = self.lookup_type(pointee); |
| 1328 | let result_pointee_type = match pointee_kind { |
| 1329 | SpirvType::Adt { field_types, .. } => field_types[idx as usize], |
| 1330 | SpirvType::Array { element, .. } |
| 1331 | | SpirvType::RuntimeArray { element, .. } |
| 1332 | | SpirvType::Vector { element, .. } |
| 1333 | | SpirvType::Matrix { element, .. } => element, |
| 1334 | SpirvType::InterfaceBlock { inner_type } => { |
| 1335 | assert_eq!(idx, 0); |
| 1336 | inner_type |
| 1337 | } |
| 1338 | other => self.fatal(&format!( |
| 1339 | "struct_gep not on struct, array, or vector type: {other:?}, index {idx}" |
| 1340 | )), |
| 1341 | }; |
| 1342 | let result_type = SpirvType::Pointer { |
| 1343 | pointee: result_pointee_type, |
| 1344 | } |
| 1345 | .def(self.span(), self); |
| 1346 | |
| 1347 | // Special-case field accesses through a `pointercast`, to accesss the |
| 1348 | // right field in the original type, for the `Logical` addressing model. |
| 1349 | if let SpirvValueKind::LogicalPtrCast { |
| 1350 | original_ptr, |
| 1351 | original_pointee_ty, |
| 1352 | bitcast_result_id: _, |
| 1353 | } = ptr.kind |
| 1354 | { |
| 1355 | let offset = match pointee_kind { |
| 1356 | SpirvType::Adt { field_offsets, .. } => field_offsets[idx as usize], |
| 1357 | SpirvType::Array { element, .. } |
| 1358 | | SpirvType::RuntimeArray { element, .. } |
| 1359 | | SpirvType::Vector { element, .. } |
| 1360 | | SpirvType::Matrix { element, .. } => { |
| 1361 | self.lookup_type(element).sizeof(self).unwrap() * idx |
| 1362 | } |
| 1363 | _ => unreachable!(), |
| 1364 | }; |
| 1365 | if let Some(indices) = self.recover_access_chain_from_offset( |
| 1366 | original_pointee_ty, |
| 1367 | result_pointee_type, |
| 1368 | offset, |
| 1369 | ) { |
| 1370 | let indices = indices |
| 1371 | .into_iter() |
| 1372 | .map(|idx| self.constant_u32(self.span(), idx).def(self)) |
| 1373 | .collect::<Vec<_>>(); |
| 1374 | return self |
no test coverage detected