Skip to content

Commit 215bb15

Browse files
committed
[IR] restrict vector reduction intrinsic types
The arguments in all cases should be vectors of exactly one of integer or FP. All of the tests currently pass the verifier because we check for any vector type regardless of the type of reduction. This obviously can't work if we mix up integer and FP, and based on current LangRef text it was not intended to work for pointers either. The pointer case from https://llvm.org/PR49215 is what led me here. That example was avoided with 5b250a2. Differential Revision: https://reviews.llvm.org/D96904
1 parent a83a825 commit 215bb15

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

llvm/lib/IR/Verifier.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5018,6 +5018,36 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
50185018

50195019
break;
50205020
}
5021+
case Intrinsic::vector_reduce_and:
5022+
case Intrinsic::vector_reduce_or:
5023+
case Intrinsic::vector_reduce_xor:
5024+
case Intrinsic::vector_reduce_add:
5025+
case Intrinsic::vector_reduce_mul:
5026+
case Intrinsic::vector_reduce_smax:
5027+
case Intrinsic::vector_reduce_smin:
5028+
case Intrinsic::vector_reduce_umax:
5029+
case Intrinsic::vector_reduce_umin: {
5030+
Type *ArgTy = Call.getArgOperand(0)->getType();
5031+
Assert(ArgTy->isIntOrIntVectorTy() && ArgTy->isVectorTy(),
5032+
"Intrinsic has incorrect argument type!");
5033+
break;
5034+
}
5035+
case Intrinsic::vector_reduce_fmax:
5036+
case Intrinsic::vector_reduce_fmin: {
5037+
Type *ArgTy = Call.getArgOperand(0)->getType();
5038+
Assert(ArgTy->isFPOrFPVectorTy() && ArgTy->isVectorTy(),
5039+
"Intrinsic has incorrect argument type!");
5040+
break;
5041+
}
5042+
case Intrinsic::vector_reduce_fadd:
5043+
case Intrinsic::vector_reduce_fmul: {
5044+
// Unlike the other reductions, the first argument is a start value. The
5045+
// second argument is the vector to be reduced.
5046+
Type *ArgTy = Call.getArgOperand(1)->getType();
5047+
Assert(ArgTy->isFPOrFPVectorTy() && ArgTy->isVectorTy(),
5048+
"Intrinsic has incorrect argument type!");
5049+
break;
5050+
}
50215051
case Intrinsic::smul_fix:
50225052
case Intrinsic::smul_fix_sat:
50235053
case Intrinsic::umul_fix:

llvm/test/Verifier/reduction-intrinsics.ll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,33 @@ define i64 @result_too_wide(<4 x i32> %x) {
3030
ret i64 %r
3131
}
3232

33+
; We should have the appropriate (either int or FP) type of argument
34+
; for any vector reduction.
35+
36+
define float @not_float_reduce(<4 x float> %x) {
37+
; CHECK: Intrinsic has incorrect argument type!
38+
%r = call float @llvm.vector.reduce.umin.v4f32(<4 x float> %x)
39+
ret float %r
40+
}
41+
42+
define i32* @not_pointer_reduce(<4 x i32*> %x) {
43+
; CHECK: Intrinsic has incorrect argument type!
44+
%r = call i32* @llvm.vector.reduce.or.v4p0i32(<4 x i32*> %x)
45+
ret i32* %r
46+
}
47+
48+
define i32 @not_integer_reduce(<4 x i32> %x) {
49+
; CHECK: Intrinsic has incorrect argument type!
50+
%r = call i32 @llvm.vector.reduce.fadd.v4i32(i32 0, <4 x i32> %x)
51+
ret i32 %r
52+
}
53+
54+
define i32* @not_pointer_reduce2(<4 x i32*> %x) {
55+
; CHECK: Intrinsic has incorrect argument type!
56+
%r = call i32* @llvm.vector.reduce.fmin.v4p0i32(<4 x i32*> %x)
57+
ret i32* %r
58+
}
59+
3360
declare float @llvm.vector.reduce.umin.v4f32(<4 x float>)
3461
declare i32* @llvm.vector.reduce.or.v4p0i32(<4 x i32*>)
3562
declare i32 @llvm.vector.reduce.fadd.v4i32(i32, <4 x i32>)

0 commit comments

Comments
 (0)