-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[MLIR] Zero-extend unsigned and 1-bit values when translating IntegerAttr #169751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…VM IR This updates the LLVM IR ConstantInt creation from mlir::IntegerAttr so that unsigned integers and 1-bit integers are zero-extended rather than sign-extended.
|
@llvm/pr-subscribers-mlir-llvm Author: Andy Kaylor (andykaylor) ChangesThis updates the LLVM IR ConstantInt creation from mlir::IntegerAttr so that unsigned integers and 1-bit integers are zero-extended rather than sign-extended. Full diff: https://github.com/llvm/llvm-project/pull/169751.diff 3 Files Affected:
diff --git a/clang/test/CIR/CodeGen/globals.cpp b/clang/test/CIR/CodeGen/globals.cpp
index a3e16139a41a9..848cac8a46299 100644
--- a/clang/test/CIR/CodeGen/globals.cpp
+++ b/clang/test/CIR/CodeGen/globals.cpp
@@ -35,3 +35,9 @@ int *constArrAddr = &arr[2][1];
// LLVM: @constArrAddr = global ptr getelementptr inbounds nuw (i8, ptr @arr, i64 132), align 8
// OGCG: @constArrAddr = global ptr getelementptr (i8, ptr @arr, i64 132), align 8
+
+bool bool_global = true;
+
+// CIR: cir.global external @bool_global = #true {alignment = 1 : i64}
+// LLVM: @bool_global = global i8 1, align 1
+// OGCG: @bool_global = global i8 1, align 1
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 412a5f76d5753..0d36dcef56123 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -588,10 +588,17 @@ llvm::Constant *mlir::LLVM::detail::getLLVMConstant(
}
// For integer types, we allow a mismatch in sizes as the index type in
// MLIR might have a different size than the index type in the LLVM module.
- if (auto intAttr = dyn_cast<IntegerAttr>(attr))
- return llvm::ConstantInt::get(
- llvmType,
- intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth()));
+ if (auto intAttr = dyn_cast<IntegerAttr>(attr)) {
+ // If the attribute is an unsigned integer or a 1-bit integer, zero-extend
+ // the value to the bit width of the LLVM type. Otherwise, sign-extend.
+ auto intTy = mlir::dyn_cast<IntegerType>(intAttr.getType());
+ APInt value;
+ if (intTy && (intTy.isUnsigned() || intTy.getWidth() == 1))
+ value = intAttr.getValue().zextOrTrunc(llvmType->getIntegerBitWidth());
+ else
+ value = intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth());
+ return llvm::ConstantInt::get(llvmType, value);
+ }
if (auto floatAttr = dyn_cast<FloatAttr>(attr)) {
const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
// Special case for 8-bit floats, which are represented by integers due to
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index d1ed1b4bfa064..819a514bc8b7e 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -78,6 +78,9 @@ llvm.mlir.global internal @f8E8M0FNU_global_as_i8(1.0 : f8E8M0FNU) : i8
// CHECK: @bf16_global_as_i16 = internal global i16 16320
llvm.mlir.global internal @bf16_global_as_i16(1.5 : bf16) : i16
+// CHECK: @bool_global_as_i8 = internal global i8 1
+llvm.mlir.global internal @bool_global_as_i8(true) : i8
+
// CHECK: @explicit_undef = global i32 undef
llvm.mlir.global external @explicit_undef() : i32 {
%0 = llvm.mlir.undef : i32
|
|
@llvm/pr-subscribers-mlir Author: Andy Kaylor (andykaylor) ChangesThis updates the LLVM IR ConstantInt creation from mlir::IntegerAttr so that unsigned integers and 1-bit integers are zero-extended rather than sign-extended. Full diff: https://github.com/llvm/llvm-project/pull/169751.diff 3 Files Affected:
diff --git a/clang/test/CIR/CodeGen/globals.cpp b/clang/test/CIR/CodeGen/globals.cpp
index a3e16139a41a9..848cac8a46299 100644
--- a/clang/test/CIR/CodeGen/globals.cpp
+++ b/clang/test/CIR/CodeGen/globals.cpp
@@ -35,3 +35,9 @@ int *constArrAddr = &arr[2][1];
// LLVM: @constArrAddr = global ptr getelementptr inbounds nuw (i8, ptr @arr, i64 132), align 8
// OGCG: @constArrAddr = global ptr getelementptr (i8, ptr @arr, i64 132), align 8
+
+bool bool_global = true;
+
+// CIR: cir.global external @bool_global = #true {alignment = 1 : i64}
+// LLVM: @bool_global = global i8 1, align 1
+// OGCG: @bool_global = global i8 1, align 1
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 412a5f76d5753..0d36dcef56123 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -588,10 +588,17 @@ llvm::Constant *mlir::LLVM::detail::getLLVMConstant(
}
// For integer types, we allow a mismatch in sizes as the index type in
// MLIR might have a different size than the index type in the LLVM module.
- if (auto intAttr = dyn_cast<IntegerAttr>(attr))
- return llvm::ConstantInt::get(
- llvmType,
- intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth()));
+ if (auto intAttr = dyn_cast<IntegerAttr>(attr)) {
+ // If the attribute is an unsigned integer or a 1-bit integer, zero-extend
+ // the value to the bit width of the LLVM type. Otherwise, sign-extend.
+ auto intTy = mlir::dyn_cast<IntegerType>(intAttr.getType());
+ APInt value;
+ if (intTy && (intTy.isUnsigned() || intTy.getWidth() == 1))
+ value = intAttr.getValue().zextOrTrunc(llvmType->getIntegerBitWidth());
+ else
+ value = intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth());
+ return llvm::ConstantInt::get(llvmType, value);
+ }
if (auto floatAttr = dyn_cast<FloatAttr>(attr)) {
const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
// Special case for 8-bit floats, which are represented by integers due to
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index d1ed1b4bfa064..819a514bc8b7e 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -78,6 +78,9 @@ llvm.mlir.global internal @f8E8M0FNU_global_as_i8(1.0 : f8E8M0FNU) : i8
// CHECK: @bf16_global_as_i16 = internal global i16 16320
llvm.mlir.global internal @bf16_global_as_i16(1.5 : bf16) : i16
+// CHECK: @bool_global_as_i8 = internal global i8 1
+llvm.mlir.global internal @bool_global_as_i8(true) : i8
+
// CHECK: @explicit_undef = global i32 undef
llvm.mlir.global external @explicit_undef() : i32 {
%0 = llvm.mlir.undef : i32
|
|
@llvm/pr-subscribers-clangir Author: Andy Kaylor (andykaylor) ChangesThis updates the LLVM IR ConstantInt creation from mlir::IntegerAttr so that unsigned integers and 1-bit integers are zero-extended rather than sign-extended. Full diff: https://github.com/llvm/llvm-project/pull/169751.diff 3 Files Affected:
diff --git a/clang/test/CIR/CodeGen/globals.cpp b/clang/test/CIR/CodeGen/globals.cpp
index a3e16139a41a9..848cac8a46299 100644
--- a/clang/test/CIR/CodeGen/globals.cpp
+++ b/clang/test/CIR/CodeGen/globals.cpp
@@ -35,3 +35,9 @@ int *constArrAddr = &arr[2][1];
// LLVM: @constArrAddr = global ptr getelementptr inbounds nuw (i8, ptr @arr, i64 132), align 8
// OGCG: @constArrAddr = global ptr getelementptr (i8, ptr @arr, i64 132), align 8
+
+bool bool_global = true;
+
+// CIR: cir.global external @bool_global = #true {alignment = 1 : i64}
+// LLVM: @bool_global = global i8 1, align 1
+// OGCG: @bool_global = global i8 1, align 1
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 412a5f76d5753..0d36dcef56123 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -588,10 +588,17 @@ llvm::Constant *mlir::LLVM::detail::getLLVMConstant(
}
// For integer types, we allow a mismatch in sizes as the index type in
// MLIR might have a different size than the index type in the LLVM module.
- if (auto intAttr = dyn_cast<IntegerAttr>(attr))
- return llvm::ConstantInt::get(
- llvmType,
- intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth()));
+ if (auto intAttr = dyn_cast<IntegerAttr>(attr)) {
+ // If the attribute is an unsigned integer or a 1-bit integer, zero-extend
+ // the value to the bit width of the LLVM type. Otherwise, sign-extend.
+ auto intTy = mlir::dyn_cast<IntegerType>(intAttr.getType());
+ APInt value;
+ if (intTy && (intTy.isUnsigned() || intTy.getWidth() == 1))
+ value = intAttr.getValue().zextOrTrunc(llvmType->getIntegerBitWidth());
+ else
+ value = intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth());
+ return llvm::ConstantInt::get(llvmType, value);
+ }
if (auto floatAttr = dyn_cast<FloatAttr>(attr)) {
const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
// Special case for 8-bit floats, which are represented by integers due to
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index d1ed1b4bfa064..819a514bc8b7e 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -78,6 +78,9 @@ llvm.mlir.global internal @f8E8M0FNU_global_as_i8(1.0 : f8E8M0FNU) : i8
// CHECK: @bf16_global_as_i16 = internal global i16 16320
llvm.mlir.global internal @bf16_global_as_i16(1.5 : bf16) : i16
+// CHECK: @bool_global_as_i8 = internal global i8 1
+llvm.mlir.global internal @bool_global_as_i8(true) : i8
+
// CHECK: @explicit_undef = global i32 undef
llvm.mlir.global external @explicit_undef() : i32 {
%0 = llvm.mlir.undef : i32
|
| // the value to the bit width of the LLVM type. Otherwise, sign-extend. | ||
| auto intTy = mlir::dyn_cast<IntegerType>(intAttr.getType()); | ||
| APInt value; | ||
| if (intTy && (intTy.isUnsigned() || intTy.getWidth() == 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't entirely sure what the condition should be here. Sign-extending a signless value feels a bit arbitrary, but I think that's the behavior that's expected for index types, so I guess it makes sense for signless integers also. My motivation in making this change is that in global initializers true was being translated to i8 -1 whereas in local initializers it was i8 1.
This updates the LLVM IR ConstantInt creation from mlir::IntegerAttr so that unsigned integers and 1-bit integers are zero-extended rather than sign-extended.