Skip to content

Commit 37c7e20

Browse files
committed
storeop and usages
Created using spr 1.3.5
2 parents 60e4512 + 3d16a0f commit 37c7e20

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1868
-414
lines changed

clang/include/clang/CIR/ABIArgInfo.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ class ABIArgInfo {
103103
bool InReg : 1; // isDirect() || isExtend() || isIndirect()
104104
bool CanBeFlattened : 1; // isDirect()
105105
bool SignExt : 1; // isExtend()
106+
bool IndirectByVal : 1; // isIndirect()
107+
bool IndirectRealign : 1; // isIndirect()
108+
bool SRetAfterThis : 1; // isIndirect()
106109

107110
bool canHavePaddingType() const {
108111
return isDirect() || isExtend() || isIndirect() || isIndirectAliased() ||
@@ -195,6 +198,43 @@ class ABIArgInfo {
195198

196199
static ABIArgInfo getIgnore() { return ABIArgInfo(Ignore); }
197200

201+
static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true,
202+
bool Realign = false,
203+
mlir::Type Padding = nullptr) {
204+
auto AI = ABIArgInfo(Indirect);
205+
AI.setIndirectAlign(Alignment);
206+
AI.setIndirectByVal(ByVal);
207+
AI.setIndirectRealign(Realign);
208+
AI.setSRetAfterThis(false);
209+
AI.setPaddingType(Padding);
210+
return AI;
211+
}
212+
213+
void setIndirectAlign(unsigned align) {
214+
assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
215+
IndirectAttr.Align = align;
216+
}
217+
218+
void setIndirectByVal(bool IBV) {
219+
assert(isIndirect() && "Invalid kind!");
220+
IndirectByVal = IBV;
221+
}
222+
223+
void setIndirectRealign(bool IR) {
224+
assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
225+
IndirectRealign = IR;
226+
}
227+
228+
void setSRetAfterThis(bool AfterThis) {
229+
assert(isIndirect() && "Invalid kind!");
230+
SRetAfterThis = AfterThis;
231+
}
232+
233+
bool isSRetAfterThis() const {
234+
assert(isIndirect() && "Invalid kind!");
235+
return SRetAfterThis;
236+
}
237+
198238
Kind getKind() const { return TheKind; }
199239
bool isDirect() const { return TheKind == Direct; }
200240
bool isInAlloca() const { return TheKind == InAlloca; }

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
115115
return getPointerTo(::mlir::cir::VoidType::get(getContext()), cirAS);
116116
}
117117

118+
mlir::cir::MethodAttr getMethodAttr(mlir::cir::MethodType ty,
119+
mlir::cir::FuncOp methodFuncOp) {
120+
auto methodFuncSymbolRef = mlir::FlatSymbolRefAttr::get(methodFuncOp);
121+
return mlir::cir::MethodAttr::get(ty, methodFuncSymbolRef);
122+
}
123+
124+
mlir::cir::MethodAttr getNullMethodAttr(mlir::cir::MethodType ty) {
125+
return mlir::cir::MethodAttr::get(ty);
126+
}
127+
118128
mlir::cir::BoolAttr getCIRBoolAttr(bool state) {
119129
return mlir::cir::BoolAttr::get(getContext(), getBoolTy(), state);
120130
}
@@ -142,6 +152,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
142152
return getConstNullPtrAttr(ptrTy);
143153
if (auto structTy = mlir::dyn_cast<mlir::cir::StructType>(ty))
144154
return getZeroAttr(structTy);
155+
if (auto methodTy = mlir::dyn_cast<mlir::cir::MethodType>(ty))
156+
return getNullMethodAttr(methodTy);
145157
if (mlir::isa<mlir::cir::BoolType>(ty)) {
146158
return getCIRBoolAttr(false);
147159
}
@@ -386,6 +398,25 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
386398
return createAlloca(loc, addrType, type, name, alignmentIntAttr);
387399
}
388400

