diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h b/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h index cfdf831709adc..71632a46dcde1 100644 --- a/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h +++ b/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h @@ -215,7 +215,8 @@ class CoroIdInst : public AnyCoroIdInst { void setInfo(Constant *C) { setArgOperand(InfoArg, C); } Function *getCoroutine() const { - return cast(getArgOperand(CoroutineArg)->stripPointerCasts()); + return cast( + getArgOperand(CoroutineArg)->stripPointerCastsAndAliases()); } void setCoroutineSelf() { if (!isa(getArgOperand(CoroutineArg))) @@ -254,17 +255,20 @@ class AnyCoroIdRetconInst : public AnyCoroIdInst { /// attributes, and calling convention of the continuation function(s) /// are taken from this declaration. Function *getPrototype() const { - return cast(getArgOperand(PrototypeArg)->stripPointerCasts()); + return cast( + getArgOperand(PrototypeArg)->stripPointerCastsAndAliases()); } /// Return the function to use for allocating memory. Function *getAllocFunction() const { - return cast(getArgOperand(AllocArg)->stripPointerCasts()); + return cast( + getArgOperand(AllocArg)->stripPointerCastsAndAliases()); } /// Return the function to use for deallocating memory. Function *getDeallocFunction() const { - return cast(getArgOperand(DeallocArg)->stripPointerCasts()); + return cast( + getArgOperand(DeallocArg)->stripPointerCastsAndAliases()); } // Methods to support type inquiry through isa, cast, and dyn_cast: diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 14b1f7d799ea9..48cfec0f55c41 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -6276,7 +6276,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { Check(isa(Promise) || isa(Promise), "promise argument must refer to an alloca"); - auto *CoroAddr = Call.getArgOperand(2)->stripPointerCasts(); + auto *CoroAddr = Call.getArgOperand(2)->stripPointerCastsAndAliases(); bool BeforeCoroEarly = isa(CoroAddr); Check(BeforeCoroEarly || isa(CoroAddr), "coro argument must refer to a function"); diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp index 1078fbffb13e3..fc8a6277893a3 100644 --- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp @@ -140,10 +140,12 @@ bool Lowerer::lower(Function &F) { break; case Intrinsic::coro_async_size_replace: auto *Target = cast( - cast(II->getArgOperand(0)->stripPointerCasts()) + cast( + II->getArgOperand(0)->stripPointerCastsAndAliases()) ->getInitializer()); auto *Source = cast( - cast(II->getArgOperand(1)->stripPointerCasts()) + cast( + II->getArgOperand(1)->stripPointerCastsAndAliases()) ->getInitializer()); auto *TargetSize = Target->getOperand(1); auto *SourceSize = Source->getOperand(1); diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp index 9e798ccbaacee..a922099a1f43f 100644 --- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -555,7 +555,7 @@ void coro::Shape::emitDealloc(IRBuilder<> &Builder, Value *Ptr, /// Check that the given value is a well-formed prototype for the /// llvm.coro.id.retcon.* intrinsics. static void checkWFRetconPrototype(const AnyCoroIdRetconInst *I, Value *V) { - auto F = dyn_cast(V->stripPointerCasts()); + auto F = dyn_cast(V->stripPointerCastsAndAliases()); if (!F) fail(I, "llvm.coro.id.retcon.* prototype not a Function", V); @@ -591,7 +591,7 @@ static void checkWFRetconPrototype(const AnyCoroIdRetconInst *I, Value *V) { /// Check that the given value is a well-formed allocator. static void checkWFAlloc(const Instruction *I, Value *V) { - auto F = dyn_cast(V->stripPointerCasts()); + auto F = dyn_cast(V->stripPointerCastsAndAliases()); if (!F) fail(I, "llvm.coro.* allocator not a Function", V); @@ -606,7 +606,7 @@ static void checkWFAlloc(const Instruction *I, Value *V) { /// Check that the given value is a well-formed deallocator. static void checkWFDealloc(const Instruction *I, Value *V) { - auto F = dyn_cast(V->stripPointerCasts()); + auto F = dyn_cast(V->stripPointerCastsAndAliases()); if (!F) fail(I, "llvm.coro.* deallocator not a Function", V); @@ -637,7 +637,8 @@ void AnyCoroIdRetconInst::checkWellFormed() const { } static void checkAsyncFuncPointer(const Instruction *I, Value *V) { - auto *AsyncFuncPtrAddr = dyn_cast(V->stripPointerCasts()); + auto *AsyncFuncPtrAddr = + dyn_cast(V->stripPointerCastsAndAliases()); if (!AsyncFuncPtrAddr) fail(I, "llvm.coro.id.async async function pointer not a global", V); } diff --git a/llvm/test/Transforms/Coroutines/coro-id-alias.ll b/llvm/test/Transforms/Coroutines/coro-id-alias.ll new file mode 100644 index 0000000000000..86381e58a58b4 --- /dev/null +++ b/llvm/test/Transforms/Coroutines/coro-id-alias.ll @@ -0,0 +1,13 @@ +; RUN: opt < %s -passes=coro-early -S | FileCheck %s + +declare token @llvm.coro.id(i32, ptr, ptr, ptr) + +@foo_alias = alias void (), ptr @foo + +define void @foo() presplitcoroutine { +entry: + %id = call token @llvm.coro.id(i32 0, ptr null, ptr @foo_alias, ptr null) + ret void +} +; CHECK-LABEL: define void @foo() +; CHECK: call token @llvm.coro.id(i32 0, ptr null, ptr @foo, ptr null)