From ec3cbe92c009297e093552c360d57b023a422255 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Markus=20B=C3=B6ck?= Date: Wed, 19 Jul 2023 09:32:17 +0200 Subject: [PATCH] [mlir][LLVM] add `llvm.ssa.copy` intrinsic This is quite the niche intrinsic, whose whole purpose is to be able to essentially split an SSA value to be able to attach additional information to the new value. It therefore really acts like a noop that just passes through its argument. It interestingly does not have any support in CodeGen and is therefore required to also be deleted by any pass creating it. Differential Revision: https://reviews.llvm.org/D155678 --- mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td | 7 +++++++ mlir/test/Target/LLVMIR/Import/intrinsic.ll | 8 ++++++++ mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir | 8 ++++++++ 3 files changed, 23 insertions(+) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td index d131a49..94c3687 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td @@ -419,6 +419,13 @@ def LLVM_USHLSat : LLVM_BinarySameArgsIntrOpI<"ushl.sat">; def LLVM_AssumeOp : LLVM_ZeroResultIntrOp<"assume", []>, Arguments<(ins I1:$cond)>; +def LLVM_SSACopyOp : LLVM_OneResultIntrOp<"ssa.copy", [], [0], + [Pure, SameOperandsAndResultType]> { + let arguments = (ins AnyType:$operand); + + let assemblyFormat = "$operand attr-dict `:` type($operand)"; +} + def LLVM_IsConstantOp : LLVM_IntrOp<"is.constant", [], [0], [Pure], 1> { let arguments = (ins LLVM_Type:$val); let results = (outs I1:$res); diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll index 34f0b5a..a0aa4ae 100644 --- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll +++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll @@ -850,6 +850,13 @@ define void @vector_predication_intrinsics(<8 x i32> %0, <8 x i32> %1, <8 x floa ret void } +; CHECK-LABEL: llvm.func @ssa_copy +define float @ssa_copy(float %0) { + ; CHECK: %{{.*}} = llvm.intr.ssa.copy %{{.*}} : f32 + %2 = call float @llvm.ssa.copy.f32(float %0) + ret float %2 +} + declare float @llvm.fmuladd.f32(float, float, float) declare <8 x float> @llvm.fmuladd.v8f32(<8 x float>, <8 x float>, <8 x float>) declare float @llvm.fma.f32(float, float, float) @@ -1065,3 +1072,4 @@ declare <8 x ptr> @llvm.vp.inttoptr.v8p0.v8i64(<8 x i64>, <8 x i1>, i32) declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) declare void @llvm.assume(i1) +declare float @llvm.ssa.copy.f32(float returned) diff --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir index 674e863..d6c6855 100644 --- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir +++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir @@ -932,6 +932,13 @@ llvm.func @lifetime(%p: !llvm.ptr) { llvm.return } +// CHECK-LABEL: @ssa_copy +llvm.func @ssa_copy(%arg: f32) -> f32 { + // CHECK: call float @llvm.ssa.copy + %0 = llvm.intr.ssa.copy %arg : f32 + llvm.return %0 : f32 +} + // Check that intrinsics are declared with appropriate types. // CHECK-DAG: declare float @llvm.fma.f32(float, float, float) // CHECK-DAG: declare <8 x float> @llvm.fma.v8f32(<8 x float>, <8 x float>, <8 x float>) #0 @@ -1085,3 +1092,4 @@ llvm.func @lifetime(%p: !llvm.ptr) { // CHECK-DAG: declare <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32>, i64 immarg) // CHECK-DAG: declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) // CHECK-DAG: declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) +// CHECK-DAG: declare float @llvm.ssa.copy.f32(float returned) -- 2.7.4