143 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes="loop-mssa(guard-widening)" -verify-memoryssa < %s | FileCheck %s3 4declare void @llvm.experimental.guard(i1,...)5 6@G = external global i327 8; Show that we can widen into early checks within a loop, and in the process9; expose optimization oppurtunities.10define void @widen_within_loop(i1 %cond_0, i1 %cond_1, i1 %cond_2) {11; CHECK-LABEL: @widen_within_loop(12; CHECK-NEXT: entry:13; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2:%.*]]14; CHECK-NEXT: [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]15; CHECK-NEXT: br label [[LOOP:%.*]]16; CHECK: loop:17; CHECK-NEXT: store i32 0, ptr @G, align 418; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]19; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2_GW_FR]]20; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]21; CHECK-NEXT: store i32 1, ptr @G, align 422; CHECK-NEXT: store i32 2, ptr @G, align 423; CHECK-NEXT: store i32 3, ptr @G, align 424; CHECK-NEXT: br label [[LOOP]]25;26entry:27 br label %loop28 29loop:30 store i32 0, ptr @G31 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]32 store i32 1, ptr @G33 call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ]34 store i32 2, ptr @G35 call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]36 store i32 3, ptr @G37 br label %loop38}39 40define void @widen_into_preheader(i1 %cond_0, i1 %cond_1, i1 %cond_2) {41; CHECK-LABEL: @widen_into_preheader(42; CHECK-NEXT: entry:43; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2:%.*]]44; CHECK-NEXT: [[COND_1_GW_FR:%.*]] = freeze i1 [[COND_1:%.*]]45; CHECK-NEXT: store i32 0, ptr @G, align 446; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1_GW_FR]]47; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2_GW_FR]]48; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]49; CHECK-NEXT: br label [[LOOP:%.*]]50; CHECK: loop:51; CHECK-NEXT: store i32 1, ptr @G, align 452; CHECK-NEXT: store i32 2, ptr @G, align 453; CHECK-NEXT: store i32 3, ptr @G, align 454; CHECK-NEXT: br label [[LOOP]]55;56entry:57 store i32 0, ptr @G58 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]59 br label %loop60 61loop:62 store i32 1, ptr @G63 call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ]64 store i32 2, ptr @G65 call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]66 store i32 3, ptr @G67 br label %loop68}69 70define void @dont_widen_over_common_exit(i1 %cond_0, i1 %cond_1, i1 %cond_2) {71; CHECK-LABEL: @dont_widen_over_common_exit(72; CHECK-NEXT: entry:73; CHECK-NEXT: br label [[LOOP:%.*]]74; CHECK: loop:75; CHECK-NEXT: store i32 0, ptr @G, align 476; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"(i32 0) ]77; CHECK-NEXT: store i32 1, ptr @G, align 478; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]]79; CHECK: backedge:80; CHECK-NEXT: store i32 2, ptr @G, align 481; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_2:%.*]]) [ "deopt"(i32 2) ]82; CHECK-NEXT: store i32 3, ptr @G, align 483; CHECK-NEXT: br label [[LOOP]]84; CHECK: exit:85; CHECK-NEXT: ret void86;87entry:88 br label %loop89 90loop:91 store i32 0, ptr @G92 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]93 store i32 1, ptr @G94 br i1 %cond_1, label %backedge, label %exit95 96backedge:97 store i32 2, ptr @G98 call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]99 store i32 3, ptr @G100 br label %loop101 102exit:103 ret void104}105 106define void @widen_over_common_exit_to_ph(i1 %cond_0, i1 %cond_1, i1 %cond_2) {107; CHECK-LABEL: @widen_over_common_exit_to_ph(108; CHECK-NEXT: entry:109; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2:%.*]]110; CHECK-NEXT: store i32 0, ptr @G, align 4111; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_2_GW_FR]]112; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"(i32 0) ]113; CHECK-NEXT: br label [[LOOP:%.*]]114; CHECK: loop:115; CHECK-NEXT: store i32 1, ptr @G, align 4116; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]]117; CHECK: backedge:118; CHECK-NEXT: store i32 2, ptr @G, align 4119; CHECK-NEXT: store i32 3, ptr @G, align 4120; CHECK-NEXT: br label [[LOOP]]121; CHECK: exit:122; CHECK-NEXT: ret void123;124entry:125 store i32 0, ptr @G126 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]127 br label %loop128 129loop:130 store i32 1, ptr @G131 br i1 %cond_1, label %backedge, label %exit132 133backedge:134 store i32 2, ptr @G135 call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]136 store i32 3, ptr @G137 br label %loop138 139exit:140 ret void141}142 143