401+
mlir::Value createGetGlobal(mlir::cir::GlobalOp global,
402+
bool threadLocal = false) {
403+
return create<mlir::cir::GetGlobalOp>(
404+
global.getLoc(),
405+
getPointerTo(global.getSymType(), global.getAddrSpaceAttr()),
406+
global.getName(), threadLocal);
407+
}
408+
409+
/// Create a copy with inferred length.
410+
mlir::cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
411+
bool isVolatile = false) {
412+
return create<mlir::cir::CopyOp>(dst.getLoc(), dst, src, isVolatile);
413+
}
414+
415+
mlir::cir::MemCpyOp createMemCpy(mlir::Location loc, mlir::Value dst,
416+
mlir::Value src, mlir::Value len) {
417+
return create<mlir::cir::MemCpyOp>(loc, dst, src, len);
418+
}
419+
389420
mlir::Value createSub(mlir::Value lhs, mlir::Value rhs, bool hasNUW = false,
390421
bool hasNSW = false) {
391422
auto op = create<mlir::cir::BinOp>(lhs.getLoc(), lhs.getType(),

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

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ def LoadOp : CIR_Op<"load", [
602602
let extraClassDeclaration = [{
603603
// TODO(CIR): The final interface here should include an argument for the
604604
// SyncScope::ID.
605+
// This should be used over the ODS generated setMemOrder.
605606
void setAtomic(mlir::cir::MemOrder order);
606607
}];
607608

@@ -662,6 +663,13 @@ def StoreOp : CIR_Op<"store", [
662663
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
663664
}];
664665

666+
let extraClassDeclaration = [{
667+
// TODO(CIR): The final interface here should include an argument for the
668+
// SyncScope::ID.
669+
// This should be used over the ODS generated setMemOrder.
670+
void setAtomic(mlir::cir::MemOrder order);
671+
}];
672+
665673
// FIXME: add verifier.
666674
}
667675

@@ -3937,13 +3945,22 @@ def CopyOp : CIR_Op<"copy",
39373945
}
39383946

39393947
//===----------------------------------------------------------------------===//
3940-
// MemCpyOp
3948+
// MemCpyOp && MemMoveOp
39413949
//===----------------------------------------------------------------------===//
39423950

