From d93eb5820f73060debe0985b3499c77fbb79fc60 Mon Sep 17 00:00:00 2001 From: Jan Rehders Date: Tue, 30 Jan 2024 17:02:53 +0000 Subject: [PATCH] Change name mangling for intrinsic functions We want to avoid confusion when one op's intrinsic is the prefix of another one. Using a character which we don't use for intrinsic function names ensures this. Fixes https://github.com/GPUOpen-Drivers/llvm-dialects/issues/2 --- lib/Dialect/Dialect.cpp | 3 ++- lib/Dialect/Utils.cpp | 2 +- test/example/test-builder.test | 34 +++++++++++++++++----------------- test/example/verifier-basic.ll | 22 +++++++++++----------- test/example/visitor-basic.ll | 24 ++++++++++++------------ 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/lib/Dialect/Dialect.cpp b/lib/Dialect/Dialect.cpp index 72de8f1..7049480 100644 --- a/lib/Dialect/Dialect.cpp +++ b/lib/Dialect/Dialect.cpp @@ -281,7 +281,8 @@ bool llvm_dialects::detail::isOperationDecl(llvm::StringRef fn, if (!fn.starts_with(mnemonic)) return false; - return fn[mnemonic.size()] == '.'; + return fn.size() >= mnemonic.size() + 2 && fn[mnemonic.size()] == '_' && + fn[mnemonic.size() + 1] == '_'; } return fn == mnemonic; diff --git a/lib/Dialect/Utils.cpp b/lib/Dialect/Utils.cpp index 90b0348..292b066 100644 --- a/lib/Dialect/Utils.cpp +++ b/lib/Dialect/Utils.cpp @@ -130,7 +130,7 @@ std::string llvm_dialects::getMangledName(StringRef name, ArrayRef overloadTypes) { std::string result = name.str(); for (Type *ty : overloadTypes) { - result += '.'; + result += "__"; bool hasUnnamedType = false; result += getMangledTypeStr(ty, hasUnnamedType); diff --git a/test/example/test-builder.test b/test/example/test-builder.test index 0b8df76..854c62b 100644 --- a/test/example/test-builder.test +++ b/test/example/test-builder.test @@ -4,32 +4,32 @@ ; CHECK-LABEL: @example( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = call i32 @xd.read.i32() +; CHECK-NEXT: [[TMP0:%.*]] = call i32 @xd.read__i32() ; CHECK-NEXT: [[TMP1:%.*]] = call i64 (...) @xd.sizeof(double poison) -; CHECK-NEXT: [[TMP2:%.*]] = call i32 (...) @xd.itrunc.i32(i64 [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = call i32 (...) @xd.itrunc__i32(i64 [[TMP1]]) ; CHECK-NEXT: [[TMP3:%.*]] = call i32 @xd.add32(i32 [[TMP0]], i32 [[TMP2]], i32 7) -; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @xd.combine.i32(i32 [[TMP3]], i32 [[TMP0]]) -; CHECK-NEXT: [[TMP5:%.*]] = call i64 (...) @xd.iext.i64(i32 [[TMP4]]) +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @xd.combine__i32(i32 [[TMP3]], i32 [[TMP0]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i64 (...) @xd.iext__i64(i32 [[TMP4]]) ; CHECK-NEXT: call void (...) @xd.write(i64 [[TMP5]]) -; CHECK-NEXT: [[TMP6:%.*]] = call <2 x i32> @xd.read.v2i32() -; CHECK-NEXT: [[TMP7:%.*]] = call target("xd.vector", i32, 1, 2) (...) @xd.fromfixedvector.txd.vector_i32_1_2t(<2 x i32> [[TMP6]]) -; CHECK-NEXT: [[TMP8:%.*]] = call target("xd.vector", i32, 1, 4) @xd.read.txd.vector_i32_1_4t() -; CHECK-NEXT: [[TMP9:%.*]] = call i32 (...) @xd.extractelement.i32(target("xd.vector", i32, 1, 4) [[TMP8]], i32 [[TMP0]]) -; CHECK-NEXT: [[TMP10:%.*]] = call i32 (...) @xd.extractelement.i32(target("xd.vector", i32, 1, 4) [[TMP8]], i32 2) +; CHECK-NEXT: [[TMP6:%.*]] = call <2 x i32> @xd.read__v2i32() +; CHECK-NEXT: [[TMP7:%.*]] = call target("xd.vector", i32, 1, 2) (...) @xd.fromfixedvector__txd.vector_i32_1_2t(<2 x i32> [[TMP6]]) +; CHECK-NEXT: [[TMP8:%.*]] = call target("xd.vector", i32, 1, 4) @xd.read__txd.vector_i32_1_4t() +; CHECK-NEXT: [[TMP9:%.*]] = call i32 (...) @xd.extractelement__i32(target("xd.vector", i32, 1, 4) [[TMP8]], i32 [[TMP0]]) +; CHECK-NEXT: [[TMP10:%.*]] = call i32 (...) @xd.extractelement__i32(target("xd.vector", i32, 1, 4) [[TMP8]], i32 2) ; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP9]], [[TMP10]] -; CHECK-NEXT: [[TMP12:%.*]] = call target("xd.vector", i32, 1, 2) (...) @xd.insertelement.txd.vector_i32_1_2t(target("xd.vector", i32, 1, 2) [[TMP7]], i32 [[TMP11]], i32 [[TMP0]]) -; CHECK-NEXT: [[TMP13:%.*]] = call target("xd.vector", i32, 1, 2) (...) @xd.insertelement.txd.vector_i32_1_2t(target("xd.vector", i32, 1, 2) [[TMP12]], i32 [[TMP9]], i32 1) +; CHECK-NEXT: [[TMP12:%.*]] = call target("xd.vector", i32, 1, 2) (...) @xd.insertelement__txd.vector_i32_1_2t(target("xd.vector", i32, 1, 2) [[TMP7]], i32 [[TMP11]], i32 [[TMP0]]) +; CHECK-NEXT: [[TMP13:%.*]] = call target("xd.vector", i32, 1, 2) (...) @xd.insertelement__txd.vector_i32_1_2t(target("xd.vector", i32, 1, 2) [[TMP12]], i32 [[TMP9]], i32 1) ; CHECK-NEXT: call void (...) @xd.write(target("xd.vector", i32, 1, 2) [[TMP13]]) -; CHECK-NEXT: [[P1:%.*]] = call ptr @xd.read.p0() -; CHECK-NEXT: [[P2:%.*]] = call i8 (...) @xd.stream.add.i8(ptr [[P1]], i64 14, i8 0) +; CHECK-NEXT: [[P1:%.*]] = call ptr @xd.read__p0() +; CHECK-NEXT: [[P2:%.*]] = call i8 (...) @xd.stream.add__i8(ptr [[P1]], i64 14, i8 0) ; CHECK-NEXT: call void (...) @xd.write(i8 [[P2]]) ; CHECK-NEXT: call void (...) @xd.write.vararg(i8 [[P2]], ptr [[P1]], i8 [[P2]]) ; CHECK-NEXT: [[TMP14:%.*]] = call target("xd.handle") @xd.handle.get() -; CHECK-NEXT: [[TMP15:%.*]] = call <2 x i32> @xd.set.read.v2i32() +; CHECK-NEXT: [[TMP15:%.*]] = call <2 x i32> @xd.set.read__v2i32() ; CHECK-NEXT: call void (...) @xd.set.write(target("xd.vector", i32, 1, 2) [[TMP13]]) -; CHECK-NEXT: [[TMP16:%.*]] = call [[TMP0]] @xd.read.s_s() -; CHECK-NEXT: [[TMP17:%.*]] = call [[TMP1]] @xd.read.s_s_0() -; CHECK-NEXT: [[TMP18:%.*]] = call [[TMP2]] @xd.read.s_s_1() +; CHECK-NEXT: [[TMP16:%.*]] = call [[TMP0]] @xd.read__s_s() +; CHECK-NEXT: [[TMP17:%.*]] = call [[TMP1]] @xd.read__s_s_0() +; CHECK-NEXT: [[TMP18:%.*]] = call [[TMP2]] @xd.read__s_s_1() ; CHECK-NEXT: call void (...) @xd.write([[TMP0]] [[TMP16]]) ; CHECK-NEXT: call void (...) @xd.write([[TMP1]] [[TMP17]]) ; CHECK-NEXT: call void (...) @xd.write([[TMP2]] [[TMP18]]) diff --git a/test/example/verifier-basic.ll b/test/example/verifier-basic.ll index e33624f..d5407fc 100644 --- a/test/example/verifier-basic.ll +++ b/test/example/verifier-basic.ll @@ -12,29 +12,29 @@ entry: ; CHECK: failed check for (le ?:$result_width, ?:$source_width) ; CHECK: with $result_width = 64 ; CHECK: with $source_width = 32 - %trunc1 = call i64 (...) @xd.itrunc.i64(i32 %sizeof1) + %trunc1 = call i64 (...) @xd.itrunc__i64(i32 %sizeof1) ; CHECK-LABEL: Verifier error in: %fromfixedvector1 = ; CHECK: unexpected value of $scalar_type: ; CHECK: expected: i32 ; CHECK: actual: i64 - %fromfixedvector1 = call target("xd.vector", i32, 0, 2) (...) @xd.fromfixedvector.txd.vector_i32_0_2t(<2 x i64> poison) + %fromfixedvector1 = call target("xd.vector", i32, 0, 2) (...) @xd.fromfixedvector__txd.vector_i32_0_2t(<2 x i64> poison) ; CHECK-LABEL: Verifier error in: %fromfixedvector2 = ; CHECK: unexpected value of $num_elements: ; CHECK: expected: 2 ; CHECK: actual: 4 - %fromfixedvector2 = call target("xd.vector", i32, 0, 2) (...) @xd.fromfixedvector.txd.vector_i32_0_2t(<4 x i32> poison) + %fromfixedvector2 = call target("xd.vector", i32, 0, 2) (...) @xd.fromfixedvector__txd.vector_i32_0_2t(<4 x i32> poison) ; CHECK-LABEL: Verifier error in: %stream.max1 = ; CHECK: unexpected value of $result: ; CHECK: expected: i16 ; CHECK: actual: <2 x i16> - %stream.max1 = call <2 x i16> (...) @xd.stream.max.v2i16(ptr %p, i64 %trunc1, i16 0) + %stream.max1 = call <2 x i16> (...) @xd.stream.max__v2i16(ptr %p, i64 %trunc1, i16 0) ; CHECK-LABEL: Verifier error in: %stream.min1 = ; CHECK: wrong number of arguments: 2, expected 3 - %stream.min1 = call i8 (...) @xd.stream.min.i8(ptr %p, i64 14) + %stream.min1 = call i8 (...) @xd.stream.min__i8(ptr %p, i64 14) ; CHECK-LABEL: Verifier error in: %fromfixedvector3 = ; CHECK: eq:$rhs (MiddleEndian) does not match any available option @@ -50,14 +50,14 @@ entry: ; CHECK: previously: MiddleEndian ; CHECK: while checking (isReasonableVectorKind ?:$kind) ; CHECK: with $kind = MiddleEndian - %fromfixedvector3 = call target("xd.vector", i32, 2, 2) (...) @xd.fromfixedvector.txd.vector_i32_2_2t(<2 x i32> poison) + %fromfixedvector3 = call target("xd.vector", i32, 2, 2) (...) @xd.fromfixedvector__txd.vector_i32_2_2t(<2 x i32> poison) ret void } declare i32 @xd.sizeof(...) -declare i64 @xd.itrunc.i64(...) -declare target("xd.vector", i32, 0, 2) @xd.fromfixedvector.txd.vector_i32_0_2t(...) -declare target("xd.vector", i32, 2, 2) @xd.fromfixedvector.txd.vector_i32_2_2t(...) -declare <2 x i16> @xd.stream.max.v2i16(...) -declare i8 @xd.stream.min.i8(...) +declare i64 @xd.itrunc__i64(...) +declare target("xd.vector", i32, 0, 2) @xd.fromfixedvector__txd.vector_i32_0_2t(...) +declare target("xd.vector", i32, 2, 2) @xd.fromfixedvector__txd.vector_i32_2_2t(...) +declare <2 x i16> @xd.stream.max__v2i16(...) +declare i8 @xd.stream.min__i8(...) diff --git a/test/example/visitor-basic.ll b/test/example/visitor-basic.ll index c7c1d38..f173888 100644 --- a/test/example/visitor-basic.ll +++ b/test/example/visitor-basic.ll @@ -1,14 +1,14 @@ ; RUN: llvm-dialects-example -visit %s | FileCheck --check-prefixes=DEFAULT %s -; DEFAULT: visiting ReadOp: %v = call i32 @xd.read.i32() +; DEFAULT: visiting ReadOp: %v = call i32 @xd.read__i32() ; DEFAULT-NEXT: visiting UnaryInstruction (pre): %w = load i32, ptr %p ; DEFAULT-NEXT: visiting UnaryInstruction (pre): %q = load i32, ptr %p1 ; DEFAULT-NEXT: visiting BinaryOperator: %v1 = add i32 %v, %w ; DEFAULT-NEXT: visiting umax intrinsic: %v2 = call i32 @llvm.umax.i32(i32 %v1, i32 %q) ; DEFAULT-NEXT: visiting WriteOp: call void (...) @xd.write(i8 %t) -; DEFAULT-NEXT: visiting SetReadOp: %v.0 = call i1 @xd.set.read.i1() -; DEFAULT-NEXT: visiting SetReadOp: %v.1 = call i32 @xd.set.read.i32() -; DEFAULT-NEXT: visiting SetReadOp (set): %v.1 = call i32 @xd.set.read.i32() +; DEFAULT-NEXT: visiting SetReadOp: %v.0 = call i1 @xd.set.read__i1() +; DEFAULT-NEXT: visiting SetReadOp: %v.1 = call i32 @xd.set.read__i32() +; DEFAULT-NEXT: visiting SetReadOp (set): %v.1 = call i32 @xd.set.read__i32() ; DEFAULT-NEXT: visiting UnaryInstruction (pre): %v.2 = trunc i32 %v.1 to i8 ; DEFAULT-NEXT: visiting UnaryInstruction: %v.2 = trunc i32 %v.1 to i8 ; DEFAULT-NEXT: visiting SetWriteOp (set): call void (...) @xd.set.write(i8 %v.2) @@ -22,16 +22,16 @@ define void @test1(ptr %p) { entry: - %v = call i32 @xd.read.i32() + %v = call i32 @xd.read__i32() %w = load i32, ptr %p %p1 = getelementptr i32, ptr %p, i32 1 %q = load i32, ptr %p1 %v1 = add i32 %v, %w %v2 = call i32 @llvm.umax.i32(i32 %v1, i32 %q) - %t = call i8 (...) @xd.itrunc.i8(i32 %v2) + %t = call i8 (...) @xd.itrunc__i8(i32 %v2) call void (...) @xd.write(i8 %t) - %v.0 = call i1 @xd.set.read.i1() - %v.1 = call i32 @xd.set.read.i32() + %v.0 = call i1 @xd.set.read__i1() + %v.1 = call i32 @xd.set.read__i32() %v.2 = trunc i32 %v.1 to i8 call void (...) @xd.set.write(i8 %v.2) call void (...) @xd.write.vararg(i8 %t, i32 %v2, i32 %q) @@ -39,13 +39,13 @@ entry: ret void } -declare i32 @xd.read.i32() -declare i1 @xd.set.read.i1() -declare i32 @xd.set.read.i32() +declare i32 @xd.read__i32() +declare i1 @xd.set.read__i1() +declare i32 @xd.set.read__i32() declare void @xd.write(...) declare void @xd.set.write(...) declare void @xd.write.vararg(...) -declare i8 @xd.itrunc.i8(...) +declare i8 @xd.itrunc__i8(...) declare i32 @llvm.umax.i32(i32, i32) declare i32 @llvm.umin.i32(i32, i32)