[llvm] d4912e8 - ValueTracking: Add some tests to cover asserts in fcmpImpliesClass

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 12 22:05:59 PST 2023


Author: Matt Arsenault
Date: 2023-11-13T15:05:52+09:00
New Revision: d4912e80500706a9912725d45d822675cf9153d8

URL: https://github.com/llvm/llvm-project/commit/d4912e80500706a9912725d45d822675cf9153d8
DIFF: https://github.com/llvm/llvm-project/commit/d4912e80500706a9912725d45d822675cf9153d8.diff

LOG: ValueTracking: Add some tests to cover asserts in fcmpImpliesClass

Catch asserts hit after 1adce7d8e47e2438f99f91607760b825e5e3cc37

Added: 
    llvm/test/Transforms/EarlyCSE/cannot-be-negative-zero-assert.ll

Modified: 
    llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll
    llvm/test/Transforms/InstSimplify/known-never-infinity.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/EarlyCSE/cannot-be-negative-zero-assert.ll b/llvm/test/Transforms/EarlyCSE/cannot-be-negative-zero-assert.ll
new file mode 100644
index 000000000000000..1a24c47337757d6
--- /dev/null
+++ b/llvm/test/Transforms/EarlyCSE/cannot-be-negative-zero-assert.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -S -passes=early-cse < %s | FileCheck %s
+
+; We can't assume comparisons with 0 are exact class tests with dynamic denormal mode
+define double @cannot_be_negative_zero_test_dynamic_denormal_fp_math(double %a) #0 {
+; CHECK-LABEL: define double @cannot_be_negative_zero_test_dynamic_denormal_fp_math(
+; CHECK-SAME: double [[A:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A]], 0.000000e+00
+; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double 1.000000e+00, double 0.000000e+00
+; CHECK-NEXT:    store double [[COND]], ptr addrspace(5) null, align 8
+; CHECK-NEXT:    ret double [[COND]]
+;
+entry:
+  %cmp = fcmp oeq double %a, 0.000000e+00
+  %cond = select i1 %cmp, double 1.000000e+00, double 0.000000e+00
+  store double %cond, ptr addrspace(5) null, align 8
+  %load = load double, ptr addrspace(5) null, align 8
+  %add.i = fadd double %load, 0.000000e+00
+  ret double %add.i
+}
+
+define double @cannot_be_negative_zero_test_dynamic_denormal_fp_math_negzero(double %a) #0 {
+; CHECK-LABEL: define double @cannot_be_negative_zero_test_dynamic_denormal_fp_math_negzero(
+; CHECK-SAME: double [[A:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A]], -0.000000e+00
+; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], double 1.000000e+00, double 0.000000e+00
+; CHECK-NEXT:    store double [[COND]], ptr addrspace(5) null, align 8
+; CHECK-NEXT:    ret double [[COND]]
+;
+entry:
+  %cmp = fcmp oeq double %a, -0.000000e+00
+  %cond = select i1 %cmp, double 1.000000e+00, double 0.000000e+00
+  store double %cond, ptr addrspace(5) null, align 8
+  %load = load double, ptr addrspace(5) null, align 8
+  %add.i = fadd double %load, 0.000000e+00
+  ret double %add.i
+}
+
+attributes #0 = { "denormal-fp-math"="dynamic,dynamic" }

diff  --git a/llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll b/llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll
index e6d5e409bbabf4a..ec4e3c3092414aa 100644
--- a/llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll
+++ b/llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll
@@ -6,6 +6,7 @@
 ; classes.
 
 declare void @llvm.assume(i1 noundef) #0
+declare float @llvm.fabs.f32(float) #0
 
 ; --------------------------------------------------------------------
 ; Test assume x < -1.0 with compares to 0
@@ -3037,4 +3038,126 @@ define i1 @assume_olt_2__olt_1(float %arg) {
   ret i1 %cmp
 }
 
