1137995d8SPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 28cf5b69fSNikita Popov; RUN: opt -S -passes="loop-mssa(guard-widening)" -verify-memoryssa < %s | FileCheck %s 3137995d8SPhilip Reames 4137995d8SPhilip Reamesdeclare void @llvm.experimental.guard(i1,...) 5137995d8SPhilip Reames 6137995d8SPhilip Reames@G = external global i32 7137995d8SPhilip Reames 8137995d8SPhilip Reames; Show that we can widen into early checks within a loop, and in the process 9137995d8SPhilip Reames; expose optimization oppurtunities. 10137995d8SPhilip Reamesdefine void @widen_within_loop(i1 %cond_0, i1 %cond_1, i1 %cond_2) { 11137995d8SPhilip Reames; CHECK-LABEL: @widen_within_loop( 12137995d8SPhilip Reames; CHECK-NEXT: entry: 13137995d8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 14137995d8SPhilip Reames; CHECK: loop: 15*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 0, i32* @G, align 4 16137995d8SPhilip Reames; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] 17137995d8SPhilip Reames; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]] 18137995d8SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ] 19*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 1, i32* @G, align 4 20*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 2, i32* @G, align 4 21*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 3, i32* @G, align 4 22137995d8SPhilip Reames; CHECK-NEXT: br label [[LOOP]] 23137995d8SPhilip Reames; 24137995d8SPhilip Reamesentry: 25137995d8SPhilip Reames br label %loop 26137995d8SPhilip Reames 27137995d8SPhilip Reamesloop: 28137995d8SPhilip Reames store i32 0, i32* @G 29137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ] 30137995d8SPhilip Reames store i32 1, i32* @G 31137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ] 32137995d8SPhilip Reames store i32 2, i32* @G 33137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ] 34137995d8SPhilip Reames store i32 3, i32* @G 35137995d8SPhilip Reames br label %loop 36137995d8SPhilip Reames} 37137995d8SPhilip Reames 38137995d8SPhilip Reamesdefine void @widen_into_preheader(i1 %cond_0, i1 %cond_1, i1 %cond_2) { 39137995d8SPhilip Reames; CHECK-LABEL: @widen_into_preheader( 40137995d8SPhilip Reames; CHECK-NEXT: entry: 41*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 0, i32* @G, align 4 42137995d8SPhilip Reames; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]] 43137995d8SPhilip Reames; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]] 44137995d8SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ] 45137995d8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 46137995d8SPhilip Reames; CHECK: loop: 47*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 1, i32* @G, align 4 48*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 2, i32* @G, align 4 49*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 3, i32* @G, align 4 50137995d8SPhilip Reames; CHECK-NEXT: br label [[LOOP]] 51137995d8SPhilip Reames; 52137995d8SPhilip Reamesentry: 53137995d8SPhilip Reames store i32 0, i32* @G 54137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ] 55137995d8SPhilip Reames br label %loop 56137995d8SPhilip Reames 57137995d8SPhilip Reamesloop: 58137995d8SPhilip Reames store i32 1, i32* @G 59137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ] 60137995d8SPhilip Reames store i32 2, i32* @G 61137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ] 62137995d8SPhilip Reames store i32 3, i32* @G 63137995d8SPhilip Reames br label %loop 64137995d8SPhilip Reames} 65137995d8SPhilip Reames 66137995d8SPhilip Reamesdefine void @dont_widen_over_common_exit(i1 %cond_0, i1 %cond_1, i1 %cond_2) { 67137995d8SPhilip Reames; CHECK-LABEL: @dont_widen_over_common_exit( 68137995d8SPhilip Reames; CHECK-NEXT: entry: 69137995d8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 70137995d8SPhilip Reames; CHECK: loop: 71*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 0, i32* @G, align 4 72137995d8SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"(i32 0) ] 73*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 1, i32* @G, align 4 74137995d8SPhilip Reames; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]] 75137995d8SPhilip Reames; CHECK: backedge: 76*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 2, i32* @G, align 4 77137995d8SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_2:%.*]]) [ "deopt"(i32 2) ] 78*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 3, i32* @G, align 4 79137995d8SPhilip Reames; CHECK-NEXT: br label [[LOOP]] 80137995d8SPhilip Reames; CHECK: exit: 81137995d8SPhilip Reames; CHECK-NEXT: ret void 82137995d8SPhilip Reames; 83137995d8SPhilip Reamesentry: 84137995d8SPhilip Reames br label %loop 85137995d8SPhilip Reames 86137995d8SPhilip Reamesloop: 87137995d8SPhilip Reames store i32 0, i32* @G 88137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ] 89137995d8SPhilip Reames store i32 1, i32* @G 90137995d8SPhilip Reames br i1 %cond_1, label %backedge, label %exit 91137995d8SPhilip Reames 92137995d8SPhilip Reamesbackedge: 93137995d8SPhilip Reames store i32 2, i32* @G 94137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ] 95137995d8SPhilip Reames store i32 3, i32* @G 96137995d8SPhilip Reames br label %loop 97137995d8SPhilip Reames 98137995d8SPhilip Reamesexit: 99137995d8SPhilip Reames ret void 100137995d8SPhilip Reames} 101137995d8SPhilip Reames 102137995d8SPhilip Reamesdefine void @widen_over_common_exit_to_ph(i1 %cond_0, i1 %cond_1, i1 %cond_2) { 103137995d8SPhilip Reames; CHECK-LABEL: @widen_over_common_exit_to_ph( 104137995d8SPhilip Reames; CHECK-NEXT: entry: 105*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 0, i32* @G, align 4 106137995d8SPhilip Reames; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_2:%.*]] 107137995d8SPhilip Reames; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"(i32 0) ] 108137995d8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 109137995d8SPhilip Reames; CHECK: loop: 110*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 1, i32* @G, align 4 111137995d8SPhilip Reames; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]] 112137995d8SPhilip Reames; CHECK: backedge: 113*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 2, i32* @G, align 4 114*9ffe1b0aSSerguei Katkov; CHECK-NEXT: store i32 3, i32* @G, align 4 115137995d8SPhilip Reames; CHECK-NEXT: br label [[LOOP]] 116137995d8SPhilip Reames; CHECK: exit: 117137995d8SPhilip Reames; CHECK-NEXT: ret void 118137995d8SPhilip Reames; 119137995d8SPhilip Reamesentry: 120137995d8SPhilip Reames store i32 0, i32* @G 121137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ] 122137995d8SPhilip Reames br label %loop 123137995d8SPhilip Reames 124137995d8SPhilip Reamesloop: 125137995d8SPhilip Reames store i32 1, i32* @G 126137995d8SPhilip Reames br i1 %cond_1, label %backedge, label %exit 127137995d8SPhilip Reames 128137995d8SPhilip Reamesbackedge: 129137995d8SPhilip Reames store i32 2, i32* @G 130137995d8SPhilip Reames call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ] 131137995d8SPhilip Reames store i32 3, i32* @G 132137995d8SPhilip Reames br label %loop 133137995d8SPhilip Reames 134137995d8SPhilip Reamesexit: 135137995d8SPhilip Reames ret void 136137995d8SPhilip Reames} 137137995d8SPhilip Reames 138