-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR][CodeGen] kr-style for function arguments #938
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty nasty, nice find.
bool isPromoted = isa<ParmVarDecl>(paramVar) && | ||
cast<ParmVarDecl>(paramVar)->isKNRPromoted(); | ||
if (isPromoted) { | ||
auto ty = getCIRType(paramVar->getType()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OG checks that the types are different before emitting any casts. It mentions enums, but I haven't actually been able to trigger a case where that matters. (I commented out that code and check-clang
still passes.) Maybe just leave a comment about that, so that it's easier to match against OG in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, looks like either assert or missing feature use cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added assert(!MissingFeatures::constructABIArgDirectExtend());
if you meant this enum
|
@gitoleg thanks for the patch
Perhaps we can make it a bit more strict by adding asserts for the ones we know that look absurd (like this bug)? Tricky question too: removing automatic bitcast leads to a lot of boilerplace on the call sites in CIRGen. Seems like to some extend LLVM OG codegen also does bitcasts under the hood, IIRC, which means that probably most code in CIRGen might have asserts when it differs. OTOH, keeping it automatic requires the user to sanitize and could perhaps lead to less efficient combination of casts. I prefer the correctness angle of handling in the call sites, but seems like a lot of work if they are mostly already accounted for (which I haven't checked). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to fix few nits
@smeenai sorry for delay, done! |
I tried to run llvm-test-suite and turned out that there are many tests fail with segfault due to old C style (let's remember Kernighan and Ritchie) . This PR fix it by the usual copy-pasta from the original codegen :) So let's take a look at the code: ``` void foo(x) short x; {} int main() { foo(4); return 0; } ``` and CIR for `foo` function is: ``` cir.func @foo(%arg0: !s32i) { %0 = cir.alloca !s16i, !cir.ptr<!s16i>, ["x", init] %1 = cir.cast(bitcast, %0 : !cir.ptr<!s16i>), !cir.ptr<!s32i> cir.store %arg0, %1 : !s32i, !cir.ptr<!s32i> cir.return } ``` We bitcast the **address** (!!!) and store a value of a bigger size there. And now everything looks fine: ``` cir.func no_proto @foo(%arg0: !s32i) { %0 = cir.alloca !s16i, !cir.ptr<!s16i>, ["x", init] %1 = cir.cast(integral, %arg0 : !s32i), !s16i cir.store %1, %0 : !s16i, !cir.ptr<!s16i> cir.return } ``` We truncate an argument and store it. P.S. The `bitcast` that was there before looks a little bit suspicious and dangerous. Are we sure we can do this unconditional cast while we create `StoreOp` ?
I tried to run llvm-test-suite and turned out that there are many tests fail with segfault due to old C style (let's remember Kernighan and Ritchie) . This PR fix it by the usual copy-pasta from the original codegen :) So let's take a look at the code: ``` void foo(x) short x; {} int main() { foo(4); return 0; } ``` and CIR for `foo` function is: ``` cir.func @foo(%arg0: !s32i) { %0 = cir.alloca !s16i, !cir.ptr<!s16i>, ["x", init] %1 = cir.cast(bitcast, %0 : !cir.ptr<!s16i>), !cir.ptr<!s32i> cir.store %arg0, %1 : !s32i, !cir.ptr<!s32i> cir.return } ``` We bitcast the **address** (!!!) and store a value of a bigger size there. And now everything looks fine: ``` cir.func no_proto @foo(%arg0: !s32i) { %0 = cir.alloca !s16i, !cir.ptr<!s16i>, ["x", init] %1 = cir.cast(integral, %arg0 : !s32i), !s16i cir.store %1, %0 : !s16i, !cir.ptr<!s16i> cir.return } ``` We truncate an argument and store it. P.S. The `bitcast` that was there before looks a little bit suspicious and dangerous. Are we sure we can do this unconditional cast while we create `StoreOp` ?
I tried to run llvm-test-suite and turned out that there are many tests fail with segfault due to old C style (let's remember Kernighan and Ritchie) . This PR fix it by the usual copy-pasta from the original codegen :)
So let's take a look at the code:
and CIR for
foo
function is:We bitcast the address (!!!) and store a value of a bigger size there.
And now everything looks fine:
We truncate an argument and store it.
P.S.
The
bitcast
that was there before looks a little bit suspicious and dangerous. Are we sure we can do this unconditional cast while we createStoreOp
?