@@ -430,10 +430,14 @@ void SPIRVTypeScavenger::correctUseTypes(Instruction &I) {
430
430
// arguments we pass in to the argument requirements of the function.
431
431
if (Function *F = CB->getCalledFunction ()) {
432
432
for (Use &U : CB->args ()) {
433
+ // If we're calling a var-arg method, we have more operands than the
434
+ // function has parameters. Bail out if we hit that point.
435
+ unsigned ArgNo = CB->getArgOperandNo (&U);
436
+ if (ArgNo >= F->arg_size ())
437
+ break ;
433
438
if (U->getType ()->isPointerTy ())
434
439
PointerOperands.emplace_back (
435
- U.getOperandNo (),
436
- computePointerElementType (F->getArg (CB->getArgOperandNo (&U))));
440
+ U.getOperandNo (), computePointerElementType (F->getArg (ArgNo)));
437
441
}
438
442
}
439
443
}
@@ -475,6 +479,16 @@ void SPIRVTypeScavenger::correctUseTypes(Instruction &I) {
475
479
U.set (CastedValue);
476
480
};
477
481
482
+ // This handles the scenario where a deferred type gets resolved to a fixed
483
+ // type during handling of this instruction, and another operand is using
484
+ // the same deferred type later in the instruction.
485
+ auto ReplaceTypeInOperands = [&](DeducedType From, DeducedType To) {
486
+ for (auto &ReplacePair : PointerOperands) {
487
+ if (ReplacePair.second == From)
488
+ ReplacePair.second = To;
489
+ }
490
+ };
491
+
478
492
if (isa<Value *>(UsedTy)) {
479
493
// When the use is of an indirect-pointer type, insert a bitcast to the
480
494
// use type only for this use. This prevents indirect pointers from
@@ -491,15 +505,18 @@ void SPIRVTypeScavenger::correctUseTypes(Instruction &I) {
491
505
// Source type is fixed, use type is deferred: set the deferred type to
492
506
// the fixed type.
493
507
fixType (*DeferredUseTy, FixedTy);
508
+ ReplaceTypeInOperands (DeferredUseTy, FixedTy);
494
509
}
495
510
} else if (auto *DeferredTy = dyn_cast<DeferredType *>(SourceTy)) {
496
511
if (auto *FixedUseTy = dyn_cast<Type *>(UsedTy)) {
497
512
// Source type is fixed, use type is deferred: set the deferred type to
498
513
// the fixed type.
499
514
fixType (*DeferredTy, FixedUseTy);
515
+ ReplaceTypeInOperands (DeferredTy, FixedUseTy);
500
516
} else if (auto *DeferredUseTy = dyn_cast<DeferredType *>(UsedTy)) {
501
517
// If they're both deferred, merge the two types together.
502
518
mergeType (DeferredTy, DeferredUseTy);
519
+ ReplaceTypeInOperands (DeferredUseTy, DeferredTy);
503
520
}
504
521
}
505
522
}
0 commit comments