================
@@ -5159,16 +5156,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
     } else if (!ReturnValue.isNull()) {
       SRetPtr = ReturnValue.getAddress();
     } else {
-      SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
+      SRetPtr = CreateMemTempWithoutCast(RetTy, "tmp");
       if (HaveInsertPoint() && ReturnValue.isUnused()) {
         llvm::TypeSize size =
             CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
-        UnusedReturnSizePtr = EmitLifetimeStart(size, SRetAlloca.getPointer());
+        UnusedReturnSizePtr = EmitLifetimeStart(size, 
SRetPtr.getBasePointer());
       }
     }
     if (IRFunctionArgs.hasSRetArg()) {
+      // If the caller allocated the return slot, it is possible that the
+      // alloca was AS casted to the default as, so we ensure the cast is
+      // stripped before binding to the sret arg, which is in the allocaAS.
----------------
AlexVlx wrote:

It's not really blind, this is actually captured in current tests e.g. 
`CodeGen/sret.c`, please see: <https://gcc.godbolt.org/z/TWd83dbdE>. This 
currently works because `sret` gets arbitrarily placed in the default AS, 
switching it over to anything but will break it. This happens when we receive a 
pre-`alloca`ed return value slot, which gets created in 
`AggExprEmitter::withReturnValueSlot` iff we cannot elide the temporary. This 
uses `CreateMemTemp` which inserts a cast to the default AS. An alternative 
would be to instead use `CreateMemTempWithoutCast`.

https://github.com/llvm/llvm-project/pull/114062
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to