diff --git a/llvm/test/Transforms/IRCE/iv-plus-offset-range-check.ll b/llvm/test/Transforms/IRCE/iv-plus-offset-range-check.ll index cd076d0c10d96..fbab857a2f055 100644 --- a/llvm/test/Transforms/IRCE/iv-plus-offset-range-check.ll +++ b/llvm/test/Transforms/IRCE/iv-plus-offset-range-check.ll @@ -3,7 +3,7 @@ ; IV = 0; IV = 2) -; TODO: IRCE is allowed +; TODO: IRCE is allowed. define i8 @test1(i8 %limit, i8 %n) { ; CHECK-LABEL: define i8 @test1 ; CHECK-SAME: (i8 [[LIMIT:%.*]], i8 [[N:%.*]]) { @@ -54,9 +54,65 @@ out_of_bounds: ret i8 %idx; } +; IV = 0; IV = 2) +; N is known to be non-negative. +; TODO: IRCE is allowed. +define i8 @test1a(i8 %limit, ptr %p) { +; CHECK-LABEL: define i8 @test1a +; CHECK-SAME: (i8 [[LIMIT:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[N:%.*]] = load i8, ptr [[P]], align 1, !range [[RNG0:![0-9]+]] +; CHECK-NEXT: [[PRECHECK:%.*]] = icmp sgt i8 [[LIMIT]], 0 +; CHECK-NEXT: br i1 [[PRECHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ [[IDX_NEXT:%.*]], [[INBOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[N]], [[IDX]] +; CHECK-NEXT: [[CHECK:%.*]] = icmp sge i8 [[SUB]], 2 +; CHECK-NEXT: br i1 [[CHECK]], label [[INBOUNDS]], label [[OUT_OF_BOUNDS:%.*]] +; CHECK: inbounds: +; CHECK-NEXT: [[IDX_NEXT]] = add nuw i8 [[IDX]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[IDX_NEXT]], [[LIMIT]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK: exit.loopexit: +; CHECK-NEXT: [[IDX_LCSSA1:%.*]] = phi i8 [ [[IDX]], [[INBOUNDS]] ] +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: [[RES:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IDX_LCSSA1]], [[EXIT_LOOPEXIT]] ] +; CHECK-NEXT: ret i8 [[RES]] +; CHECK: out_of_bounds: +; CHECK-NEXT: [[IDX_LCSSA:%.*]] = phi i8 [ [[IDX]], [[LOOP]] ] +; CHECK-NEXT: ret i8 [[IDX_LCSSA]] +; +entry: + %n = load i8, ptr %p, !range !0 + %precheck = icmp sgt i8 %limit, 0 + br i1 %precheck, label %loop, label %exit + +loop: + %idx = phi i8 [ %idx.next, %inbounds ], [ 0, %entry ] + %sub = sub i8 %n, %idx + %check = icmp sge i8 %sub, 2 + br i1 %check, label %inbounds, label %out_of_bounds + +inbounds: + %idx.next = add nuw i8 %idx, 1 + %cmp = icmp slt i8 %idx.next, %limit + br i1 %cmp, label %loop, label %exit + +exit: + %res = phi i8 [ 0, %entry ], [ %idx, %inbounds ] + ret i8 %res + +out_of_bounds: + ret i8 %idx; +} + ; IV = 0; IV 2) +; TODO: IRCE is allowed. +define i8 @test4(i8 %limit, i8 %n) { +; CHECK-LABEL: define i8 @test4 +; CHECK-SAME: (i8 [[LIMIT:%.*]], i8 [[N:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[PRECHECK:%.*]] = icmp sgt i8 [[LIMIT]], 0 +; CHECK-NEXT: br i1 [[PRECHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ [[IDX_NEXT:%.*]], [[INBOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[N]], [[IDX]] +; CHECK-NEXT: [[CHECK:%.*]] = icmp sgt i8 [[SUB]], 2 +; CHECK-NEXT: br i1 [[CHECK]], label [[INBOUNDS]], label [[OUT_OF_BOUNDS:%.*]] +; CHECK: inbounds: +; CHECK-NEXT: [[IDX_NEXT]] = add nuw i8 [[IDX]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[IDX_NEXT]], [[LIMIT]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK: exit.loopexit: +; CHECK-NEXT: [[IDX_LCSSA1:%.*]] = phi i8 [ [[IDX]], [[INBOUNDS]] ] +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: [[RES:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IDX_LCSSA1]], [[EXIT_LOOPEXIT]] ] +; CHECK-NEXT: ret i8 [[RES]] +; CHECK: out_of_bounds: +; CHECK-NEXT: [[IDX_LCSSA:%.*]] = phi i8 [ [[IDX]], [[LOOP]] ] +; CHECK-NEXT: ret i8 [[IDX_LCSSA]] +; +entry: + %precheck = icmp sgt i8 %limit, 0 + br i1 %precheck, label %loop, label %exit + +loop: + %idx = phi i8 [ %idx.next, %inbounds ], [ 0, %entry ] + %sub = sub i8 %n, %idx + %check = icmp sgt i8 %sub, 2 + br i1 %check, label %inbounds, label %out_of_bounds + +inbounds: + %idx.next = add nuw i8 %idx, 1 + %cmp = icmp slt i8 %idx.next, %limit + br i1 %cmp, label %loop, label %exit + +exit: + %res = phi i8 [ 0, %entry ], [ %idx, %inbounds ] + ret i8 %res + +out_of_bounds: + ret i8 %idx; +} + +; IV = 0; IV 2) +; N is known to be non-negative. +; TODO: IRCE is allowed. +define i8 @test4a(i8 %limit, ptr %p) { +; CHECK-LABEL: define i8 @test4a +; CHECK-SAME: (i8 [[LIMIT:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[N:%.*]] = load i8, ptr [[P]], align 1, !range [[RNG0]] +; CHECK-NEXT: [[PRECHECK:%.*]] = icmp sgt i8 [[LIMIT]], 0 +; CHECK-NEXT: br i1 [[PRECHECK]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ [[IDX_NEXT:%.*]], [[INBOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[N]], [[IDX]] +; CHECK-NEXT: [[CHECK:%.*]] = icmp sgt i8 [[SUB]], 2 +; CHECK-NEXT: br i1 [[CHECK]], label [[INBOUNDS]], label [[OUT_OF_BOUNDS:%.*]] +; CHECK: inbounds: +; CHECK-NEXT: [[IDX_NEXT]] = add nuw i8 [[IDX]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[IDX_NEXT]], [[LIMIT]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK: exit.loopexit: +; CHECK-NEXT: [[IDX_LCSSA1:%.*]] = phi i8 [ [[IDX]], [[INBOUNDS]] ] +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: [[RES:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IDX_LCSSA1]], [[EXIT_LOOPEXIT]] ] +; CHECK-NEXT: ret i8 [[RES]] +; CHECK: out_of_bounds: +; CHECK-NEXT: [[IDX_LCSSA:%.*]] = phi i8 [ [[IDX]], [[LOOP]] ] +; CHECK-NEXT: ret i8 [[IDX_LCSSA]] +; +entry: + %n = load i8, ptr %p, !range !0 + %precheck = icmp sgt i8 %limit, 0 + br i1 %precheck, label %loop, label %exit + +loop: + %idx = phi i8 [ %idx.next, %inbounds ], [ 0, %entry ] + %sub = sub i8 %n, %idx + %check = icmp sgt i8 %sub, 2 + br i1 %check, label %inbounds, label %out_of_bounds + +inbounds: + %idx.next = add nuw i8 %idx, 1 + %cmp = icmp slt i8 %idx.next, %limit + br i1 %cmp, label %loop, label %exit + +exit: + %res = phi i8 [ 0, %entry ], [ %idx, %inbounds ] + ret i8 %res + +out_of_bounds: + ret i8 %idx; +} + +; IV = 0; IV