llvm.org GIT mirror llvm / 3a7cf3b
[SimpleLoopUnswitch] partial unswitch needs to be careful when replacing invariants with constants When partial unswitch operates on multiple conditions at once, .e.g: if (Cond1 || Cond2 || NonInv) ... it should infer (and replace) values for individual conditions only on one side of unswitch and not another. More precisely only these derivations hold true: (Cond1 || Cond2) == false => Cond1 == Cond2 == false (Cond1 && Cond2) == true => Cond1 == Cond2 == true By the way we organize unswitching it means only replacing on "continue" blocks and never on "unswitched" ones. Since trivial unswitch does not have "unswitched" blocks it does not have this problem. Fixes PR 39568. Reviewers: chandlerc, asbirlea Differential Revision: https://reviews.llvm.org/D54211 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346350 91177308-0d34-0410-b5e6-96231b3b80d8 Fedor Sergeev 10 months ago
2 changed file(s) with 112 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
20432043 assert(UnswitchedSuccBBs.size() == 1 &&
20442044 "Only one possible unswitched block for a branch!");
20452045 BasicBlock *ClonedPH = ClonedPHs.begin()->second;
2046
2047 // When considering multiple partially-unswitched invariants
2048 // we cant just go replace them with constants in both branches.
2049 //
2050 // For 'AND' we infer that true branch ("continue") means true
2051 // for each invariant operand.
2052 // For 'OR' we can infer that false branch ("continue") means false
2053 // for each invariant operand.
2054 // So it happens that for multiple-partial case we dont replace
2055 // in the unswitched branch.
2056 bool ReplaceUnswitched = FullUnswitch || (Invariants.size() == 1);
2057
20462058 ConstantInt *UnswitchedReplacement =
20472059 Direction ? ConstantInt::getTrue(BI->getContext())
20482060 : ConstantInt::getFalse(BI->getContext());
20622074 // unswitched if in the cloned blocks.
20632075 if (DT.dominates(LoopPH, UserI->getParent()))
20642076 U->set(ContinueReplacement);
2065 else if (DT.dominates(ClonedPH, UserI->getParent()))
2077 else if (ReplaceUnswitched &&
2078 DT.dominates(ClonedPH, UserI->getParent()))
20662079 U->set(UnswitchedReplacement);
20672080 }
20682081 }
27952795 ; CHECK: loop_begin.us:
27962796 ; CHECK-NEXT: %[[V1_US:.*]] = load i1, i1* %ptr1
27972797 ; CHECK-NEXT: %[[V2_US:.*]] = load i1, i1* %ptr2
2798 ; CHECK-NEXT: %[[AND1_US:.*]] = and i1 %[[V1_US]], false
2798 ; CHECK-NEXT: %[[AND1_US:.*]] = and i1 %[[V1_US]], %cond1
27992799 ; CHECK-NEXT: %[[OR1_US:.*]] = or i1 %[[V2_US]], %cond2
28002800 ; CHECK-NEXT: %[[AND2_US:.*]] = and i1 %[[AND1_US]], %[[OR1_US]]
2801 ; CHECK-NEXT: %[[AND3_US:.*]] = and i1 %[[AND2_US]], false
2801 ; CHECK-NEXT: %[[AND3_US:.*]] = and i1 %[[AND2_US]], %cond3
28022802 ; CHECK-NEXT: br label %loop_b.us
28032803 ;
28042804 ; CHECK: loop_b.us:
28562856 ; CHECK-NEXT: ret
28572857 }
28582858
2859 ; Non-trivial partial loop unswitching of multiple invariant inputs to an `or`
2860 ; chain. Basically an inverted version of corresponding `and` test (test26).
2861 define i32 @test27(i1* %ptr1, i1* %ptr2, i1* %ptr3, i1 %cond1, i1 %cond2, i1 %cond3) {
2862 ; CHECK-LABEL: @test27(
2863 entry:
2864 br label %loop_begin
2865 ; CHECK-NEXT: entry:
2866 ; CHECK-NEXT: %[[INV_OR:.*]] = or i1 %cond3, %cond1
2867 ; CHECK-NEXT: br i1 %[[INV_OR]], label %entry.split.us, label %entry.split
2868
2869 loop_begin:
2870 %v1 = load i1, i1* %ptr1
2871 %v2 = load i1, i1* %ptr2
2872 %cond_or1 = or i1 %v1, %cond1
2873 %cond_and1 = and i1 %v2, %cond2
2874 %cond_or2 = or i1 %cond_or1, %cond_and1
2875 %cond_or3 = or i1 %cond_or2, %cond3
2876 br i1 %cond_or3, label %loop_b, label %loop_a
2877 ; The 'loop_b' unswitched loop.
2878 ;
2879 ; CHECK: entry.split.us:
2880 ; CHECK-NEXT: br label %loop_begin.us
2881 ;
2882 ; CHECK: loop_begin.us:
2883 ; CHECK-NEXT: %[[V1_US:.*]] = load i1, i1* %ptr1
2884 ; CHECK-NEXT: %[[V2_US:.*]] = load i1, i1* %ptr2
2885 ; CHECK-NEXT: %[[OR1_US:.*]] = or i1 %[[V1_US]], %cond1
2886 ; CHECK-NEXT: %[[AND1_US:.*]] = and i1 %[[V2_US]], %cond2
2887 ; CHECK-NEXT: %[[OR2_US:.*]] = or i1 %[[OR1_US]], %[[AND1_US]]
2888 ; CHECK-NEXT: %[[OR3_US:.*]] = or i1 %[[OR2_US]], %cond3
2889 ; CHECK-NEXT: br label %loop_b.us
2890 ;
2891 ; CHECK: loop_b.us:
2892 ; CHECK-NEXT: call i32 @b()
2893 ; CHECK-NEXT: br label %latch.us
2894 ;
2895 ; CHECK: latch.us:
2896 ; CHECK-NEXT: %[[V3_US:.*]] = load i1, i1* %ptr3
2897 ; CHECK-NEXT: br i1 %[[V3_US]], label %loop_begin.us, label %loop_exit.split.us
2898 ;
2899 ; CHECK: loop_exit.split.us:
2900 ; CHECK-NEXT: br label %loop_exit
2901
2902 ; The original loop.
2903 ;
2904 ; CHECK: entry.split:
2905 ; CHECK-NEXT: br label %loop_begin
2906 ;
2907 ; CHECK: loop_begin:
2908 ; CHECK-NEXT: %[[V1:.*]] = load i1, i1* %ptr1
2909 ; CHECK-NEXT: %[[V2:.*]] = load i1, i1* %ptr2
2910 ; CHECK-NEXT: %[[OR1:.*]] = or i1 %[[V1]], false
2911 ; CHECK-NEXT: %[[AND1:.*]] = and i1 %[[V2]], %cond2
2912 ; CHECK-NEXT: %[[OR2:.*]] = or i1 %[[OR1]], %[[AND1]]
2913 ; CHECK-NEXT: %[[OR3:.*]] = or i1 %[[OR2]], false
2914 ; CHECK-NEXT: br i1 %[[OR3]], label %loop_b, label %loop_a
2915
2916 loop_a:
2917 call i32 @a()
2918 br label %latch
2919 ; CHECK: loop_a:
2920 ; CHECK-NEXT: call i32 @a()
2921 ; CHECK-NEXT: br label %latch
2922
2923 loop_b:
2924 call i32 @b()
2925 br label %latch
2926 ; CHECK: loop_b:
2927 ; CHECK-NEXT: call i32 @b()
2928 ; CHECK-NEXT: br label %latch
2929
2930 latch:
2931 %v3 = load i1, i1* %ptr3
2932 br i1 %v3, label %loop_begin, label %loop_exit
2933 ; CHECK: latch:
2934 ; CHECK-NEXT: %[[V3:.*]] = load i1, i1* %ptr3
2935 ; CHECK-NEXT: br i1 %[[V3]], label %loop_begin, label %loop_exit.split
2936
2937 loop_exit:
2938 ret i32 0
2939 ; CHECK: loop_exit.split:
2940 ; CHECK-NEXT: br label %loop_exit
2941 ;
2942 ; CHECK: loop_exit:
2943 ; CHECK-NEXT: ret
2944 }
2945
28592946 ; Non-trivial unswitching of a switch.
2860 define i32 @test27(i1* %ptr, i32 %cond) {
2861 ; CHECK-LABEL: @test27(
2947 define i32 @test28(i1* %ptr, i32 %cond) {
2948 ; CHECK-LABEL: @test28(
28622949 entry:
28632950 br label %loop_begin
28642951 ; CHECK-NEXT: entry:
29693056 ; can introduce multiple edges to successors. These need lots of special case
29703057 ; handling as they get collapsed in many cases (domtree, the unswitch itself)
29713058 ; but not in all cases (the PHI node operands).
2972 define i32 @test28(i32 %arg) {
2973 ; CHECK-LABEL: @test28(
3059 define i32 @test29(i32 %arg) {
3060 ; CHECK-LABEL: @test29(
29743061 entry:
29753062 br label %header
29763063 ; CHECK-NEXT: entry:
31483235 ; CHECK-NEXT: ret i32 %[[EXIT_PHI2]]
31493236 }
31503237
3151 ; Similar to @test28 but designed to have one of the duplicate edges be
3238 ; Similar to @test29 but designed to have one of the duplicate edges be
31523239 ; a loop exit edge as those can in some cases be special. Among other things,
31533240 ; this includes an LCSSA phi with multiple entries despite being a dedicated
31543241 ; exit block.
3155 define i32 @test29(i32 %arg) {
3156 ; CHECK-LABEL: define i32 @test29(
3242 define i32 @test30(i32 %arg) {
3243 ; CHECK-LABEL: define i32 @test30(
31573244 entry:
31583245 br label %header
31593246 ; CHECK-NEXT: entry:
39454032 ; viable for unswitching the inner-most loop. This lets us check that the
39464033 ; unswitching doesn't end up cycling infinitely even when the cycle is
39474034 ; indirect and due to revisiting a loop after cloning.
3948 define void @test30(i32 %arg) {
3949 ; CHECK-LABEL: define void @test30(
4035 define void @test31(i32 %arg) {
4036 ; CHECK-LABEL: define void @test31(
39504037 entry:
39514038 br label %outer.header
39524039 ; CHECK-NEXT: entry: