[llvm] [LLVM][ConstFolds] Verify a scalar src before attempting scalar->vector bitcast transformation. (PR #111149)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 4 06:22:50 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Paul Walker (paulwalker-arm)

<details>
<summary>Changes</summary>

It was previously safe to assume isa<Constant{Int,FP}> meant a scalar value. This is not true when use-constant-##-for-###-splat are enabled.

---
Full diff: https://github.com/llvm/llvm-project/pull/111149.diff


3 Files Affected:

- (modified) llvm/lib/Analysis/ConstantFolding.cpp (+2-1) 
- (modified) llvm/lib/IR/ConstantFold.cpp (+3-2) 
- (modified) llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll (+45-14) 


``````````diff
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index a7a6de3f3b97b0..a6ef271da11f1a 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -145,7 +145,8 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
 
   // If this is a scalar -> vector cast, convert the input into a <1 x scalar>
   // vector so the code below can handle it uniformly.
-  if (isa<ConstantFP>(C) || isa<ConstantInt>(C)) {
+  if (!isa<VectorType>(C->getType()) &&
+      (isa<ConstantFP>(C) || isa<ConstantInt>(C))) {
     Constant *Ops = C; // don't take the address of C!
     return FoldBitCast(ConstantVector::get(Ops), DestTy, DL);
   }
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index a6f46da313e213..57d9a03c9c22b8 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -81,8 +81,9 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
     // Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts
     // This allows for other simplifications (although some of them
     // can only be handled by Analysis/ConstantFolding.cpp).
-    if (isa<ConstantInt>(V) || isa<ConstantFP>(V))
-      return ConstantExpr::getBitCast(ConstantVector::get(V), DestPTy);
+    if (!isa<VectorType>(SrcTy))
+      if (isa<ConstantInt>(V) || isa<ConstantFP>(V))
+        return ConstantExpr::getBitCast(ConstantVector::get(V), DestPTy);
     return nullptr;
   }
 
diff --git a/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll b/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
index 68ff0859beb2a7..2e75a0d2c98abf 100644
--- a/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
+++ b/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
+; RUN: opt < %s -passes=instsimplify -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC
+; RUN: opt < %s -passes=instsimplify -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat -S | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-f64:32:64-v64:64:64-v128:128:128"
 
 define <2 x i64> @test1() {
@@ -67,17 +68,24 @@ define <4 x i32> @test8(<1 x i64> %y) {
 }
 
 define <4 x i32> @test9(<1 x i64> %y) {
-; CHECK-LABEL: @test9(
-; CHECK-NEXT:    ret <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+; CONSTVEC-LABEL: @test9(
+; CONSTVEC-NEXT:    ret <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+;
+; CONSTSPLAT-LABEL: @test9(
+; CONSTSPLAT-NEXT:    ret <4 x i32> splat (i32 -1)
 ;
   %c = bitcast <2 x i64> <i64 -1, i64 -1> to <4 x i32>
   ret <4 x i32> %c
 }
 
 define <1 x i1> @test10() {
-; CHECK-LABEL: @test10(
-; CHECK-NEXT:    [[RET:%.*]] = icmp eq <1 x i64> <i64 bitcast (<1 x double> <double 0xFFFFFFFFFFFFFFFF> to i64)>, zeroinitializer
-; CHECK-NEXT:    ret <1 x i1> [[RET]]
+; CONSTVEC-LABEL: @test10(
+; CONSTVEC-NEXT:    [[RET:%.*]] = icmp eq <1 x i64> <i64 bitcast (<1 x double> <double 0xFFFFFFFFFFFFFFFF> to i64)>, zeroinitializer
+; CONSTVEC-NEXT:    ret <1 x i1> [[RET]]
+;
+; CONSTSPLAT-LABEL: @test10(
+; CONSTSPLAT-NEXT:    [[RET:%.*]] = icmp eq <1 x i64> splat (i64 -1), zeroinitializer
+; CONSTSPLAT-NEXT:    ret <1 x i1> [[RET]]
 ;
   %ret = icmp eq <1 x i64> <i64 bitcast (<1 x double> <double 0xFFFFFFFFFFFFFFFF> to i64)>, zeroinitializer
   ret <1 x i1> %ret
@@ -85,8 +93,11 @@ define <1 x i1> @test10() {
 
 ; from MultiSource/Benchmarks/Bullet
 define <2 x float> @foo() {
-; CHECK-LABEL: @foo(
-; CHECK-NEXT:    ret <2 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>
+; CONSTVEC-LABEL: @foo(
+; CONSTVEC-NEXT:    ret <2 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>
+;
+; CONSTSPLAT-LABEL: @foo(
+; CONSTSPLAT-NEXT:    ret <2 x float> splat (float 0xFFFFFFFFE0000000)
 ;
   %cast = bitcast i64 -1 to <2 x float>
   ret <2 x float> %cast
@@ -94,16 +105,22 @@ define <2 x float> @foo() {
 
 
 define <2 x double> @foo2() {
-; CHECK-LABEL: @foo2(
-; CHECK-NEXT:    ret <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
+; CONSTVEC-LABEL: @foo2(
+; CONSTVEC-NEXT:    ret <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
+;
+; CONSTSPLAT-LABEL: @foo2(
+; CONSTSPLAT-NEXT:    ret <2 x double> splat (double 0xFFFFFFFFFFFFFFFF)
 ;
   %cast = bitcast i128 -1 to <2 x double>
   ret <2 x double> %cast
 }
 
 define <1 x float> @foo3() {
-; CHECK-LABEL: @foo3(
-; CHECK-NEXT:    ret <1 x float> <float 0xFFFFFFFFE0000000>
+; CONSTVEC-LABEL: @foo3(
+; CONSTVEC-NEXT:    ret <1 x float> <float 0xFFFFFFFFE0000000>
+;
+; CONSTSPLAT-LABEL: @foo3(
+; CONSTSPLAT-NEXT:    ret <1 x float> splat (float 0xFFFFFFFFE0000000)
 ;
   %cast = bitcast i32 -1 to <1 x float>
   ret <1 x float> %cast
@@ -126,8 +143,11 @@ define double @foo5() {
 }
 
 define <2 x double> @foo6() {
-; CHECK-LABEL: @foo6(
-; CHECK-NEXT:    ret <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
+; CONSTVEC-LABEL: @foo6(
+; CONSTVEC-NEXT:    ret <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
+;
+; CONSTSPLAT-LABEL: @foo6(
+; CONSTSPLAT-NEXT:    ret <2 x double> splat (double 0xFFFFFFFFFFFFFFFF)
 ;
   %cast = bitcast <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1> to <2 x double>
   ret <2 x double> %cast
@@ -276,3 +296,14 @@ define <16 x i8> @bitcast_constexpr_16i8_8i16_u256uuu256uu() {
   %cast = bitcast <8 x i16><i16 undef, i16 256, i16 undef, i16 undef, i16 undef, i16 256, i16 undef, i16 undef> to <16 x i8>
   ret <16 x i8> %cast
 }
+
+define <1 x i32> @bitcast_constexpr_scalar_fp_to_vector_int() {
+; CONSTVEC-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int(
+; CONSTVEC-NEXT:    ret <1 x i32> <i32 1065353216>
+;
+; CONSTSPLAT-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int(
+; CONSTSPLAT-NEXT:    ret <1 x i32> bitcast (<1 x float> splat (float 1.000000e+00) to <1 x i32>)
+;
+  %res = bitcast float 1.0 to <1 x i32>
+  ret <1 x i32> %res
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/111149


More information about the llvm-commits mailing list