-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[Clang][CodeGen][X86] don't coerce int128 into {i64,i64} for SysV-like ABIs
#135230
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
Changes from 4 commits
16068fb
ef48930
b5c9535
678468d
e78426d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2470,13 +2470,12 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset, | |
| return llvm::Type::getDoubleTy(getVMContext()); | ||
| } | ||
|
|
||
|
|
||
| /// GetINTEGERTypeAtOffset - The ABI specifies that a value should be passed in | ||
| /// an 8-byte GPR. This means that we either have a scalar or we are talking | ||
| /// about the high or low part of an up-to-16-byte struct. This routine picks | ||
| /// the best LLVM IR type to represent this, which may be i64 or may be anything | ||
| /// else that the backend will pass in a GPR that works better (e.g. i8, %foo*, | ||
| /// etc). | ||
| /// one or more 8-byte GPRs. This means that we either have a scalar or we are | ||
| /// talking about the high and/or low part of an up-to-16-byte struct. This | ||
| /// routine picks the best LLVM IR type to represent this, which may be i64 or | ||
| /// may be anything else that the backend will pass in GPRs that works better | ||
| /// (e.g. i8, %foo*, etc). | ||
| /// | ||
| /// PrefType is an LLVM IR type that corresponds to (part of) the IR type for | ||
| /// the source type. IROffset is an offset in bytes into the LLVM IR type that | ||
|
|
@@ -2534,6 +2533,13 @@ GetINTEGERTypeAtOffset(llvm::Type *IRType, unsigned IROffset, | |
| SourceOffset); | ||
| } | ||
|
|
||
| // if we have a 128-bit integer, we can pass it safely using an i128 | ||
| // so we return that | ||
| if (IRType->isIntegerTy(128)) { | ||
| assert(IROffset <= 8); | ||
| return IRType; | ||
| } | ||
|
|
||
| // Okay, we don't have any better idea of what to pass, so we pass this in an | ||
| // integer register that isn't too big to fit the rest of the struct. | ||
| unsigned TySizeInBytes = | ||
|
|
@@ -2592,8 +2598,7 @@ GetX86_64ByValArgumentPair(llvm::Type *Lo, llvm::Type *Hi, | |
| return Result; | ||
| } | ||
|
|
||
| ABIArgInfo X86_64ABIInfo:: | ||
| classifyReturnType(QualType RetTy) const { | ||
| ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy) const { | ||
| // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the | ||
| // classification algorithm. | ||
| X86_64ABIInfo::Class Lo, Hi; | ||
|
||
|
|
@@ -2639,6 +2644,12 @@ classifyReturnType(QualType RetTy) const { | |
| isPromotableIntegerTypeForABI(RetTy)) | ||
| return ABIArgInfo::getExtend(RetTy); | ||
| } | ||
|
|
||
| if (ResType->isIntegerTy(128)) { | ||
| // i128 are passed directly | ||
| assert(Hi == Integer); | ||
| return ABIArgInfo::getDirect(ResType); | ||
| } | ||
| break; | ||
|
|
||
| // AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next | ||
|
|
@@ -2784,6 +2795,11 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs, | |
| return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); | ||
| } | ||
|
|
||
| if (ResType->isIntegerTy(128)) { | ||
| assert(Hi == Integer); | ||
| ++neededInt; | ||
| return ABIArgInfo::getDirect(ResType); | ||
| } | ||
| break; | ||
|
|
||
| // AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // no autogeneration since update_cc_test_checks does not support -g | ||
| // RUN: %clang_cc1 -triple x86_64-pc-linux -O1 -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s | ||
|
|
||
| // CHECK-LABEL: define{{.*}} i128 @add(i128 noundef %a) | ||
| // CHECK: #dbg_value(i128 %a, ![[DI:.*]], !DIExpression() | ||
| __int128_t add(__int128_t a) { | ||
| return a + a; | ||
| } | ||
|
|
||
| // CHECK: ![[DI]] = !DILocalVariable(name: "a", arg: 1 |
Uh oh!
There was an error while loading. Please reload this page.