diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-02-20 00:09:50 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-02-20 00:09:50 +0000 |
commit | 058bb8351351d56d2a4e8a772570231f9e5305e5 (patch) | |
tree | c1ed7b7acf0ae76ceba6318b4efdab03c049893e | |
parent | 3ae672623401ab9e0b5adc1c10cfd371246ab207 (diff) | |
download | bcm5719-llvm-058bb8351351d56d2a4e8a772570231f9e5305e5.tar.gz bcm5719-llvm-058bb8351351d56d2a4e8a772570231f9e5305e5.zip |
[InstSimplify] use any-zero matcher for fcmp folds
The m_APFloat matcher does not work with anything but strict
splat vector constants, so we could miss these folds and then
trigger an assertion in instcombine:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13201
llvm-svn: 354406
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 47 | ||||
-rw-r--r-- | llvm/test/Transforms/InstSimplify/floating-point-compare.ll | 16 |
2 files changed, 29 insertions, 34 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 843b3e97c07..092aaf610ca 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3648,6 +3648,31 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, } // Handle fcmp with constant RHS. + if (match(RHS, m_AnyZeroFP())) { + switch (Pred) { + case FCmpInst::FCMP_OGE: + if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getTrue(RetTy); + break; + case FCmpInst::FCMP_UGE: + if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getTrue(RetTy); + break; + case FCmpInst::FCMP_ULT: + if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getFalse(RetTy); + break; + case FCmpInst::FCMP_OLT: + if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getFalse(RetTy); + break; + default: + break; + } + } + + // TODO: Use match with a specific FP value, so these work with vectors with + // undef lanes. const APFloat *C; if (match(RHS, m_APFloat(C))) { // Check whether the constant is an infinity. @@ -3675,28 +3700,6 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, break; } } - } - if (C->isZero()) { - switch (Pred) { - case FCmpInst::FCMP_OGE: - if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) - return getTrue(RetTy); - break; - case FCmpInst::FCMP_UGE: - if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) - return getTrue(RetTy); - break; - case FCmpInst::FCMP_ULT: - if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) - return getFalse(RetTy); - break; - case FCmpInst::FCMP_OLT: - if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) - return getFalse(RetTy); - break; - default: - break; - } } else if (C->isNegative()) { assert(!C->isNaN() && "Unexpected NaN constant!"); // TODO: We can catch more cases by using a range check rather than diff --git a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll index 77db0522c98..5ce56e029d3 100644 --- a/llvm/test/Transforms/InstSimplify/floating-point-compare.ll +++ b/llvm/test/Transforms/InstSimplify/floating-point-compare.ll @@ -399,9 +399,7 @@ define <2 x i1> @fabs_is_not_negative_poszero(<2 x float> %V) { define <2 x i1> @fabs_is_not_negative_anyzero(<2 x float> %V) { ; CHECK-LABEL: @fabs_is_not_negative_anyzero( -; CHECK-NEXT: [[ABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[V:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <2 x float> [[ABS]], <float 0.000000e+00, float -0.000000e+00> -; CHECK-NEXT: ret <2 x i1> [[CMP]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %V) %cmp = fcmp olt <2 x float> %abs, <float 0.0, float -0.0> @@ -410,9 +408,7 @@ define <2 x i1> @fabs_is_not_negative_anyzero(<2 x float> %V) { define <3 x i1> @fabs_is_not_negative_negzero_undef(<3 x float> %V) { ; CHECK-LABEL: @fabs_is_not_negative_negzero_undef( -; CHECK-NEXT: [[ABS:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[V:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <3 x float> [[ABS]], <float -0.000000e+00, float -0.000000e+00, float undef> -; CHECK-NEXT: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> zeroinitializer ; %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) %cmp = fcmp olt <3 x float> %abs, <float -0.0, float -0.0, float undef> @@ -421,9 +417,7 @@ define <3 x i1> @fabs_is_not_negative_negzero_undef(<3 x float> %V) { define <3 x i1> @fabs_is_not_negative_poszero_undef(<3 x float> %V) { ; CHECK-LABEL: @fabs_is_not_negative_poszero_undef( -; CHECK-NEXT: [[ABS:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[V:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <3 x float> [[ABS]], <float 0.000000e+00, float 0.000000e+00, float undef> -; CHECK-NEXT: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> zeroinitializer ; %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) %cmp = fcmp olt <3 x float> %abs, <float 0.0, float 0.0, float undef> @@ -432,9 +426,7 @@ define <3 x i1> @fabs_is_not_negative_poszero_undef(<3 x float> %V) { define <3 x i1> @fabs_is_not_negative_anyzero_undef(<3 x float> %V) { ; CHECK-LABEL: @fabs_is_not_negative_anyzero_undef( -; CHECK-NEXT: [[ABS:%.*]] = call <3 x float> @llvm.fabs.v3f32(<3 x float> [[V:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <3 x float> [[ABS]], <float 0.000000e+00, float -0.000000e+00, float undef> -; CHECK-NEXT: ret <3 x i1> [[CMP]] +; CHECK-NEXT: ret <3 x i1> zeroinitializer ; %abs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %V) %cmp = fcmp olt <3 x float> %abs, <float 0.0, float -0.0, float undef> |