@@ -430,10 +430,14 @@ void SPIRVTypeScavenger::correctUseTypes(Instruction &I) {
430430 // arguments we pass in to the argument requirements of the function.
431431 if (Function *F = CB->getCalledFunction ()) {
432432 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 ;
433438 if (U->getType ()->isPointerTy ())
434439 PointerOperands.emplace_back (
435- U.getOperandNo (),
436- computePointerElementType (F->getArg (CB->getArgOperandNo (&U))));
440+ U.getOperandNo (), computePointerElementType (F->getArg (ArgNo)));
437441 }
438442 }
439443 }
@@ -475,6 +479,16 @@ void SPIRVTypeScavenger::correctUseTypes(Instruction &I) {
475479 U.set (CastedValue);
476480 };
477481
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+
478492 if (isa<Value *>(UsedTy)) {
479493 // When the use is of an indirect-pointer type, insert a bitcast to the
480494 // use type only for this use. This prevents indirect pointers from
@@ -491,15 +505,18 @@ void SPIRVTypeScavenger::correctUseTypes(Instruction &I) {
491505 // Source type is fixed, use type is deferred: set the deferred type to
492506 // the fixed type.
493507 fixType (*DeferredUseTy, FixedTy);
508+ ReplaceTypeInOperands (DeferredUseTy, FixedTy);
494509 }
495510 } else if (auto *DeferredTy = dyn_cast<DeferredType *>(SourceTy)) {
496511 if (auto *FixedUseTy = dyn_cast<Type *>(UsedTy)) {
497512 // Source type is fixed, use type is deferred: set the deferred type to
498513 // the fixed type.
499514 fixType (*DeferredTy, FixedUseTy);
515+ ReplaceTypeInOperands (DeferredTy, FixedUseTy);
500516 } else if (auto *DeferredUseTy = dyn_cast<DeferredType *>(UsedTy)) {
501517 // If they're both deferred, merge the two types together.
502518 mergeType (DeferredTy, DeferredUseTy);
519+ ReplaceTypeInOperands (DeferredUseTy, DeferredTy);
503520 }
504521 }
505522 }
0 commit comments