3943-
def MemCpyOp : CIR_Op<"libc.memcpy"> {
3944-
let arguments = (ins Arg<CIR_PointerType, "", [MemWrite]>:$dst,
3945-
Arg<CIR_PointerType, "", [MemRead]>:$src,
3946-
PrimitiveInt:$len);
3951+
class CIR_MemCpyOp<string mnemonic>: CIR_Op<mnemonic, [AllTypesMatch<["dst", "src"]>]> {
3952+
let arguments = (ins Arg<VoidPtr, "", [MemWrite]>:$dst,
3953+
Arg<VoidPtr, "", [MemRead]>:$src,
3954+
PrimitiveUInt:$len);
3955+
let hasVerifier = 0;
3956+
3957+
let extraClassDeclaration = [{
3958+
/// Returns the byte length type.
3959+
mlir::cir::IntType getLenTy() { return getLen().getType(); }
3960+
}];
3961+
}
3962+
3963+
def MemCpyOp : CIR_MemCpyOp<"libc.memcpy"> {
39473964
let summary = "Equivalent to libc's `memcpy`";
39483965
let description = [{
39493966
Given two CIR pointers, `src` and `dst`, `cir.libc.memcpy` will copy `len`
@@ -3966,17 +3983,29 @@ def MemCpyOp : CIR_Op<"libc.memcpy"> {
39663983
$len `bytes` `from` $src `to` $dst attr-dict
39673984
`:` type($len) `` `,` qualified(type($src)) `->` qualified(type($dst))
39683985
}];
3969-
let hasVerifier = 1;
3986+
}
39703987

3971-
let extraClassDeclaration = [{
3972-
/// Returns the data source pointer type.
3973-
mlir::cir::PointerType getSrcTy() { return getSrc().getType(); }
3988+
def MemMoveOp : CIR_MemCpyOp<"libc.memmove"> {
3989+
let summary = "Equivalent to libc's `memmove`";
3990+
let description = [{
3991+
Given two CIR pointers, `src` and `dst`, `cir.libc.memmove` will copy `len`
3992+
bytes from the memory pointed by `src` to the memory pointed by `dst`.
39743993

3975-
/// Returns the data destination pointer type.
3976-
mlir::cir::PointerType getDstTy() { return getDst().getType(); }
3994+
similiar to `cir.libc.memcpy` but accounts for overlapping memory.
39773995

3978-
/// Returns the byte length type.
3979-
mlir::cir::IntType getLenTy() { return getLen().getType(); }
3996+
Examples:
3997+
3998+
```mlir
3999+
// Copying 2 bytes from one array to a struct:
4000+
%2 = cir.const #cir.int<2> : !u32i
4001+
cir.libc.memmove %2 bytes from %arr to %struct : !cir.ptr<!void>, !u64i
4002+
```
4003+
}];
4004+
4005+
4006+
let assemblyFormat = [{
4007+
$len `bytes` `from` $src `to` $dst attr-dict
4008+
`:` qualified(type($dst)) `,` type($len)
39804009
}];
39814010
}
39824011

@@ -4131,6 +4160,26 @@ def SinOp : UnaryFPToFPBuiltinOp<"sin", "SinOp">;
41314160
def SqrtOp : UnaryFPToFPBuiltinOp<"sqrt", "SqrtOp">;
41324161
def TruncOp : UnaryFPToFPBuiltinOp<"trunc", "FTruncOp">;
41334162

4163+
def AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> {
4164+
let arguments = (ins PrimitiveSInt:$src, UnitAttr:$poison);
4165+
let results = (outs PrimitiveSInt:$result);
4166+
let summary = [{
4167+
libc builtin equivalent abs, labs, llabs
4168+
4169+
The `poison` argument indicate whether the result value
4170+
is a poison value if the first argument is statically or
4171+
dynamically an INT_MIN value.
4172+
4173+
Example:
4174+
4175+
```mlir
4176+
%0 = cir.const #cir.int<-42> : s32i
4177+
%1 = cir.abs %0 poison : s32i
4178+
```
4179+
}];
4180+
let assemblyFormat = "$src ( `poison` $poison^ )? `:` type($src) attr-dict";
4181+
}
4182+
41344183
class BinaryFPToFPBuiltinOp<string mnemonic, string llvmOpName>
41354184
: CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> {
41364185
let summary = [{

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,6 @@ struct MissingFeatures {
172172
static bool volatileTypes() { return false; }
173173
static bool syncScopeID() { return false; }
174174

175-
// AArch64 Neon builtin related.
176-
static bool buildNeonShiftVector() { return false; }
177-
178175
// ABIInfo queries.
179176
static bool useTargetLoweringABIInfo() { return false; }
180177

@@ -271,6 +268,7 @@ struct MissingFeatures {
271268
static bool ABIParameterCoercion() { return false; }
272269
static bool ABIPointerParameterAttrs() { return false; }
273270
static bool ABITransparentUnionHandling() { return false; }
271+
static bool ABIPotentialArgAccess() { return false; }
274272

275273
//-- Missing AST queries
276274

@@ -401,6 +399,8 @@ struct MissingFeatures {
401399

402400
// This Itanium bit is currently being skipped in cir.
403401
static bool itaniumRecordLayoutBuilderFinishLayout() { return false; }
402+
403+
static bool mustProgress() { return false; }
404404
};
405405

406406
} // namespace cir

clang/lib/CIR/CodeGen/CIRGenAtomic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1462,7 +1462,7 @@ void CIRGenFunction::buildAtomicStore(RValue rvalue, LValue dest,
14621462
MO = mlir::cir::MemOrder::Release;
14631463
// Initializations don't need to be atomic.
14641464
if (!isInit)
1465-
store.setMemOrder(MO);
1465+
store.setAtomic(MO);
14661466

14671467
// Other decoration.
14681468
if (IsVolatile)

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,6 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
251251
return mlir::cir::DataMemberAttr::get(getContext(), ty, std::nullopt);
252252
}
253253

254-
mlir::cir::MethodAttr getMethodAttr(mlir::cir::MethodType ty,
255-
mlir::cir::FuncOp methodFuncOp) {
256-
auto methodFuncSymbolRef = mlir::FlatSymbolRefAttr::get(methodFuncOp);
257-
return mlir::cir::MethodAttr::get(ty, methodFuncSymbolRef);
258-
}
259-
260-
mlir::cir::MethodAttr getNullMethodAttr(mlir::cir::MethodType ty) {
261-
return mlir::cir::MethodAttr::get(ty);
262-
}
263-
264254
// TODO(cir): Once we have CIR float types, replace this by something like a
265255
// NullableValueInterface to allow for type-independent queries.
266256
bool isNullValue(mlir::Attribute attr) const {
@@ -603,7 +593,8 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
603593
mlir::cir::ConstantOp getZero(mlir::Location loc, mlir::Type ty) {
604594
// TODO: dispatch creation for primitive types.
605595
assert((mlir::isa<mlir::cir::StructType>(ty) ||
606-
mlir::isa<mlir::cir::ArrayType>(ty)) &&
596+
mlir::isa<mlir::cir::ArrayType>(ty) ||
597+
mlir::isa<mlir::cir::VectorType>(ty)) &&
607598
"NYI for other types");
608599
return create<mlir::cir::ConstantOp>(loc, ty, getZeroAttr(ty));
609600
}
@@ -613,12 +604,6 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
613604
// --------------------------
614605
//
615606

616-
/// Create a copy with inferred length.
617-
mlir::cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
618-
bool isVolatile = false) {
619-
return create<mlir::cir::CopyOp>(dst.getLoc(), dst, src, isVolatile);
620-
}
621-
622607
/// Create a break operation.
623608
mlir::cir::BreakOp createBreak(mlir::Location loc) {
624609
return create<mlir::cir::BreakOp>(loc);
@@ -634,6 +619,11 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
634619
return create<mlir::cir::MemCpyOp>(loc, dst, src, len);
635620
}
636621

622+
mlir::cir::MemMoveOp createMemMove(mlir::Location loc, mlir::Value dst,
623+
mlir::Value src, mlir::Value len) {
624+
return create<mlir::cir::MemMoveOp>(loc, dst, src, len);
625+
}
626+
637627
mlir::Value createNeg(mlir::Value value) {
638628

639629
if (auto intTy = mlir::dyn_cast<mlir::cir::IntType>(value.getType())) {
@@ -764,14 +754,6 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
764754
addrSpace);
765755
}
766756

767-
mlir::Value createGetGlobal(mlir::cir::GlobalOp global,
768-
bool threadLocal = false) {
769-
return create<mlir::cir::GetGlobalOp>(
770-
global.getLoc(),
771-
getPointerTo(global.getSymType(), global.getAddrSpaceAttr()),
772-
global.getName(), threadLocal);
773-
}
774-
775757
mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType,
776758
mlir::Value addr, mlir::Type storageType,
777759
const CIRGenBitFieldInfo &info,

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -855,9 +855,33 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
855855
case Builtin::BIllabs:
856856
case Builtin::BI__builtin_abs:
857857
case Builtin::BI__builtin_labs:
858-
case Builtin::BI__builtin_llabs:
859-
llvm_unreachable("Builtin::BIabs like NYI");
860-
858+
case Builtin::BI__builtin_llabs: {
859+
bool SanitizeOverflow = SanOpts.has(SanitizerKind::SignedIntegerOverflow);
860+
auto Arg = buildScalarExpr(E->getArg(0));
861+
mlir::Value Result;
862+
switch (getLangOpts().getSignedOverflowBehavior()) {
863+
case LangOptions::SOB_Defined: {
864+
auto Call = getBuilder().create<mlir::cir::AbsOp>(
865+
getLoc(E->getExprLoc()), Arg.getType(), Arg, false);
866+
Result = Call->getResult(0);
867+
break;
868+
}
869+
case LangOptions::SOB_Undefined: {
870+
if (!SanitizeOverflow) {
871+
auto Call = getBuilder().create<mlir::cir::AbsOp>(
872+
getLoc(E->getExprLoc()), Arg.getType(), Arg, true);
873+
Result = Call->getResult(0);
874+
break;
875+
}
876+
llvm_unreachable("BI__builtin_abs with LangOptions::SOB_Undefined when "
877+
"SanitizeOverflow is true");
878+
}
879+
[[fallthrough]];
880+
case LangOptions::SOB_Trapping:
881+
llvm_unreachable("BI__builtin_abs with LangOptions::SOB_Trapping");
882+
}
883+
return RValue::get(Result);
884+
}
861885
case Builtin::BI__builtin_complex: {
862886
mlir::Value Real = buildScalarExpr(E->getArg(0));
863887
mlir::Value Imag = buildScalarExpr(E->getArg(1));
@@ -1411,9 +1435,19 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
14111435
llvm_unreachable("BI__builtin___memmove_chk NYI");
14121436

14131437
case Builtin::BImemmove:
1414-
case Builtin::BI__builtin_memmove:
1415-
llvm_unreachable("BImemmove like NYI");
1416-
1438+
case Builtin::BI__builtin_memmove: {
1439+
Address Dest = buildPointerWithAlignment(E->getArg(0));
1440+
Address Src = buildPointerWithAlignment(E->getArg(1));
1441+
mlir::Value SizeVal = buildScalarExpr(E->getArg(2));
1442+
buildNonNullArgCheck(RValue::get(Dest.getPointer()),
1443+
E->getArg(0)->getType(), E->getArg(0)->getExprLoc(),
1444+
FD, 0);
1445+
buildNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
1446+
E->getArg(1)->getExprLoc(), FD, 1);
1447+
builder.createMemMove(getLoc(E->getSourceRange()), Dest.getPointer(),
1448+
Src.getPointer(), SizeVal);
1449+
return RValue::get(Dest.getPointer());
1450+
}
14171451
case Builtin::BImemset:
14181452
case Builtin::BI__builtin_memset:
14191453
llvm_unreachable("BImemset like NYI");
@@ -1804,9 +1838,12 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
18041838
case Builtin::BI__builtin_function_start:
18051839
llvm_unreachable("BI__builtin_function_start NYI");
18061840
case Builtin::BI__builtin_operator_new:
1807-
llvm_unreachable("BI__builtin_operator_new NYI");
1841+
return buildBuiltinNewDeleteCall(
1842+
E->getCallee()->getType()->castAs<FunctionProtoType>(), E, false);
18081843
case Builtin::BI__builtin_operator_delete:
1809-
llvm_unreachable("BI__builtin_operator_delete NYI");
1844+
buildBuiltinNewDeleteCall(
1845+
E->getCallee()->getType()->castAs<FunctionProtoType>(), E, true);
1846+
return RValue::get(nullptr);
18101847
case Builtin::BI__builtin_is_aligned:
18111848
llvm_unreachable("BI__builtin_is_aligned NYI");
18121849
case Builtin::BI__builtin_align_up:

0 commit comments

Comments
 (0)