brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · 64f7e8e Raw
133 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=licm < %s | FileCheck %s3; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s4 5; Make sure we don't hoist the unsafe division to some executable block.6define void @test_impossible_exit_in_untaken_block(i32 %a, i32 %b, ptr %p) {7; CHECK-LABEL: @test_impossible_exit_in_untaken_block(8; CHECK-NEXT:  entry:9; CHECK-NEXT:    br label [[LOOP:%.*]]10; CHECK:       loop:11; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]12; CHECK-NEXT:    br i1 false, label [[NEVER_TAKEN:%.*]], label [[BACKEDGE]]13; CHECK:       never_taken:14; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]15; CHECK-NEXT:    store i32 [[DIV]], ptr [[P:%.*]]16; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[EXIT:%.*]]17; CHECK:       backedge:18; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 119; CHECK-NEXT:    br label [[LOOP]]20; CHECK:       exit:21; CHECK-NEXT:    ret void22;23entry:24  br label %loop25 26loop:27  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]28  br i1 false, label %never_taken, label %backedge29 30never_taken:31  %div = sdiv i32 %a, %b32  store i32 %div, ptr %p33  br i1 true, label %backedge, label %exit34 35backedge:36  %iv.next = add i32 %iv, 137  br label %loop38 39exit:40  ret void41}42 43; The test above is UB in C++, because there is a requirement that any44; thead should eventually terminate, execute volatile access operation, call IO45; or synchronize. In spite of that, the behavior in the test above *might* be46; correct. This one is equivalent to the test above, but it has a volatile47; memory access in the loop's mustexec block, so the compiler no longer has a48; right to assume that it must terminate. Show that the same problem persists,49; and that it was a bug and not a cool optimization based on loop infinity.50; By the moment when this test was added, it was accidentally correct due to51; reasons not directly related to this piece of logic. Make sure that it keeps52; correct in the future.53define void @test_impossible_exit_in_untaken_block_no_ub(i32 %a, i32 %b, ptr noalias %p, ptr noalias %vp) {54; CHECK-LABEL: @test_impossible_exit_in_untaken_block_no_ub(55; CHECK-NEXT:  entry:56; CHECK-NEXT:    br label [[LOOP:%.*]]57; CHECK:       loop:58; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]59; CHECK-NEXT:    [[TMP0:%.*]] = load volatile i32, ptr [[VP:%.*]]60; CHECK-NEXT:    br i1 false, label [[NEVER_TAKEN:%.*]], label [[BACKEDGE]]61; CHECK:       never_taken:62; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]63; CHECK-NEXT:    store i32 [[DIV]], ptr [[P:%.*]]64; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[EXIT:%.*]]65; CHECK:       backedge:66; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 167; CHECK-NEXT:    br label [[LOOP]]68; CHECK:       exit:69; CHECK-NEXT:    ret void70;71entry:72  br label %loop73 74loop:75  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]76  load volatile i32, ptr %vp77  br i1 false, label %never_taken, label %backedge78 79never_taken:80  %div = sdiv i32 %a, %b81  store i32 %div, ptr %p82  br i1 true, label %backedge, label %exit83 84backedge:85  %iv.next = add i32 %iv, 186  br label %loop87 88exit:89  ret void90}91 92; Same as above, but the volatile access is in mustexecute backedge block. The93; loop is no longer "finite by specification", make sure we don't hoist sdiv94; from it no matter how general the MustThrow analysis is.95define void @test_impossible_exit_in_untaken_block_no_ub_2(i32 %a, i32 %b, ptr noalias %p, ptr noalias %vp) {96; CHECK-LABEL: @test_impossible_exit_in_untaken_block_no_ub_2(97; CHECK-NEXT:  entry:98; CHECK-NEXT:    br label [[LOOP:%.*]]99; CHECK:       loop:100; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]101; CHECK-NEXT:    br i1 false, label [[NEVER_TAKEN:%.*]], label [[BACKEDGE]]102; CHECK:       never_taken:103; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]104; CHECK-NEXT:    store i32 [[DIV]], ptr [[P:%.*]]105; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[EXIT:%.*]]106; CHECK:       backedge:107; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1108; CHECK-NEXT:    [[TMP0:%.*]] = load volatile i32, ptr [[VP:%.*]]109; CHECK-NEXT:    br label [[LOOP]]110; CHECK:       exit:111; CHECK-NEXT:    ret void112;113entry:114  br label %loop115 116loop:117  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]118  br i1 false, label %never_taken, label %backedge119 120never_taken:121  %div = sdiv i32 %a, %b122  store i32 %div, ptr %p123  br i1 true, label %backedge, label %exit124 125backedge:126  %iv.next = add i32 %iv, 1127  load volatile i32, ptr %vp128  br label %loop129 130exit:131  ret void132}133