@@ -632,21 +632,41 @@ class YkIRWriter {
632
632
633
633
void serialiseGetElementPtrInst (GetElementPtrInst *I, FuncLowerCtxt &FLCtxt,
634
634
unsigned BBIdx, unsigned &InstIdx) {
635
- unsigned BitWidth = 64 ;
636
- MapVector<Value *, APInt> Offsets;
637
- APInt Offset (BitWidth, 0 );
638
-
639
- bool Res = I->collectOffset (DL, BitWidth, Offsets, Offset);
640
- assert (Res);
641
-
642
635
// opcode:
643
636
serialiseOpcode (OpCodePtrAdd);
644
637
// type_idx:
645
638
OutStreamer.emitSizeT (typeIndex (I->getType ()));
646
639
// pointer:
647
640
serialiseOperand (I, FLCtxt, I->getPointerOperand ());
648
- // offset:
649
- serialiseOperand (I, FLCtxt, ConstantInt::get (I->getContext (), Offset));
641
+
642
+ // GetElementPtrInst::collectOffset() reduces the GEP to:
643
+ // - a static offset and
644
+ // - zero or more dynamic offsets of the form `elem_count * elem_size`,
645
+ // where `elem_count` is not known statically.
646
+ //
647
+ // We lower this information directly into a Yk PtrAdd instruction.
648
+ //
649
+ // Note: the width of the collected constant offset must be the same as the
650
+ // index type bit-width.
651
+ unsigned BitWidth = DL.getIndexSizeInBits (I->getPointerAddressSpace ());
652
+ APInt ConstOff (BitWidth, 0 );
653
+ MapVector<Value *, APInt> DynOffs;
654
+ bool CollectRes = I->collectOffset (DL, BitWidth, DynOffs, ConstOff);
655
+ assert (CollectRes);
656
+
657
+ // const_off:
658
+ OutStreamer.emitSizeT (ConstOff.getZExtValue ());
659
+ // num_dyn_offs:
660
+ size_t NumDyn = DynOffs.size ();
661
+ OutStreamer.emitSizeT (NumDyn);
662
+ // dyn_elem_counts:
663
+ for (auto &KV : DynOffs) {
664
+ serialiseOperand (I, FLCtxt, std::get<0 >(KV));
665
+ }
666
+ // dyn_elem_sizes:
667
+ for (auto &KV : DynOffs) {
668
+ OutStreamer.emitSizeT (std::get<1 >(KV).getZExtValue ());
669
+ }
650
670
651
671
FLCtxt.updateVLMap (I, InstIdx);
652
672
InstIdx++;
0 commit comments