Skip to content

Commit af641ff

Browse files
[LLVM][IR] Refactor ConstantFold:FoldBitCast to fully support vector ConstantInt/FP. (#116787)
This fixes the code quality issue reported in #111149.
1 parent a1153cd commit af641ff

File tree

3 files changed

+31
-36
lines changed

3 files changed

+31
-36
lines changed

llvm/lib/IR/ConstantFold.cpp

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -71,50 +71,51 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
7171
if (SrcTy == DestTy)
7272
return V; // no-op cast
7373

74-
// Handle casts from one vector constant to another. We know that the src
75-
// and dest type have the same size (otherwise its an illegal cast).
76-
if (VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
77-
if (V->isAllOnesValue())
78-
return Constant::getAllOnesValue(DestTy);
74+
if (V->isAllOnesValue())
75+
return Constant::getAllOnesValue(DestTy);
7976

77+
// Handle ConstantInt -> ConstantFP
78+
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
8079
// Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts
8180
// This allows for other simplifications (although some of them
8281
// can only be handled by Analysis/ConstantFolding.cpp).
83-
if (!isa<VectorType>(SrcTy))
84-
if (isa<ConstantInt>(V) || isa<ConstantFP>(V))
85-
return ConstantExpr::getBitCast(ConstantVector::get(V), DestPTy);
86-
return nullptr;
87-
}
82+
if (isa<VectorType>(DestTy) && !isa<VectorType>(SrcTy))
83+
return ConstantExpr::getBitCast(ConstantVector::get(V), DestTy);
8884

89-
// Handle integral constant input.
90-
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
85+
// Make sure dest type is compatible with the folded fp constant.
9186
// See note below regarding the PPC_FP128 restriction.
92-
if (DestTy->isFloatingPointTy() && !DestTy->isPPC_FP128Ty())
93-
return ConstantFP::get(DestTy->getContext(),
94-
APFloat(DestTy->getFltSemantics(),
95-
CI->getValue()));
87+
if (!DestTy->isFPOrFPVectorTy() || DestTy->isPPC_FP128Ty() ||
88+
DestTy->getScalarSizeInBits() != SrcTy->getScalarSizeInBits())
89+
return nullptr;
9690

97-
// Otherwise, can't fold this (vector?)
98-
return nullptr;
91+
return ConstantFP::get(
92+
DestTy,
93+
APFloat(DestTy->getScalarType()->getFltSemantics(), CI->getValue()));
9994
}
10095

101-
// Handle ConstantFP input: FP -> Integral.
96+
// Handle ConstantFP -> ConstantInt
10297
if (ConstantFP *FP = dyn_cast<ConstantFP>(V)) {
98+
// Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts
99+
// This allows for other simplifications (although some of them
100+
// can only be handled by Analysis/ConstantFolding.cpp).
101+
if (isa<VectorType>(DestTy) && !isa<VectorType>(SrcTy))
102+
return ConstantExpr::getBitCast(ConstantVector::get(V), DestTy);
103+
103104
// PPC_FP128 is really the sum of two consecutive doubles, where the first
104105
// double is always stored first in memory, regardless of the target
105106
// endianness. The memory layout of i128, however, depends on the target
106107
// endianness, and so we can't fold this without target endianness
107108
// information. This should instead be handled by
108109
// Analysis/ConstantFolding.cpp
109-
if (FP->getType()->isPPC_FP128Ty())
110+
if (SrcTy->isPPC_FP128Ty())
110111
return nullptr;
111112

112113
// Make sure dest type is compatible with the folded integer constant.
113-
if (!DestTy->isIntegerTy())
114+
if (!DestTy->isIntOrIntVectorTy() ||
115+
DestTy->getScalarSizeInBits() != SrcTy->getScalarSizeInBits())
114116
return nullptr;
115117

116-
return ConstantInt::get(FP->getContext(),
117-
FP->getValueAPF().bitcastToAPInt());
118+
return ConstantInt::get(DestTy, FP->getValueAPF().bitcastToAPInt());
118119
}
119120

120121
return nullptr;

llvm/test/Transforms/InstCombine/bitcast.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
; RUN: opt < %s -passes=instcombine -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat -S | FileCheck %s
34

45
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
56
target triple = "x86_64-apple-darwin10.0.0"

llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC
3-
; 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
2+
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3+
; RUN: opt < %s -passes=instsimplify -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat -S | FileCheck %s
44
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-f64:32:64-v64:64:64-v128:128:128"
55

66
define <2 x i64> @test1() {
@@ -76,12 +76,8 @@ define <4 x i32> @test9(<1 x i64> %y) {
7676
}
7777

7878
define <1 x i1> @test10() {
79-
; CONSTVEC-LABEL: @test10(
80-
; CONSTVEC-NEXT: [[RET:%.*]] = icmp eq <1 x i64> <i64 bitcast (<1 x double> splat (double 0xFFFFFFFFFFFFFFFF) to i64)>, zeroinitializer
81-
; CONSTVEC-NEXT: ret <1 x i1> [[RET]]
82-
;
83-
; CONSTSPLAT-LABEL: @test10(
84-
; CONSTSPLAT-NEXT: ret <1 x i1> zeroinitializer
79+
; CHECK-LABEL: @test10(
80+
; CHECK-NEXT: ret <1 x i1> zeroinitializer
8581
;
8682
%ret = icmp eq <1 x i64> <i64 bitcast (<1 x double> <double 0xFFFFFFFFFFFFFFFF> to i64)>, zeroinitializer
8783
ret <1 x i1> %ret
@@ -282,11 +278,8 @@ define <16 x i8> @bitcast_constexpr_16i8_8i16_u256uuu256uu() {
282278
}
283279

284280
define <1 x i32> @bitcast_constexpr_scalar_fp_to_vector_int() {
285-
; CONSTVEC-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int(
286-
; CONSTVEC-NEXT: ret <1 x i32> splat (i32 1065353216)
287-
;
288-
; CONSTSPLAT-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int(
289-
; CONSTSPLAT-NEXT: ret <1 x i32> bitcast (<1 x float> splat (float 1.000000e+00) to <1 x i32>)
281+
; CHECK-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int(
282+
; CHECK-NEXT: ret <1 x i32> splat (i32 1065353216)
290283
;
291284
%res = bitcast float 1.0 to <1 x i32>
292285
ret <1 x i32> %res

0 commit comments

Comments
 (0)