-
Notifications
You must be signed in to change notification settings - Fork 100
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][CIRGen][Builtin] Support __builtin_frame_address #1137
base: main
Are you sure you want to change the base?
Conversation
@@ -1580,18 +1580,21 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, | |||
llvm_unreachable("BI__builtin_wmemcmp NYI"); | |||
case Builtin::BI__builtin_dwarf_cfa: | |||
llvm_unreachable("BI__builtin_dwarf_cfa NYI"); | |||
case Builtin::BI__builtin_return_address: { | |||
case Builtin::BI__builtin_return_address: | |||
case Builtin::BI__builtin_frame_address: { | |||
mlir::Location loc = getLoc(E->getExprLoc()); | |||
mlir::Attribute levelAttr = ConstantEmitter(*this).emitAbstract( | |||
E->getArg(0), E->getArg(0)->getType()); | |||
int64_t level = mlir::cast<cir::IntAttr>(levelAttr).getSInt(); |
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 isn't your change, but why are we getting a singed int and storing to int64_t
? The level should be an unsigned int
and the intrinsic arg is a UInt32
.
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.
I can just use mlir::cast<cir::IntAttr>(levelAttr).getUInt()
@@ -1851,8 +1851,8 @@ mlir::LogicalResult CIRToLLVMVAArgOpLowering::matchAndRewrite( | |||
return op.emitError("cir.vaarg lowering is NYI"); | |||
} | |||
|
|||
/// Returns the name used for the linkage attribute. This *must* correspond | |||
/// to the name of the attribute in ODS. | |||
/// Returns the name used for the linkage attribute. This *must* correspond |
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 an unrelated formatting change. It's pretty minor here, but it might be worth figuring out how to avoid them in general.
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.
ah, thank you for good catch. This is super interesting as I used
git-clang-format --diff after I staged the files before I committed and pushed. Looks like even git-clang-format introduce formatting change that is not really related to diff?
Anyway, revised it so it only contains my change. Will do a NFC PR to correct formatting that is not related to this PR so we will feel better using git-clang-format
84e6fda
to
8f6f61d
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
…te personality functions While here, cleanup getOrCreateLLVMFuncOp usaga a bit.
Directly erasing the op causes a use after free later on, presumably because the lowering framework isn't aware of the op being deleted. This fixes `clang/test/CIR/CodeGen/pointer-arith-ext.c` with ASAN.
The loop was erasing the user of a value while iterating on the value's users, which results in a use after free. We're already assuming (and asserting) that there's only one user, so we can just access it directly instead. CIR/Transforms/Target/x86_64/x86_64-call-conv-lowering-pass.cpp was failing with ASAN before this change. We're now ASAN-clean except for llvm#829 (which is also in progress).
Reland llvm#638 This was reverted due to llvm#655. I tried to address the problem in the newest commit. The changes of the PR since the last landed one includes: - Move the definition of `cir::CIRGenConsumer` to `clang/include/clang/CIRFrontendAction/CIRGenConsumer.h`, and leave its `HandleTranslationUnit` interface is left empty. So that `cir::CIRGenConsumer` won't need to depend on CodeGen any more. - Change the old definition of `cir::CIRGenConsumer` in `clang/lib/CIR/FrontendAction/CIRGenAction.cpp` and to `CIRLoweringConsumer`, inherited from `cir::CIRGenConsumer`, which implements the original `HandleTranslationUnit` interface. I feel this may improve the readability more even without my original patch.
This PR fixes the lowering for multi dimensional arrays. Consider the following code snippet `test.c`: ``` void foo() { char arr[4][1] = {"a", "b", "c", "d"}; } ``` When ran with `bin/clang test.c -Xclang -fclangir -Xclang -emit-llvm -S -o -`, It produces the following error: ``` ~/clangir/llvm/include/llvm/Support/Casting.h:566: decltype(auto) llvm::cast(const From&) [with To = mlir::ArrayAttr; From = mlir::Attribute]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed. ``` The bug can be traced back to `LoweringHelpers.cpp`. It considers the values in the array as integer types, and this causes an error in this case. This PR updates `convertToDenseElementsAttrImpl` when the array contains string attributes. I have also added one more similar test. Note that in the tests I used a **literal match** to avoid matching as regex, so `!dbg` is useful.
Support expressions at the top level such as const unsigned int n = 1234; const int &r = (const int&)n; Reviewers: bcardosolopes Pull Request: llvm#857
This is to match clang CodeGen
As title. Also introduced buildAArch64NeonCall skeleton, which is partially the counterpart of OG's EmitNeonCall. And this could be use for many other neon intrinsics. --------- Co-authored-by: Guojin He <[email protected]>
See the test for example.
This PR adds aarch64 big endian support. Basically the support for aarch64_be itself is expressed only in two extra cases for the switch statement and changes in the `CIRDataLayout` are needed to prove that we really support big endian. Hence the idea for the test - I think the best way for proof is something connected with bit-fields, so we compare the results of the original codegen and ours.
This PR splits the old `cir-simplify` pass into two new passes, namely `cir-canonicalize` and `cir-simplify` (the new `cir-simplify`). The `cir-canonicalize` pass runs transformations that do not affect CIR-to-source fidelity much, such as operation folding and redundant operation elimination. On the other hand, the new `cir-simplify` pass runs transformations that may significantly change the code and break high-level code analysis passes, such as more aggresive code optimizations. This PR also updates the CIR-to-CIR pipeline to fit these two new passes. The `cir-canonicalize` pass is moved to the very front of the pipeline, while the new `cir-simplify` pass is moved to the back of the pipeline (but still before lowering prepare of course). Additionally, the new `cir-simplify` now only runs when the user specifies a non-zero optimization level on the frontend. Also fixed some typos and resolved some `clang-tidy` complaints along the way. Resolves llvm#827 .
Currently the C style cast is not implemented/supported for unions. This PR adds support for union casts as done in `CGExprAgg.cpp`. I have also added an extra test in `union-init.c`.
Mistakenly closed llvm#850 llvm#850 (review) This PR fixes array initialization for expression arguments. Consider the following code snippet `test.c`: ``` typedef struct { int a; int b[2]; } A; int bar() { return 42; } void foo() { A a = {bar(), {}}; } ``` When ran with `bin/clang test.c -Xclang -fclangir -Xclang -emit-cir -S -o -`, It produces the following error: ``` ~/clangir/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp:483: void {anonymous}::AggExprEmitter::buildArrayInit(cir::Address, mlir::cir::ArrayType, clang::QualType, clang::Expr*, llvm::ArrayRef<clang::Expr*>, clang::Expr*): Assertion `NumInitElements != 0' failed. ``` The error can be traced back to `CIRGenExprAgg.cpp`, and the fix is simple. It is possible to have an empty array initialization as an expression argument!
As title, if element type of vector type is sized, then the vector type should be deemed sized. This would enable us generate code for neon without triggering assertion
…eon_vrndaq_v (llvm#871) as title. This also added NeonType support for Float32 Co-authored-by: Guojin He <[email protected]>
This PR handles calls with unions passed by value in the calling convention pass. #### Implementation As one may know, data layout for unions in CIR and in LLVM differ one from another. In CIR we track all the union members, while in LLVM IR only the largest one. And here we need to take this difference into account: we need to find a type of the largest member and treat it as the first (and only) union member in order to preserve all the logic from the original codegen. There is a method `StructType::getLargestMember` - but looks like it produces different results (with the one I implemented or better to say copy-pasted). Maybe it's done intentionally, I don't know. The LLVM IR produced has also some difference from the original one. In the original IR `gep` is emitted - and we can not do the same. If we create `getMemberOp` we may fail on type checking for unions - since the first member type may differ from the largest type. This is why we create `bitcast` instead. Relates to the issue llvm#1061
…enBuiltinAArch64.cpp (llvm#1124) We are still seeing crash message like `NYI UNREACHABLE executed at clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp:3304`, which is not convenient for triaging as our code base changes so fast, line number doesn't help much. So, here we replaced most of `llvm_unreachable("NYI")` with more informative message.
…1125) Currently, the final `target triple` in LLVM IR is set in `CIRGenAction`, which is not executed by cir tools like `cir-translate`. This PR delay its assignment to LLVM lowering, enabling sharing the emitting of `target triple` between different invoking paths.
…bsOp to take vector input (llvm#1099) Extend AbsOp to take vector of int input. With it, we can support __builtin_elementwise_abs. We should in the next PR extend FpUnaryOps to support vector type input so we won't have blocker to implement all elementwise builtins completely. Now just temporarily have missingFeature `fpUnaryOPsSupportVectorType`. Currently, int type UnaryOp support vector type. FYI: [clang's documentation about elementwise builtins](https://clang.llvm.org/docs/LanguageExtensions.html#vector-builtins)
…vm#1102) This is a NFC patch that moves declaration from LowerToLLVM.cpp. The motivation of the patch is, we hope we can use the abilities from MLIR's standard dialects without lowering **ALL** clangir operation to MLIR's standard dialects. For example, currently we have 86 operations in LowerToLLVM.cpp but only 45 operations under though MLIR. It won't be easy to add proper lowering for all operation to **different** dialects. I think the solution may be to allow **mixed** IR. So that we can lowering CIR to MLIR's standard dialects partially and we can use some existing analysis and optimizations in MLIR and then we can lower all of them (the MLIR dialects and unlowered clangir) to LLVM IR. The hybrid IR is one of the goals of MLIR as far as I know. NOTE: I completely understand that the DirectlyLLVM pipeline is the tier-1 pipeline that we want to support. The idea above won't change this. I just want to offer some oppotunities for the downstream projects and finally some chances to improve the overall ecosystem.
…, neon_splatq_lane and neon_splatq_laneq (llvm#1126)
This is going to be raised in follow up work, which is hard to do in one go because createBaseClassAddr goes of the OG skeleton and ideally we want ApplyNonVirtualAndVirtualOffset to work naturally. This also doesn't handle null checks, coming next.
Now that we fixed the dep on VBase, clean up the rest of the function.
…e BaseClassAddrOp
It was always the intention for `cir.cmp` operations to return bool result. Due to missing constraints, a bug in codegen has slipped in which created `cir.cmp` operations with result type that matches the original AST expression type. In C, as opposed to C++, boolean expression types are "int". This resulted with extra operations being codegened around boolean expressions and their usage. This commit both enforces `cir.cmp` in the op definition and fixes the mentioned bug.
This is the first patch to support TBAA, following the discussion at llvm#1076 (comment) - add skeleton for CIRGen, utilizing `decorateOperationWithTBAA` - add empty implementation in `CIRGenTBAA` - introduce `CIR_TBAAAttr` with empty body - attach `CIR_TBAAAttr` to `LoadOp` and `StoreOp` - no handling of vtable pointer - no LLVM lowering
) The title describes the purpose of the PR. It adds initial support for structures with padding to the call convention lowering for AArch64. I have also _initial support_ for the missing feature [FinishLayout](https://github.com/llvm/clangir/blob/5c5d58402bebdb1e851fb055f746662d4e7eb586/clang/lib/AST/RecordLayoutBuilder.cpp#L786) for records, and the logic is gotten from the original codegen. Finally, I added a test for verification.
@@ -3921,7 +3926,7 @@ void populateCIRToLLVMConversionPatterns( | |||
CIRToLLVMPtrMaskOpLowering, | |||
CIRToLLVMPtrStrideOpLowering, | |||
CIRToLLVMResumeOpLowering, | |||
CIRToLLVMReturnAddrOpLowering, | |||
CIRToLLVMFuncAddrBuiltinOpLowering, |
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.
We should keep this list alphabetically sorted, to prevent duplicates from coming in. (That was part of @Lancern's motivation for the change.)
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.
Ah, I see. thanks for the reminder.
For instance, value of 0 yields the return address of the current function, | ||
value of 1 yields the return address of the caller of the current function, | ||
and so forth. | ||
For instance, |
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.
The line wrapping here is a bit strange?
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.
I was thinking to make contrast of value of 0
and value of 1
lines more contrastingly visible. But open for change it to more normal line wrapping it feels strange.
…m#1152) The function `populateCIRToLLVMConversionPatterns` contains a spaghetti of LLVM dialect conversion patterns, which results in merge conflicts very easily. Besides, a few patterns are even registered for more than once, possibly due to careless resolution of merge conflicts. This PR attempts to mitigate this problem. Pattern names now are sorted in alphabetical order, and each source code line now only lists exactly one pattern name to reduce potential merge conflicts.
let summary = "The return address of the current function, or of one of its callers"; | ||
def ReturnAddr : I32EnumAttrCase<"return_address", 1>; | ||
def FrameAddr : I32EnumAttrCase<"frame_address", 2>; | ||
def FuncAddrKind |
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.
Thanks for trying to do some reuse here. I think these two operations should actually be on their own cir.return_address
and cir.frame_address
. You could still do some good reuse by factoring out common bits in a tablegen class.
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.
Thanks for trying to do some reuse here. I think these two operations should actually be on their own
cir.return_address
andcir.frame_address
. You could still do some good reuse by factoring out common bits in a tablegen class.
no problem, will make them separate Op.
No description provided.