brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · 0719b55 Raw
277 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes='loop-mssa(simple-loop-unswitch)' -S %s | FileCheck %s3 4; Test cases for trivial unswitching with selects that matches both a logical and & or.5 6declare void @some_func()7 8define void @test_select_logical_and_or_with_and_1(i1 noundef %cond1, i1 noundef %cond2) {9; CHECK-LABEL: @test_select_logical_and_or_with_and_1(10; CHECK-NEXT:  entry:11; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]12; CHECK:       loop.header:13; CHECK-NEXT:    [[COND_AND1:%.*]] = and i1 [[COND2:%.*]], [[COND1:%.*]]14; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND_AND1]], i1 true, i1 false15; CHECK-NEXT:    br i1 [[SEL]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]]16; CHECK:       loop.latch:17; CHECK-NEXT:    call void @some_func()18; CHECK-NEXT:    br label [[LOOP_HEADER]]19; CHECK:       exit:20; CHECK-NEXT:    ret void21;22entry:23  br label %loop.header24 25loop.header:26  %cond_and1 = and i1 %cond2, %cond127  %sel = select i1 %cond_and1, i1 true, i1 false28  br i1 %sel, label %exit, label %loop.latch29 30loop.latch:31  call void @some_func()32  br label %loop.header33 34exit:35  ret void36}37 38define void @test_select_logical_and_or_with_and_2(i1 noundef %cond1, i1 noundef %cond2) {39; CHECK-LABEL: @test_select_logical_and_or_with_and_2(40; CHECK-NEXT:  entry:41; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[COND2:%.*]], [[COND1:%.*]]42; CHECK-NEXT:    br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]]43; CHECK:       entry.split:44; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]45; CHECK:       loop.header:46; CHECK-NEXT:    [[COND_AND1:%.*]] = and i1 true, true47; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND_AND1]], i1 true, i1 false48; CHECK-NEXT:    br i1 [[SEL]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]49; CHECK:       loop.latch:50; CHECK-NEXT:    call void @some_func()51; CHECK-NEXT:    br label [[LOOP_HEADER]]52; CHECK:       exit:53; CHECK-NEXT:    br label [[EXIT_SPLIT]]54; CHECK:       exit.split:55; CHECK-NEXT:    ret void56;57entry:58  br label %loop.header59 60loop.header:61  %cond_and1 = and i1 %cond2, %cond162  %sel = select i1 %cond_and1, i1 true, i1 false63  br i1 %sel, label %loop.latch, label %exit64 65loop.latch:66  call void @some_func()67  br label %loop.header68 69exit:70  ret void71}72 73define void @test_select_logical_and_or_with_or_1(i1 noundef %cond1, i1 noundef %cond2) {74; CHECK-LABEL: @test_select_logical_and_or_with_or_1(75; CHECK-NEXT:  entry:76; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND2:%.*]], [[COND1:%.*]]77; CHECK-NEXT:    br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]78; CHECK:       entry.split:79; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]80; CHECK:       loop.header:81; CHECK-NEXT:    [[COND_AND1:%.*]] = or i1 false, false82; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND_AND1]], i1 true, i1 false83; CHECK-NEXT:    br i1 [[SEL]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]]84; CHECK:       loop.latch:85; CHECK-NEXT:    call void @some_func()86; CHECK-NEXT:    br label [[LOOP_HEADER]]87; CHECK:       exit:88; CHECK-NEXT:    br label [[EXIT_SPLIT]]89; CHECK:       exit.split:90; CHECK-NEXT:    ret void91;92entry:93  br label %loop.header94 95loop.header:96  %cond_and1 = or i1 %cond2, %cond197  %sel = select i1 %cond_and1, i1 true, i1 false98  br i1 %sel, label %exit, label %loop.latch99 100loop.latch:101  call void @some_func()102  br label %loop.header103 104exit:105  ret void106}107 108 109define void @test_select_logical_and_or_with_or_2(i1 noundef %cond1, i1 noundef %cond2) {110; CHECK-LABEL: @test_select_logical_and_or_with_or_2(111; CHECK-NEXT:  entry:112; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]113; CHECK:       loop.header:114; CHECK-NEXT:    [[COND_AND1:%.*]] = or i1 [[COND2:%.*]], [[COND1:%.*]]115; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND_AND1]], i1 true, i1 false116; CHECK-NEXT:    br i1 [[SEL]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]117; CHECK:       loop.latch:118; CHECK-NEXT:    call void @some_func()119; CHECK-NEXT:    br label [[LOOP_HEADER]]120; CHECK:       exit:121; CHECK-NEXT:    ret void122;123entry:124  br label %loop.header125 126loop.header:127  %cond_and1 = or i1 %cond2, %cond1128  %sel = select i1 %cond_and1, i1 true, i1 false129  br i1 %sel, label %loop.latch, label %exit130 131loop.latch:132  call void @some_func()133  br label %loop.header134 135exit:136  ret void137}138 139; Check that loop unswitch looks through a combination of or and select instructions.140define i32 @test_partial_condition_unswitch_or_select(ptr %var, i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4, i1 %cond5, i1 %cond6) {141; CHECK-LABEL: @test_partial_condition_unswitch_or_select(142; CHECK-NEXT:  entry:143; CHECK-NEXT:    [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]]144; CHECK-NEXT:    [[COND2_FR:%.*]] = freeze i1 [[COND2:%.*]]145; CHECK-NEXT:    [[COND3_FR:%.*]] = freeze i1 [[COND3:%.*]]146; CHECK-NEXT:    [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]]147; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND4_FR]], [[COND2_FR]]148; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[TMP0]], [[COND3_FR]]149; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[TMP1]], [[COND1_FR]]150; CHECK-NEXT:    br i1 [[TMP2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]151; CHECK:       entry.split:152; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]153; CHECK:       loop_begin:154; CHECK-NEXT:    [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]], align 4155; CHECK-NEXT:    [[VAR_COND:%.*]] = trunc i32 [[VAR_VAL]] to i1156; CHECK-NEXT:    [[COND_OR1:%.*]] = or i1 [[VAR_COND]], false157; CHECK-NEXT:    [[COND_OR2:%.*]] = or i1 false, false158; CHECK-NEXT:    [[COND_OR3:%.*]] = or i1 [[COND_OR1]], [[COND_OR2]]159; CHECK-NEXT:    [[COND_XOR1:%.*]] = xor i1 [[COND5:%.*]], [[VAR_COND]]160; CHECK-NEXT:    [[COND_AND1:%.*]] = and i1 [[COND6:%.*]], [[VAR_COND]]161; CHECK-NEXT:    [[COND_OR4:%.*]] = or i1 [[COND_XOR1]], [[COND_AND1]]162; CHECK-NEXT:    [[COND_OR5:%.*]] = select i1 [[COND_OR3]], i1 true, i1 [[COND_OR4]]163; CHECK-NEXT:    [[COND_OR6:%.*]] = select i1 [[COND_OR5]], i1 true, i1 false164; CHECK-NEXT:    br i1 [[COND_OR6]], label [[LOOP_EXIT:%.*]], label [[DO_SOMETHING:%.*]]165; CHECK:       do_something:166; CHECK-NEXT:    call void @some_func() #[[ATTR0:[0-9]+]]167; CHECK-NEXT:    br label [[LOOP_BEGIN]]168; CHECK:       loop_exit:169; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]170; CHECK:       loop_exit.split:171; CHECK-NEXT:    ret i32 0172;173entry:174  br label %loop_begin175 176loop_begin:177  %var_val = load i32, ptr %var178  %var_cond = trunc i32 %var_val to i1179  %cond_or1 = or i1 %var_cond, %cond1180  %cond_or2 = or i1 %cond2, %cond3181  %cond_or3 = or i1 %cond_or1, %cond_or2182  %cond_xor1 = xor i1 %cond5, %var_cond183  %cond_and1 = and i1 %cond6, %var_cond184  %cond_or4 = or i1 %cond_xor1, %cond_and1185  %cond_or5 = select i1 %cond_or3, i1 true, i1 %cond_or4186  %cond_or6 = select i1 %cond_or5, i1 true, i1 %cond4187  br i1 %cond_or6, label %loop_exit, label %do_something188 189do_something:190  call void @some_func() noreturn nounwind191  br label %loop_begin192 193loop_exit:194  ret i32 0195}196 197; Same as test_partial_condition_unswitch_or_select, but with arguments marked198; as noundef.199define i32 @test_partial_condition_unswitch_or_select_noundef(ptr noundef %var, i1 noundef %cond1, i1 noundef %cond2, i1 noundef %cond3, i1 noundef %cond4, i1 noundef %cond5, i1 noundef %cond6) {200; CHECK-LABEL: @test_partial_condition_unswitch_or_select_noundef(201; CHECK-NEXT:  entry:202; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND2:%.*]]203; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[TMP0]], [[COND3:%.*]]204; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[TMP1]], [[COND1:%.*]]205; CHECK-NEXT:    br i1 [[TMP2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]206; CHECK:       entry.split:207; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]208; CHECK:       loop_begin:209; CHECK-NEXT:    [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]], align 4210; CHECK-NEXT:    [[VAR_COND:%.*]] = trunc i32 [[VAR_VAL]] to i1211; CHECK-NEXT:    [[COND_OR1:%.*]] = or i1 [[VAR_COND]], false212; CHECK-NEXT:    [[COND_OR2:%.*]] = or i1 false, false213; CHECK-NEXT:    [[COND_OR3:%.*]] = or i1 [[COND_OR1]], [[COND_OR2]]214; CHECK-NEXT:    [[COND_XOR1:%.*]] = xor i1 [[COND5:%.*]], [[VAR_COND]]215; CHECK-NEXT:    [[COND_AND1:%.*]] = and i1 [[COND6:%.*]], [[VAR_COND]]216; CHECK-NEXT:    [[COND_OR4:%.*]] = or i1 [[COND_XOR1]], [[COND_AND1]]217; CHECK-NEXT:    [[COND_OR5:%.*]] = select i1 [[COND_OR3]], i1 true, i1 [[COND_OR4]]218; CHECK-NEXT:    [[COND_OR6:%.*]] = select i1 [[COND_OR5]], i1 true, i1 false219; CHECK-NEXT:    br i1 [[COND_OR6]], label [[LOOP_EXIT:%.*]], label [[DO_SOMETHING:%.*]]220; CHECK:       do_something:221; CHECK-NEXT:    call void @some_func() #[[ATTR0]]222; CHECK-NEXT:    br label [[LOOP_BEGIN]]223; CHECK:       loop_exit:224; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]225; CHECK:       loop_exit.split:226; CHECK-NEXT:    ret i32 0227;228entry:229  br label %loop_begin230 231loop_begin:232  %var_val = load i32, ptr %var233  %var_cond = trunc i32 %var_val to i1234  %cond_or1 = or i1 %var_cond, %cond1235  %cond_or2 = or i1 %cond2, %cond3236  %cond_or3 = or i1 %cond_or1, %cond_or2237  %cond_xor1 = xor i1 %cond5, %var_cond238  %cond_and1 = and i1 %cond6, %var_cond239  %cond_or4 = or i1 %cond_xor1, %cond_and1240  %cond_or5 = select i1 %cond_or3, i1 true, i1 %cond_or4241  %cond_or6 = select i1 %cond_or5, i1 true, i1 %cond4242  br i1 %cond_or6, label %loop_exit, label %do_something243 244do_something:245  call void @some_func() noreturn nounwind246  br label %loop_begin247 248loop_exit:249  ret i32 0250}251 252; Test case for PR55526.253define void @test_pr55526(i16 %a) {254; CHECK-LABEL: @test_pr55526(255; CHECK-NEXT:  entry:256; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i16 [[A:%.*]], 0257; CHECK-NEXT:    br i1 [[TOBOOL]], label [[ENTRY_SPLIT:%.*]], label [[EXIT:%.*]]258; CHECK:       entry.split:259; CHECK-NEXT:    br label [[LOOP:%.*]]260; CHECK:       loop:261; CHECK-NEXT:    [[SEL:%.*]] = select i1 true, i1 true, i1 false262; CHECK-NEXT:    br label [[LOOP]]263; CHECK:       exit:264; CHECK-NEXT:    ret void265;266entry:267  %tobool = icmp ne i16 %a, 0268  br label %loop269 270loop:271  %sel = select i1 %tobool, i1 true, i1 false272  br i1 %sel, label %loop, label %exit273 274exit:275  ret void276}277