[clang] [clang][CodeGen] `sret` args should always point to the `alloca` AS, so use that (PR #114062)

Alex Voicu via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 29 18:20:02 PDT 2024


================
@@ -5390,11 +5391,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
             V->getType()->isIntegerTy())
           V = Builder.CreateZExt(V, ArgInfo.getCoerceToType());
 
-        // If the argument doesn't match, perform a bitcast to coerce it.  This
-        // can happen due to trivial type mismatches.
+        // If the argument doesn't match, we are either trying to pass an
+        // alloca-ed sret argument directly, and the alloca AS does not match
+        // the default AS, case in which we AS cast it, or we have a trivial
+        // type mismatch, and thus perform a bitcast to coerce it.
----------------
AlexVlx wrote:

No this is not the `inalloca` case, it's the case when you have e.g. a C++ move ctor (`Foo(Foo&&)`) which in IR expands into a function taking two pointers to the default AS (`this` and a pointer to the moved from arg). If you're moving into the `sret` arg, you try to bind this to `this`, and you end up here. See the `no-elide-constructors` test that's part of this PR. 

Re: not inserting the cast, you're right it's probably not correct to insert it blindly. I *think* the only thing we can safely handle is if the mismatched arg is a pointer to the default AS, and should error out otherwise. The only mechanism we have for creating temporaries is `alloca`ing them, and it's not even clear what it'd mean to create a temporary in some arbitrary AS. This is probably fine though because I think the only offenders here would be the C++ ctors (perhaps member functions in general, at worst), as their IR signature is derived from the default AS, as there's no fixed argument type to inform it.

https://github.com/llvm/llvm-project/pull/114062


More information about the cfe-commits mailing list