[llvm] 14db069 - [InstCombine] Fix a cycle when folding fneg(select) with scalable vector types (#112465)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 25 10:47:44 PDT 2024
Author: ssijaric-nv
Date: 2024-10-25T10:47:39-07:00
New Revision: 14db06946839729befd6bd3ced8142547f5fd139
URL: https://github.com/llvm/llvm-project/commit/14db06946839729befd6bd3ced8142547f5fd139
DIFF: https://github.com/llvm/llvm-project/commit/14db06946839729befd6bd3ced8142547f5fd139.diff
LOG: [InstCombine] Fix a cycle when folding fneg(select) with scalable vector types (#112465)
The two folding operations are causing a cycle for the following case
with
scalable vector types:
define <vscale x 2 x double> @test_fneg_select_abs(<vscale x 2 x i1>
%cond, <vscale x 2 x double> %b) {
%1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double>
zeroinitializer, <vscale x 2 x double> %b
%2 = fneg fast <vscale x 2 x double> %1
ret <vscale x 2 x double> %2
}
1) fold fneg: -(Cond ? C : Y) -> Cond ? -C : -Y
2) fold select: (Cond ? -X : -Y) -> -(Cond ? X : Y)
1) results in the following since '<vscale x 2 x double>
zeroinitializer' passes
the check for the immediate constant:
%.neg = fneg fast <vscale x 2 x double> zeroinitializer
%b.neg = fneg fast <vscale x 2 x double> %b
%1 = select fast <vscale x 2 x i1> %cond, <vscale x 2 x double> %.neg,
<vscale x 2 x double> %b.neg
and so we end up going back and forth between 1) and 2).
Attempt to fold scalable vector constants, so that we end up with a
splat instead:
define <vscale x 2 x double> @test_fneg_select_abs(<vscale x 2 x i1>
%cond, <vscale x 2 x double> %b) {
%b.neg = fneg fast <vscale x 2 x double> %b
%1 = select fast <vscale x 2 x i1> %cond, <vscale x 2 x double>
shufflevector (<vscale x 2 x double> insertelement (<vscale x 2 x
double> poison, double -0.000000e+00, i64 0), <vscale x 2 x double>
poison, <vscale x 2 x i32> zeroinitializer), <vscale x 2 x double>
%b.neg
ret <vscale x 2 x double> %1
}
Added:
Modified:
llvm/lib/IR/ConstantFold.cpp
llvm/test/Transforms/InstCombine/fneg.ll
llvm/test/Transforms/InstSimplify/fp-nan.ll
Removed:
################################################################################
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 57d9a03c9c22b8..07dfbc41e79b00 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -581,26 +581,27 @@ Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) {
case Instruction::FNeg:
return ConstantFP::get(C->getContext(), neg(CV));
}
- } else if (auto *VTy = dyn_cast<FixedVectorType>(C->getType())) {
-
- Type *Ty = IntegerType::get(VTy->getContext(), 32);
+ } else if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
// Fast path for splatted constants.
if (Constant *Splat = C->getSplatValue())
if (Constant *Elt = ConstantFoldUnaryInstruction(Opcode, Splat))
return ConstantVector::getSplat(VTy->getElementCount(), Elt);
- // Fold each element and create a vector constant from those constants.
- SmallVector<Constant *, 16> Result;
- for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
- Constant *ExtractIdx = ConstantInt::get(Ty, i);
- Constant *Elt = ConstantExpr::getExtractElement(C, ExtractIdx);
- Constant *Res = ConstantFoldUnaryInstruction(Opcode, Elt);
- if (!Res)
- return nullptr;
- Result.push_back(Res);
- }
+ if (auto *FVTy = dyn_cast<FixedVectorType>(VTy)) {
+ // Fold each element and create a vector constant from those constants.
+ Type *Ty = IntegerType::get(FVTy->getContext(), 32);
+ SmallVector<Constant *, 16> Result;
+ for (unsigned i = 0, e = FVTy->getNumElements(); i != e; ++i) {
+ Constant *ExtractIdx = ConstantInt::get(Ty, i);
+ Constant *Elt = ConstantExpr::getExtractElement(C, ExtractIdx);
+ Constant *Res = ConstantFoldUnaryInstruction(Opcode, Elt);
+ if (!Res)
+ return nullptr;
+ Result.push_back(Res);
+ }
- return ConstantVector::get(Result);
+ return ConstantVector::get(Result);
+ }
}
// We don't know how to fold this.
diff --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll
index 3c4088832feaaa..6a9b3309bb347e 100644
--- a/llvm/test/Transforms/InstCombine/fneg.ll
+++ b/llvm/test/Transforms/InstCombine/fneg.ll
@@ -1109,4 +1109,36 @@ define float @test_fneg_select_maxnum(float %x) {
ret float %neg
}
+; Check that there's no infinite loop.
+define <vscale x 2 x double> @test_fneg_select_svec(<vscale x 2 x i1> %cond, <vscale x 2 x double> %b) {
+; CHECK-LABEL: @test_fneg_select_svec(
+; CHECK-NEXT: [[TMP2:%.*]] = fneg fast <vscale x 2 x double> [[TMP1:%.*]]
+; CHECK-NEXT: [[TMP3:%.*]] = select fast <vscale x 2 x i1> [[COND:%.*]], <vscale x 2 x double> shufflevector (<vscale x 2 x double> insertelement (<vscale x 2 x double> poison, double -0.000000e+00, i64 0), <vscale x 2 x double> poison, <vscale x 2 x i32> zeroinitializer), <vscale x 2 x double> [[TMP2]]
+; CHECK-NEXT: ret <vscale x 2 x double> [[TMP3]]
+;
+ %1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double> zeroinitializer, <vscale x 2 x double> %b
+ %2 = fneg fast <vscale x 2 x double> %1
+ ret <vscale x 2 x double> %2
+}
+
+define <vscale x 2 x double> @test_fneg_select_svec_2(<vscale x 2 x i1> %cond, <vscale x 2 x double> %a) {
+; CHECK-LABEL: @test_fneg_select_svec_2(
+; CHECK-NEXT: [[A_NEG:%.*]] = fneg fast <vscale x 2 x double> [[A:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = select fast <vscale x 2 x i1> [[COND:%.*]], <vscale x 2 x double> [[A_NEG]], <vscale x 2 x double> shufflevector (<vscale x 2 x double> insertelement (<vscale x 2 x double> poison, double -0.000000e+00, i64 0), <vscale x 2 x double> poison, <vscale x 2 x i32> zeroinitializer)
+; CHECK-NEXT: ret <vscale x 2 x double> [[TMP1]]
+;
+ %1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double> %a, <vscale x 2 x double> zeroinitializer
+ %2 = fneg fast <vscale x 2 x double> %1
+ ret <vscale x 2 x double> %2
+}
+
+define <vscale x 2 x double> @test_fneg_select_svec_3(<vscale x 2 x i1> %cond, <vscale x 2 x double> %b) {
+; CHECK-LABEL: @test_fneg_select_svec_3(
+; CHECK-NEXT: ret <vscale x 2 x double> shufflevector (<vscale x 2 x double> insertelement (<vscale x 2 x double> poison, double -0.000000e+00, i64 0), <vscale x 2 x double> poison, <vscale x 2 x i32> zeroinitializer)
+;
+ %1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double> zeroinitializer, <vscale x 2 x double> zeroinitializer
+ %2 = fneg fast <vscale x 2 x double> %1
+ ret <vscale x 2 x double> %2
+}
+
!0 = !{}
diff --git a/llvm/test/Transforms/InstSimplify/fp-nan.ll b/llvm/test/Transforms/InstSimplify/fp-nan.ll
index bb557500822c14..06b23200bafff8 100644
--- a/llvm/test/Transforms/InstSimplify/fp-nan.ll
+++ b/llvm/test/Transforms/InstSimplify/fp-nan.ll
@@ -237,8 +237,7 @@ define <2 x double> @unary_fneg_nan_2(<2 x double> %x) {
; FIXME: This doesn't behave the same way as the fixed-length vectors above
define <vscale x 1 x double> @unary_fneg_nan_2_scalable_vec_0() {
; CHECK-LABEL: @unary_fneg_nan_2_scalable_vec_0(
-; CHECK-NEXT: [[R:%.*]] = fneg <vscale x 1 x double> shufflevector (<vscale x 1 x double> insertelement (<vscale x 1 x double> poison, double 0xFFF1234567890ABC, i64 0), <vscale x 1 x double> poison, <vscale x 1 x i32> zeroinitializer)
-; CHECK-NEXT: ret <vscale x 1 x double> [[R]]
+; CHECK-NEXT: ret <vscale x 1 x double> shufflevector (<vscale x 1 x double> insertelement (<vscale x 1 x double> poison, double 0x7FF1234567890ABC, i64 0), <vscale x 1 x double> poison, <vscale x 1 x i32> zeroinitializer)
;
%r = fneg <vscale x 1 x double> splat (double 0xFFF1234567890ABC)
ret <vscale x 1 x double> %r
@@ -247,8 +246,7 @@ define <vscale x 1 x double> @unary_fneg_nan_2_scalable_vec_0() {
; FIXME: This doesn't behave the same way as the fixed-length vectors above
define <vscale x 1 x double> @unary_fneg_nan_2_scalable_vec_1() {
; CHECK-LABEL: @unary_fneg_nan_2_scalable_vec_1(
-; CHECK-NEXT: [[R:%.*]] = fneg <vscale x 1 x double> shufflevector (<vscale x 1 x double> insertelement (<vscale x 1 x double> poison, double 0x7FF0000000000001, i64 0), <vscale x 1 x double> poison, <vscale x 1 x i32> zeroinitializer)
-; CHECK-NEXT: ret <vscale x 1 x double> [[R]]
+; CHECK-NEXT: ret <vscale x 1 x double> shufflevector (<vscale x 1 x double> insertelement (<vscale x 1 x double> poison, double 0xFFF0000000000001, i64 0), <vscale x 1 x double> poison, <vscale x 1 x i32> zeroinitializer)
;
%r = fneg <vscale x 1 x double> splat (double 0x7FF0000000000001)
ret <vscale x 1 x double> %r
More information about the llvm-commits
mailing list