CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
864 lines
45 KiB
LLVM
864 lines
45 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
|
|
; RUN: opt -passes='print<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s
|
|
|
|
; Test cases that require rewriting zext SCEV expression with infomration from
|
|
; the loop guards.
|
|
|
|
define void @rewrite_zext(i32 %n) {
|
|
; CHECK-LABEL: 'rewrite_zext'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext
|
|
; CHECK-NEXT: %ext = zext i32 %n to i64
|
|
; CHECK-NEXT: --> (zext i32 %n to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, -8
|
|
; CHECK-NEXT: --> (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> U: [0,4294967289) S: [0,4294967289)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,8}<nuw><nsw><%loop> U: [0,17) S: [0,17) Exits: (-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw nsw i64 %index, 8
|
|
; CHECK-NEXT: --> {8,+,8}<nuw><nsw><%loop> U: [8,25) S: [8,25) Exits: (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%ext = zext i32 %n to i64
|
|
%cmp5 = icmp ule i64 %ext, 24
|
|
br i1 %cmp5, label %check, label %exit
|
|
|
|
check: ; preds = %entry
|
|
%min.iters.check = icmp ult i64 %ext, 8
|
|
%n.vec = and i64 %ext, -8
|
|
br i1 %min.iters.check, label %exit, label %loop
|
|
|
|
loop:
|
|
%index = phi i64 [ 0, %check ], [ %index.next, %loop ]
|
|
%index.next = add nuw nsw i64 %index, 8
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; Test case from PR40961.
|
|
define i32 @rewrite_zext_min_max(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_zext_min_max'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_min_max
|
|
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
|
|
; CHECK-NEXT: --> (16 umin %N) U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %ext = zext i32 %umin to i64
|
|
; CHECK-NEXT: --> (16 umin (zext i32 %N to i64)) U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_min_max
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
|
|
%ext = zext i32 %umin to i64
|
|
%min.iters.check = icmp ult i64 %ext, 4
|
|
br i1 %min.iters.check, label %exit, label %loop.ph
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16) and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
; This is same as rewrite_zext_min_max, but zext and umin are swapped.
|
|
; It should be able to prove the same exit count.
|
|
define i32 @rewrite_min_max_zext(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_min_max_zext'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_min_max_zext
|
|
; CHECK-NEXT: %N.wide = zext i32 %N to i64
|
|
; CHECK-NEXT: --> (zext i32 %N to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %umin = call i64 @llvm.umin.i64(i64 %N.wide, i64 16)
|
|
; CHECK-NEXT: --> (16 umin (zext i32 %N to i64)) U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %n.vec = and i64 %umin, 28
|
|
; CHECK-NEXT: --> (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_min_max_zext
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%N.wide = zext i32 %N to i64
|
|
%umin = call i64 @llvm.umin.i64(i64 %N.wide, i64 16)
|
|
%min.iters.check = icmp ult i64 %umin, 4
|
|
br i1 %min.iters.check, label %exit, label %loop.ph
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %umin, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16) and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
; same as rewrite_zext_min_max, but everything is signed.
|
|
; It should be able to prove the same exit count.
|
|
define i32 @rewrite_sext_min_max(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_sext_min_max'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_sext_min_max
|
|
; CHECK-NEXT: %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
|
|
; CHECK-NEXT: --> (16 smin %N) U: [-2147483648,17) S: [-2147483648,17)
|
|
; CHECK-NEXT: %ext = sext i32 %smin to i64
|
|
; CHECK-NEXT: --> (16 smin (sext i32 %N to i64)) U: [-2147483648,17) S: [-2147483648,17)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nsw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_sext_min_max
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
|
|
%ext = sext i32 %smin to i64
|
|
%min.iters.check = icmp slt i64 %ext, 4
|
|
br i1 %min.iters.check, label %exit, label %loop.ph
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16) and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nsw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
; This is a signed version of rewrite_min_max_zext.
|
|
; It should be able to prove the same exit count.
|
|
define i32 @rewrite_min_max_sext(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_min_max_sext'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_min_max_sext
|
|
; CHECK-NEXT: %N.wide = sext i32 %N to i64
|
|
; CHECK-NEXT: --> (sext i32 %N to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
|
|
; CHECK-NEXT: %smin = call i64 @llvm.smin.i64(i64 %N.wide, i64 16)
|
|
; CHECK-NEXT: --> (16 smin (sext i32 %N to i64)) U: [-2147483648,17) S: [-2147483648,17)
|
|
; CHECK-NEXT: %n.vec = and i64 %smin, 28
|
|
; CHECK-NEXT: --> (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nsw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_min_max_sext
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%N.wide = sext i32 %N to i64
|
|
%smin = call i64 @llvm.smin.i64(i64 %N.wide, i64 16)
|
|
%min.iters.check = icmp slt i64 %smin, 4
|
|
br i1 %min.iters.check, label %exit, label %loop.ph
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %smin, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16) and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nsw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
; Test case from PR52464. applyLoopGuards needs to apply information about %and
|
|
; to %ext, which requires rewriting the zext.
|
|
define i32 @rewrite_zext_with_info_from_icmp_ne(i32 %N) {
|
|
; CHECK-LABEL: 'rewrite_zext_with_info_from_icmp_ne'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_with_info_from_icmp_ne
|
|
; CHECK-NEXT: %and = and i32 %N, 3
|
|
; CHECK-NEXT: --> (zext i2 (trunc i32 %N to i2) to i32) U: [0,4) S: [0,4)
|
|
; CHECK-NEXT: %and.sub.1 = add nsw i32 %and, -1
|
|
; CHECK-NEXT: --> (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> U: [-1,3) S: [-1,3)
|
|
; CHECK-NEXT: %ext = zext i32 %and.sub.1 to i64
|
|
; CHECK-NEXT: --> (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %n.rnd.up = add nuw nsw i64 %ext, 4
|
|
; CHECK-NEXT: --> (4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> U: [4,4294967300) S: [4,4294967300)
|
|
; CHECK-NEXT: %n.vec = and i64 %n.rnd.up, 8589934588
|
|
; CHECK-NEXT: --> (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw> U: [4,4294967297) S: [4,4294967297)
|
|
; CHECK-NEXT: %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,1) S: [0,1) Exits: 0 LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %iv.next = add i64 %iv, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,5) S: [4,5) Exits: 4 LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_with_info_from_icmp_ne
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is i64 0
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 0
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is i64 0
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%and = and i32 %N, 3
|
|
%cmp6.not = icmp eq i32 %and, 0
|
|
br i1 %cmp6.not, label %exit, label %loop.ph
|
|
|
|
loop.ph:
|
|
%and.sub.1 = add nsw i32 %and, -1
|
|
%ext = zext i32 %and.sub.1 to i64
|
|
%n.rnd.up = add nuw nsw i64 %ext, 4
|
|
%n.vec = and i64 %n.rnd.up, 8589934588
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop ]
|
|
%iv.next = add i64 %iv, 4
|
|
call void @use(i64 %iv.next)
|
|
%ec = icmp eq i64 %iv.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
; Similar to @rewrite_zext_with_info_from_icmp_ne, but the loop is not guarded by %and != 0,
|
|
; hence the subsequent subtraction may yield a negative number.
|
|
define i32 @rewrite_zext_no_icmp_ne(i32 %N) {
|
|
; CHECK-LABEL: 'rewrite_zext_no_icmp_ne'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_no_icmp_ne
|
|
; CHECK-NEXT: %and = and i32 %N, 3
|
|
; CHECK-NEXT: --> (zext i2 (trunc i32 %N to i2) to i32) U: [0,4) S: [0,4)
|
|
; CHECK-NEXT: %and.sub.1 = add nsw i32 %and, -1
|
|
; CHECK-NEXT: --> (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> U: [-1,3) S: [-1,3)
|
|
; CHECK-NEXT: %ext = zext i32 %and.sub.1 to i64
|
|
; CHECK-NEXT: --> (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %n.rnd.up = add nuw nsw i64 %ext, 4
|
|
; CHECK-NEXT: --> (4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> U: [4,4294967300) S: [4,4294967300)
|
|
; CHECK-NEXT: %n.vec = and i64 %n.rnd.up, 8589934588
|
|
; CHECK-NEXT: --> (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw> U: [4,4294967297) S: [4,4294967297)
|
|
; CHECK-NEXT: %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,4294967293) S: [0,4294967293) Exits: (-4 + (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %iv.next = add i64 %iv, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,4294967297) S: [4,4294967297) Exits: (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_no_icmp_ne
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 1073741823
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%and = and i32 %N, 3
|
|
br label %loop.ph
|
|
|
|
loop.ph:
|
|
%and.sub.1 = add nsw i32 %and, -1
|
|
%ext = zext i32 %and.sub.1 to i64
|
|
%n.rnd.up = add nuw nsw i64 %ext, 4
|
|
%n.vec = and i64 %n.rnd.up, 8589934588
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop ]
|
|
%iv.next = add i64 %iv, 4
|
|
call void @use(i64 %iv.next)
|
|
%ec = icmp eq i64 %iv.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
; Make sure no information is lost for conditions on both %n and (zext %n).
|
|
define void @rewrite_zext_and_base_1(i32 %n) {
|
|
; CHECK-LABEL: 'rewrite_zext_and_base_1'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_and_base_1
|
|
; CHECK-NEXT: %ext = zext i32 %n to i64
|
|
; CHECK-NEXT: --> (zext i32 %n to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, -8
|
|
; CHECK-NEXT: --> (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> U: [0,4294967289) S: [0,4294967289)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,8}<nuw><nsw><%loop> U: [0,25) S: [0,25) Exits: (-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw nsw i64 %index, 8
|
|
; CHECK-NEXT: --> {8,+,8}<nuw><nsw><%loop> U: [8,33) S: [8,33) Exits: (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_and_base_1
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%ext = zext i32 %n to i64
|
|
%cmp5 = icmp ule i64 %ext, 48
|
|
br i1 %cmp5, label %check.1, label %exit
|
|
|
|
check.1:
|
|
%cmp.2 = icmp ule i32 %n, 32
|
|
br i1 %cmp.2, label %check, label %exit
|
|
|
|
|
|
check: ; preds = %entry
|
|
%min.iters.check = icmp ult i64 %ext, 8
|
|
%n.vec = and i64 %ext, -8
|
|
br i1 %min.iters.check, label %exit, label %loop
|
|
|
|
loop:
|
|
%index = phi i64 [ 0, %check ], [ %index.next, %loop ]
|
|
%index.next = add nuw nsw i64 %index, 8
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; Make sure no information is lost for conditions on both %n and (zext %n).
|
|
define void @rewrite_zext_and_base_2(i32 %n) {
|
|
; CHECK-LABEL: 'rewrite_zext_and_base_2'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_and_base_2
|
|
; CHECK-NEXT: %ext = zext i32 %n to i64
|
|
; CHECK-NEXT: --> (zext i32 %n to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, -8
|
|
; CHECK-NEXT: --> (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> U: [0,4294967289) S: [0,4294967289)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,8}<nuw><nsw><%loop> U: [0,25) S: [0,25) Exits: (-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw nsw i64 %index, 8
|
|
; CHECK-NEXT: --> {8,+,8}<nuw><nsw><%loop> U: [8,33) S: [8,33) Exits: (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_and_base_2
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%ext = zext i32 %n to i64
|
|
%cmp5 = icmp ule i64 %ext, 32
|
|
br i1 %cmp5, label %check.1, label %exit
|
|
|
|
check.1:
|
|
%cmp.2 = icmp ule i32 %n, 48
|
|
br i1 %cmp.2, label %check, label %exit
|
|
|
|
check: ; preds = %entry
|
|
%min.iters.check = icmp ult i64 %ext, 8
|
|
%n.vec = and i64 %ext, -8
|
|
br i1 %min.iters.check, label %exit, label %loop
|
|
|
|
loop:
|
|
%index = phi i64 [ 0, %check ], [ %index.next, %loop ]
|
|
%index.next = add nuw nsw i64 %index, 8
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @guard_pessimizes_analysis_step2(i1 %c, i32 %N) {
|
|
; CHECK-LABEL: 'guard_pessimizes_analysis_step2'
|
|
; CHECK-NEXT: Classifying expressions for: @guard_pessimizes_analysis_step2
|
|
; CHECK-NEXT: %N.ext = zext i32 %N to i64
|
|
; CHECK-NEXT: --> (zext i32 %N to i64) U: [0,4294967296) S: [0,4294967296)
|
|
; CHECK-NEXT: %init = phi i64 [ 2, %entry ], [ 4, %bb1 ]
|
|
; CHECK-NEXT: --> %init U: [2,5) S: [2,5)
|
|
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %init, %loop.ph ]
|
|
; CHECK-NEXT: --> {%init,+,2}<nuw><nsw><%loop> U: [2,17) S: [2,17) Exits: 14 LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %iv.next = add i64 %iv, 2
|
|
; CHECK-NEXT: --> {(2 + %init)<nuw><nsw>,+,2}<nuw><nsw><%loop> U: [4,19) S: [4,19) Exits: 16 LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @guard_pessimizes_analysis_step2
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((14 + (-1 * %init)<nsw>)<nsw> /u 2)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 6
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((14 + (-1 * %init)<nsw>)<nsw> /u 2)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%N.ext = zext i32 %N to i64
|
|
br i1 %c, label %bb1, label %guard
|
|
|
|
bb1:
|
|
br label %guard
|
|
|
|
guard:
|
|
%init = phi i64 [ 2, %entry ], [ 4, %bb1 ]
|
|
%c.1 = icmp ult i64 %init, %N.ext
|
|
br i1 %c.1, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i64 [ %iv.next, %loop ], [ %init, %loop.ph ]
|
|
%iv.next = add i64 %iv, 2
|
|
%exitcond = icmp eq i64 %iv.next, 16
|
|
br i1 %exitcond, label %exit, label %loop
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define i32 @rewrite_sext_slt_narrow_check(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_sext_slt_narrow_check'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_sext_slt_narrow_check
|
|
; CHECK-NEXT: %smin = call i32 @llvm.smax.i32(i32 %N, i32 4)
|
|
; CHECK-NEXT: --> (4 smax %N) U: [4,-2147483648) S: [4,-2147483648)
|
|
; CHECK-NEXT: %ext = sext i32 %smin to i64
|
|
; CHECK-NEXT: --> (zext i32 (4 smax %N) to i64) U: [4,2147483648) S: [4,2147483648)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_sext_slt_narrow_check
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%smin = call i32 @llvm.smax.i32(i32 %N, i32 4)
|
|
%ext = sext i32 %smin to i64
|
|
%min.iters.check = icmp slt i32 %smin, 17
|
|
br i1 %min.iters.check, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16] and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @rewrite_zext_ult_narrow_check(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_zext_ult_narrow_check'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_ult_narrow_check
|
|
; CHECK-NEXT: %umin = call i32 @llvm.umax.i32(i32 %N, i32 4)
|
|
; CHECK-NEXT: --> (4 umax %N) U: [4,0) S: [4,0)
|
|
; CHECK-NEXT: %ext = zext i32 %umin to i64
|
|
; CHECK-NEXT: --> (4 umax (zext i32 %N to i64)) U: [4,4294967296) S: [4,4294967296)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_ult_narrow_check
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%umin = call i32 @llvm.umax.i32(i32 %N, i32 4)
|
|
%ext = zext i32 %umin to i64
|
|
%min.iters.check = icmp ult i32 %umin, 17
|
|
br i1 %min.iters.check, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16] and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @rewrite_zext_ule_narrow_check(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_zext_ule_narrow_check'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_ule_narrow_check
|
|
; CHECK-NEXT: %umin = call i32 @llvm.umax.i32(i32 %N, i32 4)
|
|
; CHECK-NEXT: --> (4 umax %N) U: [4,0) S: [4,0)
|
|
; CHECK-NEXT: %ext = zext i32 %umin to i64
|
|
; CHECK-NEXT: --> (4 umax (zext i32 %N to i64)) U: [4,4294967296) S: [4,4294967296)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_ule_narrow_check
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%umin = call i32 @llvm.umax.i32(i32 %N, i32 4)
|
|
%ext = zext i32 %umin to i64
|
|
%min.iters.check = icmp ule i32 %umin, 16
|
|
br i1 %min.iters.check, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16] and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @rewrite_zext_sle_narrow_check(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_zext_sle_narrow_check'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_sle_narrow_check
|
|
; CHECK-NEXT: %smin = call i32 @llvm.smax.i32(i32 %N, i32 4)
|
|
; CHECK-NEXT: --> (4 smax %N) U: [4,-2147483648) S: [4,-2147483648)
|
|
; CHECK-NEXT: %ext = sext i32 %smin to i64
|
|
; CHECK-NEXT: --> (zext i32 (4 smax %N) to i64) U: [4,2147483648) S: [4,2147483648)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_sle_narrow_check
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%smin = call i32 @llvm.smax.i32(i32 %N, i32 4)
|
|
%ext = sext i32 %smin to i64
|
|
%min.iters.check = icmp sle i32 %smin, 17
|
|
br i1 %min.iters.check, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16] and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @rewrite_zext_uge_narrow_check(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_zext_uge_narrow_check'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_uge_narrow_check
|
|
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
|
|
; CHECK-NEXT: --> (16 umin %N) U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %ext = zext i32 %umin to i64
|
|
; CHECK-NEXT: --> (16 umin (zext i32 %N to i64)) U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_uge_narrow_check
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
|
|
%ext = zext i32 %umin to i64
|
|
%min.iters.check = icmp uge i32 %umin, 4
|
|
br i1 %min.iters.check, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16] and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @rewrite_sext_sge_narrow_check(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_sext_sge_narrow_check'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_sext_sge_narrow_check
|
|
; CHECK-NEXT: %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
|
|
; CHECK-NEXT: --> (16 smin %N) U: [-2147483648,17) S: [-2147483648,17)
|
|
; CHECK-NEXT: %ext = sext i32 %smin to i64
|
|
; CHECK-NEXT: --> (16 smin (sext i32 %N to i64)) U: [-2147483648,17) S: [-2147483648,17)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_sext_sge_narrow_check
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
|
|
%ext = sext i32 %smin to i64
|
|
%min.iters.check = icmp sge i32 %smin, 4
|
|
br i1 %min.iters.check, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16] and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @rewrite_zext_ugt_narrow_check(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_zext_ugt_narrow_check'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_zext_ugt_narrow_check
|
|
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
|
|
; CHECK-NEXT: --> (16 umin %N) U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %ext = zext i32 %umin to i64
|
|
; CHECK-NEXT: --> (16 umin (zext i32 %N to i64)) U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> U: [0,17) S: [0,17)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_zext_ugt_narrow_check
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
|
|
%ext = zext i32 %umin to i64
|
|
%min.iters.check = icmp ugt i32 %umin, 3
|
|
br i1 %min.iters.check, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16] and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @rewrite_sext_sgt_narrow_check(i32 %N, ptr %arr) {
|
|
; CHECK-LABEL: 'rewrite_sext_sgt_narrow_check'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_sext_sgt_narrow_check
|
|
; CHECK-NEXT: %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
|
|
; CHECK-NEXT: --> (16 smin %N) U: [-2147483648,17) S: [-2147483648,17)
|
|
; CHECK-NEXT: %ext = sext i32 %smin to i64
|
|
; CHECK-NEXT: --> (16 smin (sext i32 %N to i64)) U: [-2147483648,17) S: [-2147483648,17)
|
|
; CHECK-NEXT: %n.vec = and i64 %ext, 28
|
|
; CHECK-NEXT: --> (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
|
|
; CHECK-NEXT: %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
; CHECK-NEXT: --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: %index.next = add nuw i64 %index, 4
|
|
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_sext_sgt_narrow_check
|
|
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
|
|
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
|
|
; CHECK-NEXT: Loop %loop: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
|
|
%ext = sext i32 %smin to i64
|
|
%min.iters.check = icmp sgt i32 %smin, 3
|
|
br i1 %min.iters.check, label %loop.ph, label %exit
|
|
|
|
loop.ph:
|
|
%n.vec = and i64 %ext, 28
|
|
br label %loop
|
|
|
|
; %n.vec is [4, 16) and a multiple of 4.
|
|
loop:
|
|
%index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
|
|
%gep = getelementptr inbounds i32, ptr %arr, i64 %index
|
|
store i32 0, ptr %gep
|
|
%index.next = add nuw i64 %index, 4
|
|
%ec = icmp eq i64 %index.next, %n.vec
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|
|
|
|
define void @rewrite_add_rec() {
|
|
; CHECK-LABEL: 'rewrite_add_rec'
|
|
; CHECK-NEXT: Classifying expressions for: @rewrite_add_rec
|
|
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %outer.latch ]
|
|
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%outer.header> U: [0,10) S: [0,10) Exits: 9 LoopDispositions: { %outer.header: Computable, %inner: Invariant }
|
|
; CHECK-NEXT: %sub = sub i64 9, %iv
|
|
; CHECK-NEXT: --> {9,+,-1}<nsw><%outer.header> U: [0,10) S: [0,10) Exits: 0 LoopDispositions: { %outer.header: Computable, %inner: Invariant }
|
|
; CHECK-NEXT: %n.vec = and i64 %sub, -2
|
|
; CHECK-NEXT: --> (2 * ({9,+,-1}<nsw><%outer.header> /u 2))<nuw><nsw> U: [0,9) S: [0,9) Exits: 0 LoopDispositions: { %outer.header: Computable, %inner: Invariant }
|
|
; CHECK-NEXT: %inner.iv = phi i64 [ 0, %inner.ph ], [ %inner.iv.next, %inner ]
|
|
; CHECK-NEXT: --> {0,+,2}<%inner> U: [0,-1) S: [-9223372036854775808,9223372036854775807) Exits: (-2 + (2 * ({9,+,-1}<nsw><%outer.header> /u 2))<nuw><nsw>)<nsw> LoopDispositions: { %inner: Computable, %outer.header: Uniform }
|
|
; CHECK-NEXT: %inner.iv.next = add i64 %inner.iv, 2
|
|
; CHECK-NEXT: --> {2,+,2}<%inner> U: [0,-1) S: [-9223372036854775808,9223372036854775807) Exits: (2 * ({9,+,-1}<nsw><%outer.header> /u 2))<nuw><nsw> LoopDispositions: { %inner: Computable, %outer.header: Uniform }
|
|
; CHECK-NEXT: %iv.next = add i64 %iv, 1
|
|
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%outer.header> U: [1,11) S: [1,11) Exits: 10 LoopDispositions: { %outer.header: Computable, %inner: Invariant }
|
|
; CHECK-NEXT: Determining loop execution counts for: @rewrite_add_rec
|
|
; CHECK-NEXT: Loop %inner: backedge-taken count is ((-2 + (2 * ({9,+,-1}<nsw><%outer.header> /u 2))<nuw><nsw>)<nsw> /u 2)
|
|
; CHECK-NEXT: Loop %inner: constant max backedge-taken count is i64 9223372036854775807
|
|
; CHECK-NEXT: Loop %inner: symbolic max backedge-taken count is ((-2 + (2 * ({9,+,-1}<nsw><%outer.header> /u 2))<nuw><nsw>)<nsw> /u 2)
|
|
; CHECK-NEXT: Loop %inner: Trip multiple is 1
|
|
; CHECK-NEXT: Loop %outer.header: backedge-taken count is i64 9
|
|
; CHECK-NEXT: Loop %outer.header: constant max backedge-taken count is i64 9
|
|
; CHECK-NEXT: Loop %outer.header: symbolic max backedge-taken count is i64 9
|
|
; CHECK-NEXT: Loop %outer.header: Trip multiple is 10
|
|
;
|
|
entry:
|
|
br label %outer.header
|
|
|
|
outer.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %outer.latch ]
|
|
%sub = sub i64 9, %iv
|
|
%min.iters.check = icmp ult i64 %sub, 2
|
|
br i1 %min.iters.check, label %outer.latch, label %inner.ph
|
|
|
|
inner.ph:
|
|
%n.vec = and i64 %sub, -2
|
|
br label %inner
|
|
|
|
inner:
|
|
%inner.iv = phi i64 [ 0, %inner.ph ], [ %inner.iv.next, %inner ]
|
|
%inner.iv.next = add i64 %inner.iv, 2
|
|
call void @use(i64 %inner.iv)
|
|
%ec.inner = icmp eq i64 %inner.iv.next, %n.vec
|
|
br i1 %ec.inner, label %outer.latch, label %inner
|
|
|
|
outer.latch:
|
|
%iv.next = add i64 %iv, 1
|
|
%ec.outer = icmp eq i64 %iv.next, 10
|
|
br i1 %ec.outer, label %exit, label %outer.header
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
declare void @use(i64)
|
|
|
|
declare i32 @llvm.umin.i32(i32, i32)
|
|
declare i64 @llvm.umin.i64(i64, i64)
|
|
declare i32 @llvm.smin.i32(i32, i32)
|
|
declare i64 @llvm.smin.i64(i64, i64)
|
|
|
|
declare i32 @llvm.umax.i32(i32, i32)
|
|
declare i32 @llvm.smax.i32(i32, i32)
|