Revert "Don't loop unswitch vector selects" Breaks msan. Details in D138526. This reverts commitbf08973277. This reverts commite479ed90b5.
433 lines
19 KiB
LLVM
433 lines
19 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
|
|
; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s
|
|
|
|
; Non-trivial loop unswitching of select instruction.
|
|
|
|
declare i1 @foo()
|
|
declare i1 @bar(i32)
|
|
|
|
define i32 @basic(i32 %N, i1 %cond, i32 %select_input) {
|
|
; CHECK-LABEL: define i32 @basic
|
|
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]], i32 [[SELECT_INPUT:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ]
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[COND]], i32 [[SELECT_INPUT]], i32 42
|
|
; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[COND1]], [[RES]]
|
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
|
|
; CHECK-NEXT: ret i32 [[RES_LCSSA]]
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.body, %entry
|
|
%res = phi i32 [ 0, %entry ], [ %add, %for.body ]
|
|
%i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
|
%cmp = icmp slt i32 %i, %N
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.body: ; preds = %for.cond
|
|
%cond1 = select i1 %cond, i32 %select_input, i32 42
|
|
%add = add nuw nsw i32 %cond1, %res
|
|
%inc = add nuw nsw i32 %i, 1
|
|
br label %for.cond
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @select_phi_input(i32 %N, i1 %cond) {
|
|
; CHECK-LABEL: define i32 @select_phi_input
|
|
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ]
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[COND]], i32 [[I]], i32 42
|
|
; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[COND1]], [[RES]]
|
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
|
|
; CHECK-NEXT: ret i32 [[RES_LCSSA]]
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.body, %entry
|
|
%res = phi i32 [ 0, %entry ], [ %add, %for.body ]
|
|
%i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
|
%cmp = icmp slt i32 %i, %N
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.body: ; preds = %for.cond
|
|
%cond1 = select i1 %cond, i32 %i, i32 42
|
|
%add = add nuw nsw i32 %cond1, %res
|
|
%inc = add nuw nsw i32 %i, 1
|
|
br label %for.cond
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @basic_cond_noundef(i32 %N, i1 noundef %cond) {
|
|
; CHECK-LABEL: define i32 @basic_cond_noundef
|
|
; CHECK-SAME: (i32 [[N:%.*]], i1 noundef [[COND:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ]
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[COND]], i32 [[I]], i32 42
|
|
; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[COND1]], [[RES]]
|
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
|
|
; CHECK-NEXT: ret i32 [[RES_LCSSA]]
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.body, %entry
|
|
%res = phi i32 [ 0, %entry ], [ %add, %for.body ]
|
|
%i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
|
%cmp = icmp slt i32 %i, %N
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.body: ; preds = %for.cond
|
|
%cond1 = select i1 %cond, i32 %i, i32 42
|
|
%add = add nuw nsw i32 %cond1, %res
|
|
%inc = add nuw nsw i32 %i, 1
|
|
br label %for.cond
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @cond_invariant(i32 %N) {
|
|
; CHECK-LABEL: define i32 @cond_invariant
|
|
; CHECK-SAME: (i32 [[N:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ]
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
|
|
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[COND]], i32 [[I]], i32 42
|
|
; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[COND1]], [[RES]]
|
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
|
|
; CHECK-NEXT: ret i32 [[RES_LCSSA]]
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.body, %entry
|
|
%res = phi i32 [ 0, %entry ], [ %add, %for.body ]
|
|
%i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
|
%cmp = icmp slt i32 %i, %N
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.body: ; preds = %for.cond
|
|
%cond = call i1 @foo()
|
|
%cond1 = select i1 %cond, i32 %i, i32 42
|
|
%add = add nuw nsw i32 %cond1, %res
|
|
%inc = add nuw nsw i32 %i, 1
|
|
br label %for.cond
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @chained_select(i32 %N, i1 %cond, i1 %cond2) {
|
|
; CHECK-LABEL: define i32 @chained_select
|
|
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]], i1 [[COND2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY:%.*]] ]
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[COND]], i32 [[I]], i32 42
|
|
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[COND2]], i32 [[SELECT1]], i32 24
|
|
; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[SELECT2]], [[RES]]
|
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
|
|
; CHECK-NEXT: ret i32 [[RES_LCSSA]]
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.body, %entry
|
|
%res = phi i32 [ 0, %entry ], [ %add, %for.body ]
|
|
%i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
|
%cmp = icmp slt i32 %i, %N
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.body: ; preds = %for.cond
|
|
%select1 = select i1 %cond, i32 %i, i32 42
|
|
%select2 = select i1 %cond2, i32 %select1, i32 24
|
|
%add = add nuw nsw i32 %select2, %res
|
|
%inc = add nuw nsw i32 %i, 1
|
|
br label %for.cond
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @select_in_if(i32 %N, i1 %cond) {
|
|
; CHECK-LABEL: define i32 @select_in_if
|
|
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY_END:%.*]] ]
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY_END]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[I]], 2
|
|
; CHECK-NEXT: [[IF_COND:%.*]] = icmp eq i32 [[UREM]], 0
|
|
; CHECK-NEXT: br i1 [[IF_COND]], label [[FOR_BODY_IF:%.*]], label [[FOR_BODY_END]]
|
|
; CHECK: for.body.if:
|
|
; CHECK-NEXT: [[COND1:%.*]] = select i1 [[COND]], i32 [[I]], i32 42
|
|
; CHECK-NEXT: br label [[FOR_BODY_END]]
|
|
; CHECK: for.body.end:
|
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[COND1]], [[FOR_BODY_IF]] ], [ 24, [[FOR_BODY]] ]
|
|
; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[P]], [[RES]]
|
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
|
|
; CHECK-NEXT: ret i32 [[RES_LCSSA]]
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.body.end, %entry
|
|
%res = phi i32 [ 0, %entry ], [ %add, %for.body.end ]
|
|
%i = phi i32 [ 0, %entry ], [ %inc, %for.body.end ]
|
|
%cmp = icmp slt i32 %i, %N
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.body: ; preds = %for.cond
|
|
%urem = urem i32 %i, 2
|
|
%if.cond = icmp eq i32 %urem, 0
|
|
br i1 %if.cond, label %for.body.if, label %for.body.end
|
|
|
|
for.body.if: ; preds = %for.body
|
|
%cond1 = select i1 %cond, i32 %i, i32 42
|
|
br label %for.body.end
|
|
|
|
for.body.end: ; preds = %for.body, %for.body.if
|
|
%p = phi i32 [ %cond1, %for.body.if ], [ 24, %for.body ]
|
|
%add = add nuw nsw i32 %p, %res
|
|
%inc = add nuw nsw i32 %i, 1
|
|
br label %for.cond
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @select_in_if_else(i32 %N, i1 %cond) {
|
|
; CHECK-LABEL: define i32 @select_in_if_else
|
|
; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY_END:%.*]] ]
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY_END]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[I]], 2
|
|
; CHECK-NEXT: [[IF_COND:%.*]] = icmp eq i32 [[UREM]], 0
|
|
; CHECK-NEXT: br i1 [[IF_COND]], label [[FOR_BODY_IF:%.*]], label [[FOR_BODY_ELSE:%.*]]
|
|
; CHECK: for.body.if:
|
|
; CHECK-NEXT: [[COND1A:%.*]] = select i1 [[COND]], i32 [[I]], i32 42
|
|
; CHECK-NEXT: br label [[FOR_BODY_END]]
|
|
; CHECK: for.body.else:
|
|
; CHECK-NEXT: [[COND1B:%.*]] = select i1 [[COND]], i32 24, i32 [[I]]
|
|
; CHECK-NEXT: br label [[FOR_BODY_END]]
|
|
; CHECK: for.body.end:
|
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[COND1A]], [[FOR_BODY_IF]] ], [ [[COND1B]], [[FOR_BODY_ELSE]] ]
|
|
; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[P]], [[RES]]
|
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_COND]] ]
|
|
; CHECK-NEXT: ret i32 [[RES_LCSSA]]
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.body.end, %entry
|
|
%res = phi i32 [ 0, %entry ], [ %add, %for.body.end ]
|
|
%i = phi i32 [ 0, %entry ], [ %inc, %for.body.end ]
|
|
%cmp = icmp slt i32 %i, %N
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.body: ; preds = %for.cond
|
|
%urem = urem i32 %i, 2
|
|
%if.cond = icmp eq i32 %urem, 0
|
|
br i1 %if.cond, label %for.body.if, label %for.body.else
|
|
|
|
for.body.if: ; preds = %for.body
|
|
%cond1a = select i1 %cond, i32 %i, i32 42
|
|
br label %for.body.end
|
|
|
|
for.body.else: ; preds = %for.body
|
|
%cond1b = select i1 %cond, i32 24, i32 %i
|
|
br label %for.body.end
|
|
|
|
for.body.end: ; preds = %for.body.if, %for.body.else
|
|
%p = phi i32 [ %cond1a, %for.body.if ], [ %cond1b, %for.body.else ]
|
|
%add = add nuw nsw i32 %p, %res
|
|
%inc = add nuw nsw i32 %i, 1
|
|
br label %for.cond
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
ret i32 %res
|
|
}
|
|
|
|
define dso_local void @select_nested_loop(i1 noundef zeroext %cond, i32 noundef %n, i32 noundef %m) {
|
|
; CHECK-LABEL: define dso_local void @select_nested_loop
|
|
; CHECK-SAME: (i1 noundef zeroext [[COND:%.*]], i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP17_NOT:%.*]] = icmp eq i32 [[N]], 0
|
|
; CHECK-NEXT: [[CMP215_NOT:%.*]] = icmp eq i32 [[M]], 0
|
|
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP17_NOT]], [[CMP215_NOT]]
|
|
; CHECK-NEXT: br i1 [[OR_COND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
|
|
; CHECK: for.cond1.preheader.us.preheader:
|
|
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
|
|
; CHECK: for.cond1.preheader.us:
|
|
; CHECK-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC7_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
|
|
; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
|
|
; CHECK: for.body4.us:
|
|
; CHECK-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
|
|
; CHECK-NEXT: [[COND5_US:%.*]] = select i1 [[COND]], i32 [[I_018_US]], i32 [[J_016_US]]
|
|
; CHECK-NEXT: tail call void @bar(i32 noundef [[COND5_US]])
|
|
; CHECK-NEXT: [[INC_US]] = add nuw i32 [[J_016_US]], 1
|
|
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC_US]], [[M]]
|
|
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]], label [[FOR_BODY4_US]]
|
|
; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us:
|
|
; CHECK-NEXT: [[INC7_US]] = add nuw i32 [[I_018_US]], 1
|
|
; CHECK-NEXT: [[EXITCOND21_NOT:%.*]] = icmp eq i32 [[INC7_US]], [[N]]
|
|
; CHECK-NEXT: br i1 [[EXITCOND21_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_COND1_PREHEADER_US]]
|
|
; CHECK: for.cond.cleanup.loopexit:
|
|
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%cmp17.not = icmp eq i32 %n, 0
|
|
%cmp215.not = icmp eq i32 %m, 0
|
|
%or.cond = or i1 %cmp17.not, %cmp215.not
|
|
br i1 %or.cond, label %for.cond.cleanup, label %for.cond1.preheader.us
|
|
|
|
for.cond1.preheader.us: ; preds = %entry, %for.cond1.for.cond.cleanup3_crit_edge.us
|
|
%i.018.us = phi i32 [ %inc7.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %entry ]
|
|
br label %for.body4.us
|
|
|
|
for.body4.us: ; preds = %for.cond1.preheader.us, %for.body4.us
|
|
%j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
|
|
%cond5.us = select i1 %cond, i32 %i.018.us, i32 %j.016.us
|
|
tail call void @bar(i32 noundef %cond5.us) #2
|
|
%inc.us = add nuw i32 %j.016.us, 1
|
|
%exitcond.not = icmp eq i32 %inc.us, %m
|
|
br i1 %exitcond.not, label %for.cond1.for.cond.cleanup3_crit_edge.us, label %for.body4.us
|
|
|
|
for.cond1.for.cond.cleanup3_crit_edge.us: ; preds = %for.body4.us
|
|
%inc7.us = add nuw i32 %i.018.us, 1
|
|
%exitcond21.not = icmp eq i32 %inc7.us, %n
|
|
br i1 %exitcond21.not, label %for.cond.cleanup, label %for.cond1.preheader.us
|
|
|
|
for.cond.cleanup: ; preds = %for.cond1.for.cond.cleanup3_crit_edge.us, %entry
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @select_invariant_outer_loop(i1 noundef zeroext %cond, i32 noundef %n, i32 noundef %m) {
|
|
; CHECK-LABEL: define dso_local void @select_invariant_outer_loop
|
|
; CHECK-SAME: (i1 noundef zeroext [[COND:%.*]], i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP20_NOT:%.*]] = icmp eq i32 [[N]], 0
|
|
; CHECK-NEXT: [[CMP218_NOT:%.*]] = icmp eq i32 [[M]], 0
|
|
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP20_NOT]], [[CMP218_NOT]]
|
|
; CHECK-NEXT: br i1 [[OR_COND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
|
|
; CHECK: for.cond1.preheader.us.preheader:
|
|
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
|
|
; CHECK: for.cond1.preheader.us:
|
|
; CHECK-NEXT: [[I_021_US:%.*]] = phi i32 [ [[INC9_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
|
|
; CHECK-NEXT: [[REM_US:%.*]] = and i32 [[I_021_US]], 1
|
|
; CHECK-NEXT: [[CMP5_US:%.*]] = icmp eq i32 [[REM_US]], 0
|
|
; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
|
|
; CHECK: for.body4.us:
|
|
; CHECK-NEXT: [[J_019_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
|
|
; CHECK-NEXT: [[COND7_US:%.*]] = select i1 [[CMP5_US]], i32 [[I_021_US]], i32 [[J_019_US]]
|
|
; CHECK-NEXT: tail call void @bar(i32 noundef [[COND7_US]])
|
|
; CHECK-NEXT: [[INC_US]] = add nuw i32 [[J_019_US]], 1
|
|
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC_US]], [[M]]
|
|
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]], label [[FOR_BODY4_US]]
|
|
; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us:
|
|
; CHECK-NEXT: [[INC9_US]] = add nuw i32 [[I_021_US]], 1
|
|
; CHECK-NEXT: [[EXITCOND24_NOT:%.*]] = icmp eq i32 [[INC9_US]], [[N]]
|
|
; CHECK-NEXT: br i1 [[EXITCOND24_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_COND1_PREHEADER_US]]
|
|
; CHECK: for.cond.cleanup.loopexit:
|
|
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%cmp20.not = icmp eq i32 %n, 0
|
|
%cmp218.not = icmp eq i32 %m, 0
|
|
%or.cond = or i1 %cmp20.not, %cmp218.not
|
|
br i1 %or.cond, label %for.cond.cleanup, label %for.cond1.preheader.us
|
|
|
|
for.cond1.preheader.us: ; preds = %entry, %for.cond1.for.cond.cleanup3_crit_edge.us
|
|
%i.021.us = phi i32 [ %inc9.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %entry ]
|
|
%rem.us = and i32 %i.021.us, 1
|
|
%cmp5.us = icmp eq i32 %rem.us, 0
|
|
br label %for.body4.us
|
|
|
|
for.body4.us: ; preds = %for.cond1.preheader.us, %for.body4.us
|
|
%j.019.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
|
|
%cond7.us = select i1 %cmp5.us, i32 %i.021.us, i32 %j.019.us
|
|
tail call void @bar(i32 noundef %cond7.us) #2
|
|
%inc.us = add nuw i32 %j.019.us, 1
|
|
%exitcond.not = icmp eq i32 %inc.us, %m
|
|
br i1 %exitcond.not, label %for.cond1.for.cond.cleanup3_crit_edge.us, label %for.body4.us
|
|
|
|
for.cond1.for.cond.cleanup3_crit_edge.us: ; preds = %for.body4.us
|
|
%inc9.us = add nuw i32 %i.021.us, 1
|
|
%exitcond24.not = icmp eq i32 %inc9.us, %n
|
|
br i1 %exitcond24.not, label %for.cond.cleanup, label %for.cond1.preheader.us
|
|
|
|
for.cond.cleanup: ; preds = %for.cond1.for.cond.cleanup3_crit_edge.us, %entry
|
|
ret void
|
|
}
|