[llvm] 295ba49 - [NFC][SimplifyCFG] Add some tests with PHI's for fold-branch-to-common-dest xform

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 4 09:59:10 PST 2022


Author: Roman Lebedev
Date: 2022-12-04T20:58:55+03:00
New Revision: 295ba49330e6ae1d029a0430769c80c0606b0402

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

LOG: [NFC][SimplifyCFG] Add some tests with PHI's for fold-branch-to-common-dest xform

Added: 
    llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll

Modified: 
    llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll b/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll
new file mode 100644
index 000000000000..b3af7f7c2892
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll
@@ -0,0 +1,194 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -bonus-inst-threshold=1 | FileCheck %s --check-prefixes=ALL
+
+declare void @sideeffect0(i8)
+declare void @sideeffect1(i8)
+declare void @sideeffect2(i8)
+declare i8 @gen8() speculatable
+
+define void @incompatible_ivs_of_single_phi(i8 %v0, i8 %v1, i8 %iv.of.final_left.from.dispatch, i8 %iv.of.final_right.from.pred, i8 %iv.of.final_right.from.dispatch) {
+; ALL-LABEL: @incompatible_ivs_of_single_phi(
+; ALL-NEXT:  pred:
+; ALL-NEXT:    [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
+; ALL-NEXT:    br i1 [[C0]], label [[DISPATCH:%.*]], label [[FINAL_RIGHT:%.*]]
+; ALL:       dispatch:
+; ALL-NEXT:    [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
+; ALL-NEXT:    br i1 [[C1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT]]
+; ALL:       common.ret:
+; ALL-NEXT:    ret void
+; ALL:       final_left:
+; ALL-NEXT:    [[FINAL_LEFT_PHI:%.*]] = phi i8 [ [[IV_OF_FINAL_LEFT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect0(i8 [[FINAL_LEFT_PHI]])
+; ALL-NEXT:    br label [[COMMON_RET:%.*]]
+; ALL:       final_right:
+; ALL-NEXT:    [[FINAL_RIGHT_PHI:%.*]] = phi i8 [ [[IV_OF_FINAL_RIGHT_FROM_PRED:%.*]], [[PRED:%.*]] ], [ [[IV_OF_FINAL_RIGHT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect1(i8 [[FINAL_RIGHT_PHI]])
+; ALL-NEXT:    br label [[COMMON_RET]]
+;
+pred:
+  %c0 = icmp eq i8 %v0, 0
+  br i1 %c0, label %dispatch, label %final_right
+dispatch:
+  %c1 = icmp eq i8 %v1, 0
+  br i1 %c1, label %final_left, label %final_right
+final_left:
+  %final_left.phi = phi i8 [ %iv.of.final_left.from.dispatch, %dispatch ]
+  call void @sideeffect0(i8 %final_left.phi)
+  ret void
+final_right:
+  %final_right.phi = phi i8 [ %iv.of.final_right.from.pred, %pred ], [ %iv.of.final_right.from.dispatch, %dispatch ]
+  call void @sideeffect1(i8 %final_right.phi)
+  ret void
+}
+
+define void @incompatible_ivs_of_single_phi.invert_pred_cond(i8 %v0, i8 %v1, i8 %iv.of.final_left.from.dispatch, i8 %iv.of.final_right.from.pred, i8 %iv.of.final_right.from.dispatch) {
+; ALL-LABEL: @incompatible_ivs_of_single_phi.invert_pred_cond(
+; ALL-NEXT:  pred:
+; ALL-NEXT:    [[C0:%.*]] = icmp ne i8 [[V0:%.*]], 0
+; ALL-NEXT:    br i1 [[C0]], label [[FINAL_RIGHT:%.*]], label [[DISPATCH:%.*]]
+; ALL:       dispatch:
+; ALL-NEXT:    [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
+; ALL-NEXT:    br i1 [[C1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT]]
+; ALL:       common.ret:
+; ALL-NEXT:    ret void
+; ALL:       final_left:
+; ALL-NEXT:    [[FINAL_LEFT_PHI:%.*]] = phi i8 [ [[IV_OF_FINAL_LEFT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect0(i8 [[FINAL_LEFT_PHI]])
+; ALL-NEXT:    br label [[COMMON_RET:%.*]]
+; ALL:       final_right:
+; ALL-NEXT:    [[FINAL_RIGHT_PHI:%.*]] = phi i8 [ [[IV_OF_FINAL_RIGHT_FROM_PRED:%.*]], [[PRED:%.*]] ], [ [[IV_OF_FINAL_RIGHT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect1(i8 [[FINAL_RIGHT_PHI]])
+; ALL-NEXT:    br label [[COMMON_RET]]
+;
+pred:
+  %c0 = icmp ne i8 %v0, 0
+  br i1 %c0, label %final_right, label %dispatch
+dispatch:
+  %c1 = icmp eq i8 %v1, 0
+  br i1 %c1, label %final_left, label %final_right
+final_left:
+  %final_left.phi = phi i8 [ %iv.of.final_left.from.dispatch, %dispatch ]
+  call void @sideeffect0(i8 %final_left.phi)
+  ret void
+final_right:
+  %final_right.phi = phi i8 [ %iv.of.final_right.from.pred, %pred ], [ %iv.of.final_right.from.dispatch, %dispatch ]
+  call void @sideeffect1(i8 %final_right.phi)
+  ret void
+}
+
+define void @incompatible_ivs_of_single_phi.insertpos(i8 %v0, i8 %v1, i8 %iv.of.final_left.from.dispatch) {
+; ALL-LABEL: @incompatible_ivs_of_single_phi.insertpos(
+; ALL-NEXT:  pred:
+; ALL-NEXT:    [[IV_OF_FINAL_RIGHT_FROM_PRED:%.*]] = call i8 @gen8()
+; ALL-NEXT:    [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
+; ALL-NEXT:    br i1 [[C0]], label [[DISPATCH:%.*]], label [[FINAL_RIGHT:%.*]]
+; ALL:       dispatch:
+; ALL-NEXT:    [[IV_OF_FINAL_RIGHT_FROM_DISPATCH:%.*]] = call i8 @gen8()
+; ALL-NEXT:    [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
+; ALL-NEXT:    br i1 [[C1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT]]
+; ALL:       common.ret:
+; ALL-NEXT:    ret void
+; ALL:       final_left:
+; ALL-NEXT:    [[FINAL_LEFT_PHI:%.*]] = phi i8 [ [[IV_OF_FINAL_LEFT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect0(i8 [[FINAL_LEFT_PHI]])
+; ALL-NEXT:    br label [[COMMON_RET:%.*]]
+; ALL:       final_right:
+; ALL-NEXT:    [[FINAL_RIGHT_PHI:%.*]] = phi i8 [ [[IV_OF_FINAL_RIGHT_FROM_PRED]], [[PRED:%.*]] ], [ [[IV_OF_FINAL_RIGHT_FROM_DISPATCH]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect1(i8 [[FINAL_RIGHT_PHI]])
+; ALL-NEXT:    br label [[COMMON_RET]]
+;
+pred:
+  %iv.of.final_right.from.pred = call i8 @gen8()
+  %c0 = icmp eq i8 %v0, 0
+  br i1 %c0, label %dispatch, label %final_right
+dispatch:
+  %iv.of.final_right.from.dispatch = call i8 @gen8()
+  %c1 = icmp eq i8 %v1, 0
+  br i1 %c1, label %final_left, label %final_right
+final_left:
+  %final_left.phi = phi i8 [ %iv.of.final_left.from.dispatch, %dispatch ]
+  call void @sideeffect0(i8 %final_left.phi)
+  ret void
+final_right:
+  %final_right.phi = phi i8 [ %iv.of.final_right.from.pred, %pred ], [ %iv.of.final_right.from.dispatch, %dispatch ]
+  call void @sideeffect1(i8 %final_right.phi)
+  ret void
+}
+
+define void @incompatible_ivs_of_one_of_two_phis(i8 %v0, i8 %v1, i8 %iv.of.final_left.from.dispatch, i8 %iv.of.final_right.from.pred, i8 %iv.of.final_right.from.dispatch) {
+; ALL-LABEL: @incompatible_ivs_of_one_of_two_phis(
+; ALL-NEXT:  pred:
+; ALL-NEXT:    [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
+; ALL-NEXT:    br i1 [[C0]], label [[DISPATCH:%.*]], label [[FINAL_RIGHT:%.*]]
+; ALL:       dispatch:
+; ALL-NEXT:    [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
+; ALL-NEXT:    br i1 [[C1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT]]
+; ALL:       common.ret:
+; ALL-NEXT:    ret void
+; ALL:       final_left:
+; ALL-NEXT:    [[FINAL_LEFT_PHI:%.*]] = phi i8 [ [[IV_OF_FINAL_LEFT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect0(i8 [[FINAL_LEFT_PHI]])
+; ALL-NEXT:    br label [[COMMON_RET:%.*]]
+; ALL:       final_right:
+; ALL-NEXT:    [[FINAL_RIGHT_PHI_0:%.*]] = phi i8 [ [[IV_OF_FINAL_RIGHT_FROM_PRED:%.*]], [[PRED:%.*]] ], [ [[IV_OF_FINAL_RIGHT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    [[FINAL_RIGHT_PHI_1:%.*]] = phi i8 [ 42, [[PRED]] ], [ 42, [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect1(i8 [[FINAL_RIGHT_PHI_0]])
+; ALL-NEXT:    call void @sideeffect1(i8 [[FINAL_RIGHT_PHI_1]])
+; ALL-NEXT:    br label [[COMMON_RET]]
+;
+pred:
+  %c0 = icmp eq i8 %v0, 0
+  br i1 %c0, label %dispatch, label %final_right
+dispatch:
+  %c1 = icmp eq i8 %v1, 0
+  br i1 %c1, label %final_left, label %final_right
+final_left:
+  %final_left.phi = phi i8 [ %iv.of.final_left.from.dispatch, %dispatch ]
+  call void @sideeffect0(i8 %final_left.phi)
+  ret void
+final_right:
+  %final_right.phi.0 = phi i8 [ %iv.of.final_right.from.pred, %pred ], [ %iv.of.final_right.from.dispatch, %dispatch ]
+  %final_right.phi.1 = phi i8 [ 42, %pred ], [ 42, %dispatch ]
+  call void @sideeffect1(i8 %final_right.phi.0)
+  call void @sideeffect1(i8 %final_right.phi.1)
+  ret void
+}
+
+define void @incompatible_ivs_of_two_phis(i8 %v0, i8 %v1, i8 %iv.of.final_left.from.dispatch, i8 %iv0.of.final_right.from.pred, i8 %iv0.of.final_right.from.dispatch, i8 %iv1.of.final_right.from.pred, i8 %iv1.of.final_right.from.dispatch) {
+; ALL-LABEL: @incompatible_ivs_of_two_phis(
+; ALL-NEXT:  pred:
+; ALL-NEXT:    [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
+; ALL-NEXT:    br i1 [[C0]], label [[DISPATCH:%.*]], label [[FINAL_RIGHT:%.*]]
+; ALL:       dispatch:
+; ALL-NEXT:    [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
+; ALL-NEXT:    br i1 [[C1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT]]
+; ALL:       common.ret:
+; ALL-NEXT:    ret void
+; ALL:       final_left:
+; ALL-NEXT:    [[FINAL_LEFT_PHI:%.*]] = phi i8 [ [[IV_OF_FINAL_LEFT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect0(i8 [[FINAL_LEFT_PHI]])
+; ALL-NEXT:    br label [[COMMON_RET:%.*]]
+; ALL:       final_right:
+; ALL-NEXT:    [[FINAL_RIGHT_PHI_0:%.*]] = phi i8 [ [[IV0_OF_FINAL_RIGHT_FROM_PRED:%.*]], [[PRED:%.*]] ], [ [[IV0_OF_FINAL_RIGHT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    [[FINAL_RIGHT_PHI_1:%.*]] = phi i8 [ [[IV1_OF_FINAL_RIGHT_FROM_PRED:%.*]], [[PRED]] ], [ [[IV1_OF_FINAL_RIGHT_FROM_DISPATCH:%.*]], [[DISPATCH]] ]
+; ALL-NEXT:    call void @sideeffect1(i8 [[FINAL_RIGHT_PHI_0]])
+; ALL-NEXT:    call void @sideeffect1(i8 [[FINAL_RIGHT_PHI_1]])
+; ALL-NEXT:    br label [[COMMON_RET]]
+;
+pred:
+  %c0 = icmp eq i8 %v0, 0
+  br i1 %c0, label %dispatch, label %final_right
+dispatch:
+  %c1 = icmp eq i8 %v1, 0
+  br i1 %c1, label %final_left, label %final_right
+final_left:
+  %final_left.phi = phi i8 [ %iv.of.final_left.from.dispatch, %dispatch ]
+  call void @sideeffect0(i8 %final_left.phi)
+  ret void
+final_right:
+  %final_right.phi.0 = phi i8 [ %iv0.of.final_right.from.pred, %pred ], [ %iv0.of.final_right.from.dispatch, %dispatch ]
+  %final_right.phi.1 = phi i8 [ %iv1.of.final_right.from.pred, %pred ], [ %iv1.of.final_right.from.dispatch, %dispatch ]
+  call void @sideeffect1(i8 %final_right.phi.0)
+  call void @sideeffect1(i8 %final_right.phi.1)
+  ret void
+}

diff  --git a/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll b/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll
index d5945962342c..0c3914cda137 100644
--- a/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll
+++ b/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll
@@ -1117,4 +1117,49 @@ cleanup:
   ret i32 %retval.0
 }
 
+define i32 @test_builtin_fpclassify(float %x) {
+; CHECK-LABEL: @test_builtin_fpclassify(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ISZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    br i1 [[ISZERO]], label [[FPCLASSIFY_END:%.*]], label [[FPCLASSIFY_NOT_ZERO:%.*]]
+; CHECK:       fpclassify_end:
+; CHECK-NEXT:    [[FPCLASSIFY_RESULT:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ 0, [[FPCLASSIFY_NOT_ZERO]] ], [ 1, [[FPCLASSIFY_NOT_NAN:%.*]] ], [ [[NORMAL_OR_SUBNORMAL:%.*]], [[FPCLASSIFY_NOT_INF:%.*]] ]
+; CHECK-NEXT:    ret i32 [[FPCLASSIFY_RESULT]]
+; CHECK:       fpclassify_not_zero:
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[X]], 0.000000e+00
+; CHECK-NEXT:    br i1 [[CMP]], label [[FPCLASSIFY_END]], label [[FPCLASSIFY_NOT_NAN]]
+; CHECK:       fpclassify_not_nan:
+; CHECK-NEXT:    [[X_ABS:%.*]] = tail call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT:    [[ISINF:%.*]] = fcmp oeq float [[X_ABS]], 0x7FF0000000000000
+; CHECK-NEXT:    br i1 [[ISINF]], label [[FPCLASSIFY_END]], label [[FPCLASSIFY_NOT_INF]]
+; CHECK:       fpclassify_not_inf:
+; CHECK-NEXT:    [[ISNORMAL:%.*]] = fcmp uge float [[X_ABS]], 0x3810000000000000
+; CHECK-NEXT:    [[NORMAL_OR_SUBNORMAL]] = select i1 [[ISNORMAL]], i32 4, i32 3
+; CHECK-NEXT:    br label [[FPCLASSIFY_END]]
+;
+entry:
+  %iszero = fcmp oeq float %x, 0.000000e+00
+  br i1 %iszero, label %fpclassify_end, label %fpclassify_not_zero
+
+fpclassify_end:
+  %fpclassify_result = phi i32 [ 2, %entry ], [ 0, %fpclassify_not_zero ], [ 1, %fpclassify_not_nan ], [ %normal_or_subnormal, %fpclassify_not_inf ]
+  ret i32 %fpclassify_result
+
+fpclassify_not_zero:
+  %cmp = fcmp uno float %x, 0.000000e+00
+  br i1 %cmp, label %fpclassify_end, label %fpclassify_not_nan
+
+fpclassify_not_nan:
+  %x.abs = tail call float @llvm.fabs.f32(float %x)
+  %isinf = fcmp oeq float %x.abs, 0x7FF0000000000000
+  br i1 %isinf, label %fpclassify_end, label %fpclassify_not_inf
+
+fpclassify_not_inf:
+  %isnormal = fcmp uge float %x.abs, 0x3810000000000000
+  %normal_or_subnormal = select i1 %isnormal, i32 4, i32 3
+  br label %fpclassify_end
+}
+
+declare float @llvm.fabs.f32(float)
+
 attributes #0 = { nounwind argmemonly speculatable }


        


More information about the llvm-commits mailing list