Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,23 @@ class LLVM_CastOpWithNNegFlag<string mnemonic, string instName, Type type,
}];
}

class LLVM_CastOpWithOverflowFlag<string mnemonic, string instName, Type type,
Type resultType, list<Trait> traits = []> :
LLVM_Op<mnemonic, !listconcat([Pure], [DeclareOpInterfaceMethods<IntegerOverflowFlagsInterface>], traits)>,
LLVM_Builder<"$res = builder.Create" # instName # "($arg, $_resultType, /*Name=*/\"\", op.hasNoUnsignedWrap(), op.hasNoSignedWrap());"> {
let arguments = (ins type:$arg, EnumProperty<"IntegerOverflowFlags", "", "IntegerOverflowFlags::none">:$overflowFlags);
let results = (outs resultType:$res);
let builders = [LLVM_OneResultOpBuilder];
let assemblyFormat = "$arg `` custom<OverflowFlags>($overflowFlags) attr-dict `:` type($arg) `to` type($res)";
string llvmInstName = instName;
string mlirBuilder = [{
auto op = $_builder.create<$_qualCppClassName>(
$_location, $_resultType, $arg);
moduleImport.setIntegerOverflowFlags(inst, op);
$res = op;
}];
}

def LLVM_BitcastOp : LLVM_CastOp<"bitcast", "BitCast", LLVM_AnyNonAggregate,
LLVM_AnyNonAggregate, [DeclareOpInterfaceMethods<PromotableOpInterface>]> {
let hasFolder = 1;
Expand Down Expand Up @@ -554,7 +571,7 @@ def LLVM_ZExtOp : LLVM_CastOpWithNNegFlag<"zext", "ZExt",
let hasFolder = 1;
let hasVerifier = 1;
}
def LLVM_TruncOp : LLVM_CastOp<"trunc", "Trunc",
def LLVM_TruncOp : LLVM_CastOpWithOverflowFlag<"trunc", "Trunc",
LLVM_ScalarOrVectorOf<AnySignlessInteger>,
LLVM_ScalarOrVectorOf<AnySignlessInteger>>;
def LLVM_SIToFPOp : LLVM_CastOp<"sitofp", "SIToFP",
Expand Down
17 changes: 17 additions & 0 deletions mlir/test/Dialect/LLVMIR/roundtrip.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,23 @@ func.func @nneg_casts(%arg0: i32, %arg1: i64, %arg2: vector<4xi32>,
llvm.return
}

// CHECK-LABEL: @casts_overflow
// CHECK-SAME: (%[[I32:.*]]: i32, %[[I64:.*]]: i64, %[[V4I32:.*]]: vector<4xi32>, %[[V4I64:.*]]: vector<4xi64>, %[[PTR:.*]]: !llvm.ptr)
func.func @casts_overflow(%arg0: i32, %arg1: i64, %arg2: vector<4xi32>,
%arg3: vector<4xi64>, %arg4: !llvm.ptr) {
// CHECK: = llvm.trunc %[[I64]] overflow<nsw> : i64 to i56
%0 = llvm.trunc %arg1 overflow<nsw> : i64 to i56
// CHECK: = llvm.trunc %[[I64]] overflow<nuw> : i64 to i56
%1 = llvm.trunc %arg1 overflow<nuw> : i64 to i56
// CHECK: = llvm.trunc %[[I64]] overflow<nsw, nuw> : i64 to i56
%2 = llvm.trunc %arg1 overflow<nsw, nuw> : i64 to i56
// CHECK: = llvm.trunc %[[I64]] overflow<nsw, nuw> : i64 to i56
%3 = llvm.trunc %arg1 overflow<nuw, nsw> : i64 to i56
// CHECK: = llvm.trunc %[[V4I64]] overflow<nsw> : vector<4xi64> to vector<4xi56>
%4 = llvm.trunc %arg3 overflow<nsw> : vector<4xi64> to vector<4xi56>
llvm.return
}

// CHECK-LABEL: @vect
func.func @vect(%arg0: vector<4xf32>, %arg1: i32, %arg2: f32, %arg3: !llvm.vec<2 x ptr>) {
// CHECK: = llvm.extractelement {{.*}} : vector<4xf32>
Expand Down
2 changes: 2 additions & 0 deletions mlir/test/Target/LLVMIR/Import/nsw_nuw.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ define void @intflag_inst(i64 %arg1, i64 %arg2) {
%3 = mul nsw nuw i64 %arg1, %arg2
; CHECK: llvm.shl %{{.*}}, %{{.*}} overflow<nsw, nuw> : i64
%4 = shl nuw nsw i64 %arg1, %arg2
; CHECK: llvm.trunc %{{.*}} overflow<nsw> : i64 to i32
%5 = trunc nsw i64 %arg1 to i32
ret void
}
2 changes: 2 additions & 0 deletions mlir/test/Target/LLVMIR/nsw_nuw.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ llvm.func @intflags_func(%arg0: i64, %arg1: i64) {
%2 = llvm.mul %arg0, %arg1 overflow <nsw, nuw> : i64
// CHECK: %{{.*}} = shl nuw nsw i64 %{{.*}}, %{{.*}}
%3 = llvm.shl %arg0, %arg1 overflow <nsw, nuw> : i64
// CHECK: %{{.*}} = trunc nuw i64 %{{.*}} to i32
%4 = llvm.trunc %arg1 overflow<nuw> : i64 to i32
llvm.return
}
Loading