Skip to content

Commit 495eb4f

Browse files
committed
[𝘀𝗽𝗿] changes introduced through rebase
Created using spr 1.3.4 [skip ci]
2 parents 272a3d0 + 5427973 commit 495eb4f

File tree

24 files changed

+1446
-88
lines changed

24 files changed

+1446
-88
lines changed

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

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,59 @@
1010
#define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
1111

1212
#include "clang/AST/CharUnits.h"
13-
#include "clang/AST/Type.h"
1413
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
1514
#include "clang/CIR/Dialect/IR/CIRDialect.h"
1615
#include "clang/CIR/Dialect/IR/CIRTypes.h"
16+
#include "llvm/ADT/STLForwardCompat.h"
1717
#include "llvm/Support/ErrorHandling.h"
1818

1919
#include "mlir/IR/Builders.h"
2020
#include "mlir/IR/BuiltinTypes.h"
21+
#include "mlir/IR/Location.h"
2122
#include "mlir/IR/Types.h"
2223

2324
namespace cir {
2425

26+
enum class OverflowBehavior {
27+
None = 0,
28+
NoSignedWrap = 1 << 0,
29+
NoUnsignedWrap = 1 << 1,
30+
Saturated = 1 << 2,
31+
};
32+
33+
constexpr OverflowBehavior operator|(OverflowBehavior a, OverflowBehavior b) {
34+
return static_cast<OverflowBehavior>(llvm::to_underlying(a) |
35+
llvm::to_underlying(b));
36+
}
37+
38+
constexpr OverflowBehavior operator&(OverflowBehavior a, OverflowBehavior b) {
39+
return static_cast<OverflowBehavior>(llvm::to_underlying(a) &
40+
llvm::to_underlying(b));
41+
}
42+
43+
constexpr OverflowBehavior &operator|=(OverflowBehavior &a,
44+
OverflowBehavior b) {
45+
a = a | b;
46+
return a;
47+
}
48+
49+
constexpr OverflowBehavior &operator&=(OverflowBehavior &a,
50+
OverflowBehavior b) {
51+
a = a & b;
52+
return a;
53+
}
54+
2555
class CIRBaseBuilderTy : public mlir::OpBuilder {
2656

2757
public:
2858
CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
2959
: mlir::OpBuilder(&mlirContext) {}
3060

61+
mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ,
62+
const llvm::APInt &val) {
63+
return create<cir::ConstantOp>(loc, typ, getAttr<cir::IntAttr>(typ, val));
64+
}
65+
3166
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr) {
3267
return create<cir::ConstantOp>(loc, attr.getType(), attr);
3368
}
@@ -143,6 +178,93 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
143178
return createCast(loc, cir::CastKind::bitcast, src, newTy);
144179
}
145180

