[llvm] [Transforms] Resolve FIXME: Pick the smallest legal type that fits (PR #79158)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 26 09:02:28 PST 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/79158
>From 1b1021d54764f314fdb086ce93da260013d80013 Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Tue, 23 Jan 2024 10:15:46 -0500
Subject: [PATCH] [Transforms] Resolve FIXME: Pick the smallest legal type that
fits
Pick the type based on the smallest bit-width possible, using DataLayout.
---
.../llvm/Transforms/Scalar/Float2Int.h | 2 +-
llvm/lib/Transforms/Scalar/Float2Int.cpp | 27 ++++++---
llvm/test/Transforms/Float2Int/basic.ll | 55 +++++++++----------
3 files changed, 48 insertions(+), 36 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Scalar/Float2Int.h b/llvm/include/llvm/Transforms/Scalar/Float2Int.h
index 83be329bed60bab..d017c6d75dc1b85 100644
--- a/llvm/include/llvm/Transforms/Scalar/Float2Int.h
+++ b/llvm/include/llvm/Transforms/Scalar/Float2Int.h
@@ -44,7 +44,7 @@ class Float2IntPass : public PassInfoMixin<Float2IntPass> {
std::optional<ConstantRange> calcRange(Instruction *I);
void walkBackwards();
void walkForwards();
- bool validateAndTransform();
+ bool validateAndTransform(DataLayout DL);
Value *convert(Instruction *I, Type *ToTy);
void cleanup();
diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp
index ccca8bcc1a56ac7..cd3fa3087aecc47 100644
--- a/llvm/lib/Transforms/Scalar/Float2Int.cpp
+++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp
@@ -311,7 +311,7 @@ void Float2IntPass::walkForwards() {
}
// If there is a valid transform to be done, do it.
-bool Float2IntPass::validateAndTransform() {
+bool Float2IntPass::validateAndTransform(DataLayout DL) {
bool MadeChange = false;
// Iterate over every disjoint partition of the def-use graph.
@@ -382,12 +382,22 @@ bool Float2IntPass::validateAndTransform() {
continue;
}
- // OK, R is known to be representable. Now pick a type for it.
- // FIXME: Pick the smallest legal type that will fit.
- Type *Ty = (MinBW > 32) ? Type::getInt64Ty(*Ctx) : Type::getInt32Ty(*Ctx);
+ // OK, R is known to be representable.
+ // Pick the smallest legal type that will fit.
+ Type *Ty = nullptr;
+ for (unsigned BW = 8; BW <= 64; BW *= 2) {
+ if (MinBW <= BW && DL.isLegalInteger(BW)) {
+ Ty = IntegerType::get(*Ctx, BW);
+ break;
+ }
+ }
- for (auto MI = ECs.member_begin(It), ME = ECs.member_end();
- MI != ME; ++MI)
+ if (!Ty) {
+ // Should not happen, but just in case:
+ Ty = (MinBW > 32) ? Type::getInt64Ty(*Ctx) : Type::getInt32Ty(*Ctx);
+ }
+
+ for (auto MI = ECs.member_begin(It), ME = ECs.member_end(); MI != ME; ++MI)
convert(*MI, Ty);
MadeChange = true;
}
@@ -491,7 +501,10 @@ bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) {
walkBackwards();
walkForwards();
- bool Modified = validateAndTransform();
+
+ const DataLayout &DL = F.getParent()->getDataLayout();
+
+ bool Modified = validateAndTransform(DL);
if (Modified)
cleanup();
return Modified;
diff --git a/llvm/test/Transforms/Float2Int/basic.ll b/llvm/test/Transforms/Float2Int/basic.ll
index 2854a83179b7eb6..aa9ef36e4caaab1 100644
--- a/llvm/test/Transforms/Float2Int/basic.ll
+++ b/llvm/test/Transforms/Float2Int/basic.ll
@@ -7,10 +7,9 @@
define i16 @simple1(i8 %a) {
; CHECK-LABEL: @simple1(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32
-; CHECK-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16
-; CHECK-NEXT: ret i16 [[TMP2]]
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16
+; CHECK-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 1
+; CHECK-NEXT: ret i16 [[T21]]
;
%t1 = uitofp i8 %a to float
%t2 = fadd float %t1, 1.0
@@ -20,9 +19,9 @@ define i16 @simple1(i8 %a) {
define i8 @simple2(i8 %a) {
; CHECK-LABEL: @simple2(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32
-; CHECK-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1
-; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i8
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16
+; CHECK-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = trunc i16 [[T21]] to i8
; CHECK-NEXT: ret i8 [[TMP2]]
;
%t1 = uitofp i8 %a to float
@@ -33,9 +32,10 @@ define i8 @simple2(i8 %a) {
define i32 @simple3(i8 %a) {
; CHECK-LABEL: @simple3(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32
-; CHECK-NEXT: [[T21:%.*]] = sub i32 [[TMP1]], 1
-; CHECK-NEXT: ret i32 [[T21]]
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16
+; CHECK-NEXT: [[T21:%.*]] = sub i16 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[T21]] to i32
+; CHECK-NEXT: ret i32 [[TMP2]]
;
%t1 = uitofp i8 %a to float
%t2 = fsub float %t1, 1.0
@@ -45,9 +45,9 @@ define i32 @simple3(i8 %a) {
define i1 @cmp(i8 %a, i8 %b) {
; CHECK-LABEL: @cmp(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32
-; CHECK-NEXT: [[T31:%.*]] = icmp slt i32 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16
+; CHECK-NEXT: [[T31:%.*]] = icmp slt i16 [[TMP1]], [[TMP2]]
; CHECK-NEXT: ret i1 [[T31]]
;
%t1 = uitofp i8 %a to float
@@ -106,13 +106,14 @@ define i32 @simple6(i8 %a, i8 %b) {
define i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) {
; CHECK-LABEL: @multi1(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i16
; CHECK-NEXT: [[FC:%.*]] = uitofp i8 [[C:%.*]] to float
-; CHECK-NEXT: [[X1:%.*]] = add i32 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: [[X1:%.*]] = add i16 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = zext i16 [[X1]] to i32
; CHECK-NEXT: [[Z:%.*]] = fadd float [[FC]], [[D:%.*]]
; CHECK-NEXT: [[W:%.*]] = fptoui float [[Z]] to i32
-; CHECK-NEXT: [[R:%.*]] = add i32 [[X1]], [[W]]
+; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP3]], [[W]]
; CHECK-NEXT: ret i32 [[R]]
;
%fa = uitofp i8 %a to float
@@ -128,10 +129,9 @@ define i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) {
define i16 @simple_negzero(i8 %a) {
; CHECK-LABEL: @simple_negzero(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32
-; CHECK-NEXT: [[T21:%.*]] = add i32 [[TMP1]], 0
-; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16
-; CHECK-NEXT: ret i16 [[TMP2]]
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16
+; CHECK-NEXT: [[T21:%.*]] = add i16 [[TMP1]], 0
+; CHECK-NEXT: ret i16 [[T21]]
;
%t1 = uitofp i8 %a to float
%t2 = fadd fast float %t1, -0.0
@@ -141,9 +141,9 @@ define i16 @simple_negzero(i8 %a) {
define i32 @simple_negative(i8 %call) {
; CHECK-LABEL: @simple_negative(
-; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i32
-; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[TMP1]], -3
-; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[MUL1]] to i8
+; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[CALL:%.*]] to i16
+; CHECK-NEXT: [[MUL1:%.*]] = mul i16 [[TMP1]], -3
+; CHECK-NEXT: [[TMP2:%.*]] = trunc i16 [[MUL1]] to i8
; CHECK-NEXT: [[CONV3:%.*]] = sext i8 [[TMP2]] to i32
; CHECK-NEXT: ret i32 [[CONV3]]
;
@@ -156,10 +156,9 @@ define i32 @simple_negative(i8 %call) {
define i16 @simple_fneg(i8 %a) {
; CHECK-LABEL: @simple_fneg(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32
-; CHECK-NEXT: [[T21:%.*]] = sub i32 0, [[TMP1]]
-; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[T21]] to i16
-; CHECK-NEXT: ret i16 [[TMP2]]
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i16
+; CHECK-NEXT: [[T21:%.*]] = sub i16 0, [[TMP1]]
+; CHECK-NEXT: ret i16 [[T21]]
;
%t1 = uitofp i8 %a to float
%t2 = fneg fast float %t1
More information about the llvm-commits
mailing list