Skip to content

Commit 87cdc83

Browse files
[LLVM][ConstFolds] Verify a scalar src before attempting scalar->vector bitcast transformation. (#111149)
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.
1 parent e06e493 commit 87cdc83

File tree

3 files changed

+50
-17
lines changed

3 files changed

+50
-17
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
145145

146146
// If this is a scalar -> vector cast, convert the input into a <1 x scalar>
147147
// vector so the code below can handle it uniformly.
148-
if (isa<ConstantFP>(C) || isa<ConstantInt>(C)) {
148+
if (!isa<VectorType>(C->getType()) &&
149+
(isa<ConstantFP>(C) || isa<ConstantInt>(C))) {
149150
Constant *Ops = C; // don't take the address of C!
150151
return FoldBitCast(ConstantVector::get(Ops), DestTy, DL);
151152
}

llvm/lib/IR/ConstantFold.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
8181
// Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts
8282
// This allows for other simplifications (although some of them
8383
// can only be handled by Analysis/ConstantFolding.cpp).
84-
if (isa<ConstantInt>(V) || isa<ConstantFP>(V))
85-
return ConstantExpr::getBitCast(ConstantVector::get(V), DestPTy);
84+
if (!isa<VectorType>(SrcTy))
85+
if (isa<ConstantInt>(V) || isa<ConstantFP>(V))
86+
return ConstantExpr::getBitCast(ConstantVector::get(V), DestPTy);
8687
return nullptr;
8788
}
8889

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

Lines changed: 45 additions & 14 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
2-
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
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
34
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-f64:32:64-v64:64:64-v128:128:128"
45

56
define <2 x i64> @test1() {
@@ -67,43 +68,59 @@ define <4 x i32> @test8(<1 x i64> %y) {
6768
}
6869

6970
define <4 x i32> @test9(<1 x i64> %y) {
70-
; CHECK-LABEL: @test9(
71-
; CHECK-NEXT: ret <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
71+
; CONSTVEC-LABEL: @test9(
72+
; CONSTVEC-NEXT: ret <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
73+
;
74+
; CONSTSPLAT-LABEL: @test9(
75+
; CONSTSPLAT-NEXT: ret <4 x i32> splat (i32 -1)
7276
;
7377
%c = bitcast <2 x i64> <i64 -1, i64 -1> to <4 x i32>
7478
ret <4 x i32> %c
7579
}
7680

7781
define <1 x i1> @test10() {
78-
; CHECK-LABEL: @test10(
79-
; CHECK-NEXT: [[RET:%.*]] = icmp eq <1 x i64> <i64 bitcast (<1 x double> <double 0xFFFFFFFFFFFFFFFF> to i64)>, zeroinitializer
80-
; CHECK-NEXT: ret <1 x i1> [[RET]]
82+
; CONSTVEC-LABEL: @test10(
83+
; CONSTVEC-NEXT: [[RET:%.*]] = icmp eq <1 x i64> <i64 bitcast (<1 x double> <double 0xFFFFFFFFFFFFFFFF> to i64)>, zeroinitializer
84+
; CONSTVEC-NEXT: ret <1 x i1> [[RET]]
85+
;
86+
; CONSTSPLAT-LABEL: @test10(
87+
; CONSTSPLAT-NEXT: [[RET:%.*]] = icmp eq <1 x i64> splat (i64 -1), zeroinitializer
88+
; CONSTSPLAT-NEXT: ret <1 x i1> [[RET]]
8189
;
8290
%ret = icmp eq <1 x i64> <i64 bitcast (<1 x double> <double 0xFFFFFFFFFFFFFFFF> to i64)>, zeroinitializer
8391
ret <1 x i1> %ret
8492
}
8593

8694
; from MultiSource/Benchmarks/Bullet
8795
define <2 x float> @foo() {
88-
; CHECK-LABEL: @foo(
89-
; CHECK-NEXT: ret <2 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>
96+
; CONSTVEC-LABEL: @foo(
97+
; CONSTVEC-NEXT: ret <2 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>
98+
;
99+
; CONSTSPLAT-LABEL: @foo(
100+
; CONSTSPLAT-NEXT: ret <2 x float> splat (float 0xFFFFFFFFE0000000)
90101
;
91102
%cast = bitcast i64 -1 to <2 x float>
92103
ret <2 x float> %cast
93104
}
94105

95106

96107
define <2 x double> @foo2() {
97-
; CHECK-LABEL: @foo2(
98-
; CHECK-NEXT: ret <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
108+
; CONSTVEC-LABEL: @foo2(
109+
; CONSTVEC-NEXT: ret <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
110+
;
111+
; CONSTSPLAT-LABEL: @foo2(
112+
; CONSTSPLAT-NEXT: ret <2 x double> splat (double 0xFFFFFFFFFFFFFFFF)
99113
;
100114
%cast = bitcast i128 -1 to <2 x double>
101115
ret <2 x double> %cast
102116
}
103117

104118
define <1 x float> @foo3() {
105-
; CHECK-LABEL: @foo3(
106-
; CHECK-NEXT: ret <1 x float> <float 0xFFFFFFFFE0000000>
119+
; CONSTVEC-LABEL: @foo3(
120+
; CONSTVEC-NEXT: ret <1 x float> <float 0xFFFFFFFFE0000000>
121+
;
122+
; CONSTSPLAT-LABEL: @foo3(
123+
; CONSTSPLAT-NEXT: ret <1 x float> splat (float 0xFFFFFFFFE0000000)
107124
;
108125
%cast = bitcast i32 -1 to <1 x float>
109126
ret <1 x float> %cast
@@ -126,8 +143,11 @@ define double @foo5() {
126143
}
127144

128145
define <2 x double> @foo6() {
129-
; CHECK-LABEL: @foo6(
130-
; CHECK-NEXT: ret <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
146+
; CONSTVEC-LABEL: @foo6(
147+
; CONSTVEC-NEXT: ret <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>
148+
;
149+
; CONSTSPLAT-LABEL: @foo6(
150+
; CONSTSPLAT-NEXT: ret <2 x double> splat (double 0xFFFFFFFFFFFFFFFF)
131151
;
132152
%cast = bitcast <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1> to <2 x double>
133153
ret <2 x double> %cast
@@ -276,3 +296,14 @@ define <16 x i8> @bitcast_constexpr_16i8_8i16_u256uuu256uu() {
276296
%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>
277297
ret <16 x i8> %cast
278298
}
299+
300+
define <1 x i32> @bitcast_constexpr_scalar_fp_to_vector_int() {
301+
; CONSTVEC-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int(
302+
; CONSTVEC-NEXT: ret <1 x i32> <i32 1065353216>
303+
;
304+
; CONSTSPLAT-LABEL: @bitcast_constexpr_scalar_fp_to_vector_int(
305+
; CONSTSPLAT-NEXT: ret <1 x i32> bitcast (<1 x float> splat (float 1.000000e+00) to <1 x i32>)
306+
;
307+
%res = bitcast float 1.0 to <1 x i32>
308+
ret <1 x i32> %res
309+
}

0 commit comments

Comments
 (0)