+; --------------------------------------------------------------------
+; Negative infinity
+; --------------------------------------------------------------------
+
+define i1 @assume_ogt_neginf_one_neginf(float %arg) {
+; CHECK-LABEL: define i1 @assume_ogt_neginf_one_neginf(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT:    [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
+  call void @llvm.assume(i1 %cmp.ogt.neginf)
+  %cmp = fcmp one float %arg, 0xFFF0000000000000
+  ret i1 %cmp
+}
+
+define i1 @assume_ogt_neginf_oeq_posinf(float %arg) {
+; CHECK-LABEL: define i1 @assume_ogt_neginf_oeq_posinf(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT:    [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ARG]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
+  call void @llvm.assume(i1 %cmp.ogt.neginf)
+  %cmp = fcmp oeq float %arg, 0x7FF0000000000000
+  ret i1 %cmp
+}
+
+define i1 @assume_ule_neginf_oeq_neginf(float %arg) {
+; CHECK-LABEL: define i1 @assume_ule_neginf_oeq_neginf(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT:    [[CMP_ULE_NEGINF:%.*]] = fcmp ule float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_ULE_NEGINF]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp.ule.neginf = fcmp ule float %arg, 0xFFF0000000000000
+  call void @llvm.assume(i1 %cmp.ule.neginf)
+  %cmp = fcmp oeq float %arg, 0xFFF0000000000000
+  ret i1 %cmp
+}
+
+define i1 @assume_ult_neginf_oeq_neginf(float %arg) {
+; CHECK-LABEL: define i1 @assume_ult_neginf_oeq_neginf(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT:    [[CMP_ULT_NEGINF:%.*]] = fcmp ult float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_ULT_NEGINF]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp.ult.neginf = fcmp ult float %arg, 0xFFF0000000000000
+  call void @llvm.assume(i1 %cmp.ult.neginf)
+  %cmp = fcmp oeq float %arg, 0xFFF0000000000000
+  ret i1 %cmp
+}
+
+define i1 @assume_fabs_ogt_neginf_one_neginf(float %arg) {
+; CHECK-LABEL: define i1 @assume_fabs_ogt_neginf_one_neginf(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]])
+; CHECK-NEXT:    [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[FABS_ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fabs.arg = call float @llvm.fabs.f32(float %arg)
+  %cmp.ogt.neginf = fcmp ogt float %fabs.arg, 0xFFF0000000000000
+  call void @llvm.assume(i1 %cmp.ogt.neginf)
+  %cmp = fcmp one float %arg, 0xFFF0000000000000
+  ret i1 %cmp
+}
+
+define i1 @assume_fabs_ogt_neginf_one_posinf(float %arg) {
+; CHECK-LABEL: define i1 @assume_fabs_ogt_neginf_one_posinf(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]])
+; CHECK-NEXT:    [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[FABS_ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[ARG]], 0x7FF0000000000000
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fabs.arg = call float @llvm.fabs.f32(float %arg)
+  %cmp.ogt.neginf = fcmp ogt float %fabs.arg, 0xFFF0000000000000
+  call void @llvm.assume(i1 %cmp.ogt.neginf)
+  %cmp = fcmp one float %arg, 0x7FF0000000000000
+  ret i1 %cmp
+}
+
+define i1 @assume_fabs_ule_neginf_oeq_neginf(float %arg) {
+; CHECK-LABEL: define i1 @assume_fabs_ule_neginf_oeq_neginf(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]])
+; CHECK-NEXT:    [[CMP_OGT_NEGINF:%.*]] = fcmp ule float [[FABS_ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fabs.arg = call float @llvm.fabs.f32(float %arg)
+  %cmp.ogt.neginf = fcmp ule float %fabs.arg, 0xFFF0000000000000
+  call void @llvm.assume(i1 %cmp.ogt.neginf)
+  %cmp = fcmp oeq float %arg, 0xFFF0000000000000
+  ret i1 %cmp
+}
+
+define i1 @assume_oge_neginf_oeq_neginf(float %arg) {
+; CHECK-LABEL: define i1 @assume_oge_neginf_oeq_neginf(
+; CHECK-SAME: float [[ARG:%.*]]) {
+; CHECK-NEXT:    [[CMP_OGE_NEGINF:%.*]] = fcmp oge float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_OGE_NEGINF]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp.oge.neginf = fcmp oge float %arg, 0xFFF0000000000000
+  call void @llvm.assume(i1 %cmp.oge.neginf)
+  %cmp = fcmp oeq float %arg, 0xFFF0000000000000
+  ret i1 %cmp
+}
+
 attributes #0 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }

diff  --git a/llvm/test/Transforms/InstSimplify/known-never-infinity.ll b/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
index efa19aa0999a7a3..74039d3ffd56ca9 100644
--- a/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
+++ b/llvm/test/Transforms/InstSimplify/known-never-infinity.ll
@@ -1063,6 +1063,51 @@ entry:
   ret i1 %one
 }
 
+; This asserted because we didn't handle non-equality comparisons to
+; negative infinity when recognizing is.fpclass-like compares.
+define float @fcmp_ogt_neginf_implies_class_assert(float %arg) {
+; CHECK-LABEL: define float @fcmp_ogt_neginf_implies_class_assert
+; CHECK-SAME: (float [[ARG:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
+  %select_1_0 = select i1 %cmp.ogt.neginf, float 1.0, float 0.0
+  %mul_by_zero = fmul float %select_1_0, 0.0
+  ret float %mul_by_zero
+}
+
+define float @fcmp_ule_neginf_implies_class_assert(float %arg) {
+; CHECK-LABEL: define float @fcmp_ule_neginf_implies_class_assert
+; CHECK-SAME: (float [[ARG:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %cmp.ule.neginf = fcmp ule float %arg, 0xFFF0000000000000
+  %select_1_0 = select i1 %cmp.ule.neginf, float 1.0, float 0.0
+  %mul_by_zero = fmul float %select_1_0, 0.0
+  ret float %mul_by_zero
+}
+
+define float @fcmp_oge_neginf_implies_class_assert(float %arg) {
+; CHECK-LABEL: define float @fcmp_oge_neginf_implies_class_assert
+; CHECK-SAME: (float [[ARG:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %cmp.oge.neginf = fcmp oge float %arg, 0xFFF0000000000000
+  %select_1_0 = select i1 %cmp.oge.neginf, float 1.0, float 0.0
+  %mul_by_zero = fmul float %select_1_0, 0.0
+  ret float %mul_by_zero
+}
+
+define float @fcmp_ult_neginf_implies_class_assert(float %arg) {
+; CHECK-LABEL: define float @fcmp_ult_neginf_implies_class_assert
+; CHECK-SAME: (float [[ARG:%.*]]) {
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+  %cmp.ult.neginf = fcmp ult float %arg, 0xFFF0000000000000
+  %select_1_0 = select i1 %cmp.ult.neginf, float 1.0, float 0.0
+  %mul_by_zero = fmul float %select_1_0, 0.0
+  ret float %mul_by_zero
+}
 
 declare double @llvm.arithmetic.fence.f64(double)
 declare double @llvm.canonicalize.f64(double)


        


More information about the llvm-commits mailing list