[llvm] [LLVM][IR] Add support for vector ConstantInt/FP to ConstandFolding:FoldBitCast. (PR #117163)

Paul Walker via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 4 09:41:22 PST 2024


https://github.com/paulwalker-arm updated https://github.com/llvm/llvm-project/pull/117163

>From e0858b16b48e0392217d4128fde1c119f3b71c60 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Tue, 19 Nov 2024 16:23:28 +0000
Subject: [PATCH 1/2] [LLVM][IR] Add support for vector ConstantInt/FP to
 ConstandFolding:FoldBitCast.

---
 llvm/lib/Analysis/ConstantFolding.cpp    | 8 +++++++-
 llvm/test/Transforms/InstCombine/cast.ll | 2 ++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 1971c28fc4c4de..f66078e0aa545d 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -151,8 +151,14 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
     return FoldBitCast(ConstantVector::get(Ops), DestTy, DL);
   }
 
+  // Some of what follows may extend to cover scalable vectors but the current
+  // implementation is fixed length specific.
+  if (!isa<FixedVectorType>(C->getType()))
+    return ConstantExpr::getBitCast(C, DestTy);
+
   // If this is a bitcast from constant vector -> vector, fold it.
-  if (!isa<ConstantDataVector>(C) && !isa<ConstantVector>(C))
+  if (!isa<ConstantDataVector>(C) && !isa<ConstantVector>(C) &&
+      !isa<ConstantInt>(C) && !isa<ConstantFP>(C))
     return ConstantExpr::getBitCast(C, DestTy);
 
   // If the element types match, IR can fold it.
diff --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll
index ca748a9483e9b2..0f957e22ad17bc 100644
--- a/llvm/test/Transforms/InstCombine/cast.ll
+++ b/llvm/test/Transforms/InstCombine/cast.ll
@@ -2,6 +2,8 @@
 ; Tests to make sure elimination of casts is working correctly
 ; RUN: opt < %s -passes=instcombine -S -data-layout="E-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" | FileCheck %s --check-prefixes=ALL,BE
 ; RUN: opt < %s -passes=instcombine -S -data-layout="e-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" | FileCheck %s --check-prefixes=ALL,LE
+; RUN: opt < %s -passes=instcombine -S -data-layout="E-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ALL,BE
+; RUN: opt < %s -passes=instcombine -S -data-layout="e-p:64:64:64-p1:32:32:32-p2:64:64:64-p3:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ALL,LE
 
 declare void @use_i32(i32)
 declare void @use_v2i32(<2 x i32>)

>From 2f5cc5b5cf7a847dee1e54cb95d9a48363ce885e Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Wed, 4 Dec 2024 17:34:49 +0000
Subject: [PATCH 2/2] Prevent bogus return when constant fold does not happen.

Rather then return the correct result I believe we do not hit this
issue because the input has been restricted to constants that we
know can be constant folded and so I've replace the broken code with
an assert, which is in keeping with the other code in this area that
requires constant folding to work.
---
 llvm/lib/Analysis/ConstantFolding.cpp                    | 8 ++++----
 llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll | 8 ++++++++
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index f66078e0aa545d..c65a41769d372d 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -200,10 +200,10 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
         IntegerType::get(C->getContext(), FPWidth), NumSrcElt);
     // Ask IR to do the conversion now that #elts line up.
     C = ConstantExpr::getBitCast(C, SrcIVTy);
-    // If IR wasn't able to fold it, bail out.
-    if (!isa<ConstantVector>(C) &&  // FIXME: Remove ConstantVector.
-        !isa<ConstantDataVector>(C))
-      return C;
+    assert((isa<ConstantVector>(C) || // FIXME: Remove ConstantVector.
+            isa<ConstantDataVector>(C) || isa<ConstantInt>(C) ||
+            isa<ConstantFP>(C)) &&
+           "Constant folding cannot fail for plain fp->int bitcast!");
   }
 
   // Now we know that the input and output vectors are both integer vectors
diff --git a/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll b/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
index a3ad5f01391422..d2656e291547cf 100644
--- a/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
+++ b/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
@@ -284,3 +284,11 @@ define <1 x i32> @bitcast_constexpr_scalar_fp_to_vector_int() {
   %res = bitcast float 1.0 to <1 x i32>
   ret <1 x i32> %res
 }
+
+define <2 x i64> @bitcast_constexpr_4f32_2i64_1111() {
+; CHECK-LABEL: @bitcast_constexpr_4f32_2i64_1111(
+; CHECK-NEXT:    ret <2 x i64> splat (i64 4575657222473777152)
+;
+  %res = bitcast <4 x float> splat (float 1.0) to <2 x i64>
+  ret <2 x i64> %res
+}



More information about the llvm-commits mailing list