Skip to content

Commit 696d7fe

Browse files
authored
Merge branch 'main' into fix_complex_to_complex_cast
2 parents 7970ae8 + b2a8ee9 commit 696d7fe

File tree

24 files changed

+1351
-188
lines changed

24 files changed

+1351
-188
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,6 +3132,58 @@ def CIR_GetMethodOp : CIR_Op<"get_method"> {
31323132
let hasVerifier = 1;
31333133
}
31343134

3135+
//===----------------------------------------------------------------------===//
3136+
// GetElementOp
3137+
//===----------------------------------------------------------------------===//
3138+
3139+
def CIR_GetElementOp : CIR_Op<"get_element"> {
3140+
let summary = "Get the address of an array element";
3141+
let description = [{
3142+
The `cir.get_element` operation gets the address of a particular element
3143+
from the `base` array.
3144+
3145+
It expects a pointer to the `base` array and the `index` of the element.
3146+
3147+
Example:
3148+
```mlir
3149+
// Suppose we have a array.
3150+
!s32i = !cir.int<s, 32>
3151+
!arr_ty = !cir.array<!s32i x 4>
3152+
3153+
// Get the address of the element at index 1.
3154+
%elem_1 = cir.get_element %0[1] : (!cir.ptr<!array_ty>, !s32i) -> !cir.ptr<!s32i>
3155+
3156+
// Get the address of the element at index %i.
3157+
%i = ...
3158+
%elem_i = cir.get_element %0[%i] : (!cir.ptr<!array_ty>, !s32i) -> !cir.ptr<!s32i>
3159+
```
3160+
}];
3161+
3162+
let arguments = (ins
3163+
Arg<CIR_PtrToArray, "the base address of the array ">:$base,
3164+
Arg<CIR_AnyFundamentalIntType, "the index of the element">:$index
3165+
);
3166+
3167+
let results = (outs CIR_PointerType:$result);
3168+
3169+
let assemblyFormat = [{
3170+
$base `[` $index `]` `:` `(` qualified(type($base)) `,` qualified(type($index)) `)`
3171+
`->` qualified(type($result)) attr-dict
3172+
}];
3173+
3174+
let extraClassDeclaration = [{
3175+
// Get the type of the element.
3176+
mlir::Type getElementType() {
3177+
return getType().getPointee();
3178+
}
3179+
cir::PointerType getBaseType() {
3180+
return mlir::cast<cir::PointerType>(getBase().getType());
3181+
}
3182+
}];
3183+
3184+
let hasVerifier = 1;
3185+
}
3186+
31353187
//===----------------------------------------------------------------------===//
31363188
// VecInsertOp
31373189
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenBuilder.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,48 @@ mlir::Value CIRGenBuilderTy::maybeBuildArrayDecay(mlir::Location loc,
2828
return arrayPtr;
2929
}
3030

31-
mlir::Value CIRGenBuilderTy::getArrayElement(mlir::Location arrayLocBegin,
31+
mlir::Value CIRGenBuilderTy::promoteArrayIndex(const clang::TargetInfo &ti,
32+
mlir::Location loc,
33+
mlir::Value index) {
34+
// Get the array index type.
35+
auto arrayIndexWidth = ti.getTypeWidth(clang::TargetInfo::IntType::SignedInt);
36+
mlir::Type arrayIndexType = getSIntNTy(arrayIndexWidth);
37+
38+
// If this is a boolean, zero-extend it to the array index type.
39+
if (auto boolTy = mlir::dyn_cast<cir::BoolType>(index.getType()))
40+
return create<cir::CastOp>(loc, arrayIndexType, cir::CastKind::bool_to_int,
41+
index);
42+
43+
// If this an integer, ensure that it is at least as width as the array index
44+
// type.
45+
if (auto intTy = mlir::dyn_cast<cir::IntType>(index.getType())) {
46+
if (intTy.getWidth() < arrayIndexWidth)
47+
return create<cir::CastOp>(loc, arrayIndexType, cir::CastKind::integral,
48+
index);
49+
}
50+
51+
return index;
52+
}
53+
54+
mlir::Value CIRGenBuilderTy::getArrayElement(const clang::TargetInfo &ti,
55+
mlir::Location arrayLocBegin,
3256
mlir::Location arrayLocEnd,
3357
mlir::Value arrayPtr,
3458
mlir::Type eltTy, mlir::Value idx,
3559
bool shouldDecay) {
60+
auto arrayPtrTy = mlir::dyn_cast<cir::PointerType>(arrayPtr.getType());
61+
assert(arrayPtrTy && "expected pointer type");
62+
63+
// If the array pointer is not decayed, emit a GetElementOp.
64+
auto arrayTy = mlir::dyn_cast<cir::ArrayType>(arrayPtrTy.getPointee());
65+
if (shouldDecay && arrayTy && arrayTy == eltTy) {
66+
auto eltPtrTy =
67+
getPointerTo(arrayTy.getElementType(), arrayPtrTy.getAddrSpace());
68+
return create<cir::GetElementOp>(arrayLocEnd, eltPtrTy, arrayPtr,
69+
promoteArrayIndex(ti, arrayLocBegin, idx));
70+
}
71+
72+
// If we don't have sufficient type information, emit a PtrStrideOp.
3673
mlir::Value basePtr = arrayPtr;
3774
if (shouldDecay)
3875
basePtr = maybeBuildArrayDecay(arrayLocBegin, arrayPtr, eltTy);

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "clang/AST/Decl.h"
1818
#include "clang/AST/Type.h"
19+
#include "clang/Basic/TargetInfo.h"
1920
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
2021
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
2122
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
@@ -1030,10 +1031,15 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
10301031
return create<cir::GetRuntimeMemberOp>(loc, resultTy, objectPtr, memberPtr);
10311032
}
10321033

1034+
/// Promote a value for use as an array index.
1035+
mlir::Value promoteArrayIndex(const clang::TargetInfo &TargetInfo,
1036+
mlir::Location loc, mlir::Value index);
1037+
10331038
/// Create a cir.ptr_stride operation to get access to an array element.
10341039
/// idx is the index of the element to access, shouldDecay is true if the
10351040
/// result should decay to a pointer to the element type.
1036-
mlir::Value getArrayElement(mlir::Location arrayLocBegin,
1041+
mlir::Value getArrayElement(const clang::TargetInfo &targetInfo,
1042+
mlir::Location arrayLocBegin,
10371043
mlir::Location arrayLocEnd, mlir::Value arrayPtr,
10381044
mlir::Type eltTy, mlir::Value idx,
10391045
bool shouldDecay);

0 commit comments

Comments
 (0)