From 8356610f8d48ca7ecbb930dd9b987e4269784710 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Sun, 17 Jan 2021 20:29:13 -0800 Subject: [PATCH] [test] pre commit a couple more tests for vectorizing multiple exit loops --- llvm/test/Transforms/LoopVectorize/loop-form.ll | 134 ++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/llvm/test/Transforms/LoopVectorize/loop-form.ll b/llvm/test/Transforms/LoopVectorize/loop-form.ll index 5b2dd81..9178078 100644 --- a/llvm/test/Transforms/LoopVectorize/loop-form.ll +++ b/llvm/test/Transforms/LoopVectorize/loop-form.ll @@ -588,6 +588,140 @@ if.end2: ret i32 1 } +; LCSSA, common value each exit +define i32 @multiple_exit_blocks2(i16* %p, i32 %n) { +; CHECK-LABEL: @multiple_exit_blocks2( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; 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 [[IF_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[IPROM:%.*]] = sext i32 [[I]] to i64 +; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]] +; CHECK-NEXT: store i16 0, i16* [[B]], align 4 +; CHECK-NEXT: [[INC]] = add nsw i32 [[I]], 1 +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[I]], 2096 +; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]] +; CHECK: if.end: +; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ] +; CHECK-NEXT: ret i32 [[I_LCSSA]] +; CHECK: if.end2: +; CHECK-NEXT: [[I_LCSSA1:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ] +; CHECK-NEXT: ret i32 [[I_LCSSA1]] +; +; TAILFOLD-LABEL: @multiple_exit_blocks2( +; TAILFOLD-NEXT: entry: +; TAILFOLD-NEXT: br label [[FOR_COND:%.*]] +; TAILFOLD: for.cond: +; TAILFOLD-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] +; TAILFOLD-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]] +; TAILFOLD-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]] +; TAILFOLD: for.body: +; TAILFOLD-NEXT: [[IPROM:%.*]] = sext i32 [[I]] to i64 +; TAILFOLD-NEXT: [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]] +; TAILFOLD-NEXT: store i16 0, i16* [[B]], align 4 +; TAILFOLD-NEXT: [[INC]] = add nsw i32 [[I]], 1 +; TAILFOLD-NEXT: [[CMP2:%.*]] = icmp slt i32 [[I]], 2096 +; TAILFOLD-NEXT: br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]] +; TAILFOLD: if.end: +; TAILFOLD-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ] +; TAILFOLD-NEXT: ret i32 [[I_LCSSA]] +; TAILFOLD: if.end2: +; TAILFOLD-NEXT: [[I_LCSSA1:%.*]] = phi i32 [ [[I]], [[FOR_BODY]] ] +; TAILFOLD-NEXT: ret i32 [[I_LCSSA1]] +; +entry: + br label %for.cond + +for.cond: + %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %cmp = icmp slt i32 %i, %n + br i1 %cmp, label %for.body, label %if.end + +for.body: + %iprom = sext i32 %i to i64 + %b = getelementptr inbounds i16, i16* %p, i64 %iprom + store i16 0, i16* %b, align 4 + %inc = add nsw i32 %i, 1 + %cmp2 = icmp slt i32 %i, 2096 + br i1 %cmp2, label %for.cond, label %if.end2 + +if.end: + ret i32 %i + +if.end2: + ret i32 %i +} + +; LCSSA, distinct value each exit +define i32 @multiple_exit_blocks3(i16* %p, i32 %n) { +; CHECK-LABEL: @multiple_exit_blocks3( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; 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 [[IF_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[IPROM:%.*]] = sext i32 [[I]] to i64 +; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]] +; CHECK-NEXT: store i16 0, i16* [[B]], align 4 +; CHECK-NEXT: [[INC]] = add nsw i32 [[I]], 1 +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[I]], 2096 +; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]] +; CHECK: if.end: +; CHECK-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ] +; CHECK-NEXT: ret i32 [[I_LCSSA]] +; CHECK: if.end2: +; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_BODY]] ] +; CHECK-NEXT: ret i32 [[INC_LCSSA]] +; +; TAILFOLD-LABEL: @multiple_exit_blocks3( +; TAILFOLD-NEXT: entry: +; TAILFOLD-NEXT: br label [[FOR_COND:%.*]] +; TAILFOLD: for.cond: +; TAILFOLD-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] +; TAILFOLD-NEXT: [[CMP:%.*]] = icmp slt i32 [[I]], [[N:%.*]] +; TAILFOLD-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[IF_END:%.*]] +; TAILFOLD: for.body: +; TAILFOLD-NEXT: [[IPROM:%.*]] = sext i32 [[I]] to i64 +; TAILFOLD-NEXT: [[B:%.*]] = getelementptr inbounds i16, i16* [[P:%.*]], i64 [[IPROM]] +; TAILFOLD-NEXT: store i16 0, i16* [[B]], align 4 +; TAILFOLD-NEXT: [[INC]] = add nsw i32 [[I]], 1 +; TAILFOLD-NEXT: [[CMP2:%.*]] = icmp slt i32 [[I]], 2096 +; TAILFOLD-NEXT: br i1 [[CMP2]], label [[FOR_COND]], label [[IF_END2:%.*]] +; TAILFOLD: if.end: +; TAILFOLD-NEXT: [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[FOR_COND]] ] +; TAILFOLD-NEXT: ret i32 [[I_LCSSA]] +; TAILFOLD: if.end2: +; TAILFOLD-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_BODY]] ] +; TAILFOLD-NEXT: ret i32 [[INC_LCSSA]] +; +entry: + br label %for.cond + +for.cond: + %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %cmp = icmp slt i32 %i, %n + br i1 %cmp, label %for.body, label %if.end + +for.body: + %iprom = sext i32 %i to i64 + %b = getelementptr inbounds i16, i16* %p, i64 %iprom + store i16 0, i16* %b, align 4 + %inc = add nsw i32 %i, 1 + %cmp2 = icmp slt i32 %i, 2096 + br i1 %cmp2, label %for.cond, label %if.end2 + +if.end: + ret i32 %i + +if.end2: + ret i32 %inc +} + ; unique exit case but with a switch as two edges between the same pair of ; blocks is an often missed edge case define i32 @multiple_exit_switch(i16* %p, i32 %n) { -- 2.7.4