181+
//===--------------------------------------------------------------------===//
182+
// Binary Operators
183+
//===--------------------------------------------------------------------===//
184+
185+
mlir::Value createBinop(mlir::Location loc, mlir::Value lhs,
186+
cir::BinOpKind kind, mlir::Value rhs) {
187+
return create<cir::BinOp>(loc, lhs.getType(), kind, lhs, rhs);
188+
}
189+
190+
mlir::Value createLowBitsSet(mlir::Location loc, unsigned size,
191+
unsigned bits) {
192+
llvm::APInt val = llvm::APInt::getLowBitsSet(size, bits);
193+
auto type = cir::IntType::get(getContext(), size, /*isSigned=*/false);
194+
return getConstAPInt(loc, type, val);
195+
}
196+
197+
mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
198+
return createBinop(loc, lhs, cir::BinOpKind::And, rhs);
199+
}
200+
201+
mlir::Value createOr(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
202+
return createBinop(loc, lhs, cir::BinOpKind::Or, rhs);
203+
}
204+
205+
mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
206+
OverflowBehavior ob = OverflowBehavior::None) {
207+
auto op =
208+
create<cir::BinOp>(loc, lhs.getType(), cir::BinOpKind::Mul, lhs, rhs);
209+
op.setNoUnsignedWrap(
210+
llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
211+
op.setNoSignedWrap(
212+
llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
213+
return op;
214+
}
215+
mlir::Value createNSWMul(mlir::Location loc, mlir::Value lhs,
216+
mlir::Value rhs) {
217+
return createMul(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
218+
}
219+
mlir::Value createNUWAMul(mlir::Location loc, mlir::Value lhs,
220+
mlir::Value rhs) {
221+
return createMul(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
222+
}
223+
224+
mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
225+
OverflowBehavior ob = OverflowBehavior::Saturated) {
226+
auto op =
227+
create<cir::BinOp>(loc, lhs.getType(), cir::BinOpKind::Sub, lhs, rhs);
228+
op.setNoUnsignedWrap(
229+
llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
230+
op.setNoSignedWrap(
231+
llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
232+
op.setSaturated(llvm::to_underlying(ob & OverflowBehavior::Saturated));
233+
return op;
234+
}
235+
236+
mlir::Value createNSWSub(mlir::Location loc, mlir::Value lhs,
237+
mlir::Value rhs) {
238+
return createSub(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
239+
}
240+
241+
mlir::Value createNUWSub(mlir::Location loc, mlir::Value lhs,
242+
mlir::Value rhs) {
243+
return createSub(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
244+
}
245+
246+
mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs,
247+
OverflowBehavior ob = OverflowBehavior::None) {
248+
auto op =
249+
create<cir::BinOp>(loc, lhs.getType(), cir::BinOpKind::Add, lhs, rhs);
250+
op.setNoUnsignedWrap(
251+
llvm::to_underlying(ob & OverflowBehavior::NoUnsignedWrap));
252+
op.setNoSignedWrap(
253+
llvm::to_underlying(ob & OverflowBehavior::NoSignedWrap));
254+
op.setSaturated(llvm::to_underlying(ob & OverflowBehavior::Saturated));
255+
return op;
256+
}
257+
258+
mlir::Value createNSWAdd(mlir::Location loc, mlir::Value lhs,
259+
mlir::Value rhs) {
260+
return createAdd(loc, lhs, rhs, OverflowBehavior::NoSignedWrap);
261+
}
262+
263+
mlir::Value createNUWAdd(mlir::Location loc, mlir::Value lhs,
264+
mlir::Value rhs) {
265+
return createAdd(loc, lhs, rhs, OverflowBehavior::NoUnsignedWrap);
266+
}
267+
146268
//
147269
// Block handling helpers
148270
// ----------------------

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,69 @@ def ForOp : CIR_Op<"for", [LoopOpInterface, NoRegionArguments]> {
826826
}];
827827
}
828828

829+
//===----------------------------------------------------------------------===//
830+
// BinOp
831+
//===----------------------------------------------------------------------===//
832+
833+
// FIXME: represent Commutative, Idempotent traits for appropriate binops
834+
def BinOpKind_Mul : I32EnumAttrCase<"Mul", 1, "mul">;
835+
def BinOpKind_Div : I32EnumAttrCase<"Div", 2, "div">;
836+
def BinOpKind_Rem : I32EnumAttrCase<"Rem", 3, "rem">;
837+
def BinOpKind_Add : I32EnumAttrCase<"Add", 4, "add">;
838+
def BinOpKind_Sub : I32EnumAttrCase<"Sub", 5, "sub">;
839+
def BinOpKind_And : I32EnumAttrCase<"And", 8, "and">;
840+
def BinOpKind_Xor : I32EnumAttrCase<"Xor", 9, "xor">;
841+
def BinOpKind_Or : I32EnumAttrCase<"Or", 10, "or">;
842+
// TODO(cir): Do we need a min binop?
843+
def BinOpKind_Max : I32EnumAttrCase<"Max", 11, "max">;
844+
845+
def BinOpKind : I32EnumAttr<
846+
"BinOpKind",
847+
"binary operation (arith and logic) kind",
848+
[BinOpKind_Mul, BinOpKind_Div, BinOpKind_Rem,
849+
BinOpKind_Add, BinOpKind_Sub,
850+
BinOpKind_And, BinOpKind_Xor,
851+
BinOpKind_Or, BinOpKind_Max]> {
852+
let cppNamespace = "::cir";
853+
}
854+
855+
def BinOp : CIR_Op<"binop", [Pure,
856+
SameTypeOperands, SameOperandsAndResultType]> {
857+
858+
let summary = "Binary operations (arith and logic)";
859+
let description = [{
860+
cir.binop performs the binary operation according to
861+
the specified opcode kind: [mul, div, rem, add, sub,
862+
and, xor, or, max].
863+
864+
It requires two input operands and has one result, all types
865+
should be the same.
866+
867+
```mlir
868+
%7 = cir.binop(add, %1, %2) : !s32i
869+
%7 = cir.binop(mul, %1, %2) : !u8i
870+
```
871+
}];
872+
873+
// TODO: get more accurate than CIR_AnyType
874+
let results = (outs CIR_AnyType:$result);
875+
let arguments = (ins Arg<BinOpKind, "binop kind">:$kind,
876+
CIR_AnyType:$lhs, CIR_AnyType:$rhs,
877+
UnitAttr:$no_unsigned_wrap,
878+
UnitAttr:$no_signed_wrap,
879+
UnitAttr:$saturated);
880+
881+
let assemblyFormat = [{
882+
`(` $kind `,` $lhs `,` $rhs `)`
883+
(`nsw` $no_signed_wrap^)?
884+
(`nuw` $no_unsigned_wrap^)?
885+
(`sat` $saturated^)?
886+
`:` type($lhs) attr-dict
887+
}];
888+
889+
let hasVerifier = 1;
890+
}
891+
829892
//===----------------------------------------------------------------------===//
830893
// GlobalOp
831894
//===----------------------------------------------------------------------===//

clang/include/clang/CIR/Dialect/IR/CIRTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
namespace cir {
2222

2323
bool isAnyFloatingPointType(mlir::Type t);
24+
bool isFPOrFPVectorTy(mlir::Type);
2425

2526
} // namespace cir
2627

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ struct MissingFeatures {
7979
static bool opUnarySignedOverflow() { return false; }
8080
static bool opUnaryPromotionType() { return false; }
8181

82+
// Clang early optimizations or things defered to LLVM lowering.
83+
static bool mayHaveIntegerOverflow() { return false; }
84+
8285
// Misc
8386
static bool cxxABI() { return false; }
8487
static bool tryEmitAsConstant() { return false; }
@@ -93,16 +96,19 @@ struct MissingFeatures {
9396
static bool stackSaveOp() { return false; }
9497
static bool aggValueSlot() { return false; }
9598
static bool generateDebugInfo() { return false; }
99+
static bool pointerOverflowSanitizer() { return false; }
96100
static bool fpConstraints() { return false; }
97101
static bool sanitizers() { return false; }
98102
static bool addHeapAllocSiteMetadata() { return false; }
99103
static bool targetCodeGenInfoGetNullPointer() { return false; }
100-
static bool CGFPOptionsRAII() { return false; }
101104
static bool loopInfoStack() { return false; }
102105
static bool requiresCleanups() { return false; }
103106
static bool createProfileWeightsForLoop() { return false; }
104107
static bool emitCondLikelihoodViaExpectIntrinsic() { return false; }
105108
static bool pgoUse() { return false; }
109+
static bool cgFPOptionsRAII() { return false; }
110+
static bool metaDataNode() { return false; }
111+
static bool fastMathFlags() { return false; }
106112

107113
// Missing types
108114
static bool dataMemberType() { return false; }
@@ -111,6 +117,8 @@ struct MissingFeatures {
111117
static bool scalableVectors() { return false; }
112118
static bool unsizedTypes() { return false; }
113119
static bool vectorType() { return false; }
120+
static bool complexType() { return false; }
121+
static bool fixedPointType() { return false; }
114122

115123
// Future CIR operations
116124
static bool awaitOp() { return false; }
@@ -127,6 +135,8 @@ struct MissingFeatures {
127135
static bool ternaryOp() { return false; }
128136
static bool tryOp() { return false; }
129137
static bool zextOp() { return false; }
138+
static bool ptrStrideOp() { return false; }
139+
static bool ptrDiffOp() { return false; }
130140
};
131141

132142
} // namespace cir

0 commit comments

Comments
 (0)