Sam Parker ea8448e361 [LoopUnroll] Adjust CostKind query
When TTI was updated to use an explicit cost, TCK_CodeSize was used
although the default implicit cost would have been the hand-wavey
cost of size and latency. So, revert back to this behaviour. This is
not expected to have (much) impact on targets since most (all?) of
them return the same value for SizeAndLatency and CodeSize.

When optimising for size, the logic has been changed to query
CodeSize costs instead of SizeAndLatency.

This patch also adds a testing option in the unroller so that
OptSize thresholds can be specified.

Differential Revision: https://reviews.llvm.org/D85723
2020-08-12 12:56:09 +01:00

398 lines
18 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -loop-unroll -unroll-allow-partial -unroll-optsize-threshold=18 -mtriple=thumbv8 -S %s -o - | FileCheck %s --check-prefix=CHECK-V8
define void @test_i32_add_optsize(i32* %a, i32* %b, i32* %c) #0 {
; CHECK-V8-LABEL: @test_i32_add_optsize(
; CHECK-V8-NEXT: entry:
; CHECK-V8-NEXT: br label [[LOOP:%.*]]
; CHECK-V8: loop:
; CHECK-V8-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ADDR_A:%.*]] = getelementptr i32, i32* [[A:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[ADDR_B:%.*]] = getelementptr i32, i32* [[B:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[DATA_A:%.*]] = load i32, i32* [[ADDR_A]], align 4
; CHECK-V8-NEXT: [[DATA_B:%.*]] = load i32, i32* [[ADDR_B]], align 4
; CHECK-V8-NEXT: [[RES:%.*]] = add i32 [[DATA_A]], [[DATA_B]]
; CHECK-V8-NEXT: [[ADDR_C:%.*]] = getelementptr i32, i32* [[C:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: store i32 [[RES]], i32* [[ADDR_C]], align 4
; CHECK-V8-NEXT: [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
; CHECK-V8-NEXT: [[ADDR_A_1:%.*]] = getelementptr i32, i32* [[A]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[ADDR_B_1:%.*]] = getelementptr i32, i32* [[B]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[DATA_A_1:%.*]] = load i32, i32* [[ADDR_A_1]], align 4
; CHECK-V8-NEXT: [[DATA_B_1:%.*]] = load i32, i32* [[ADDR_B_1]], align 4
; CHECK-V8-NEXT: [[RES_1:%.*]] = add i32 [[DATA_A_1]], [[DATA_B_1]]
; CHECK-V8-NEXT: [[ADDR_C_1:%.*]] = getelementptr i32, i32* [[C]], i32 [[COUNT]]
; CHECK-V8-NEXT: store i32 [[RES_1]], i32* [[ADDR_C_1]], align 4
; CHECK-V8-NEXT: [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
; CHECK-V8-NEXT: [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
; CHECK-V8-NEXT: br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-V8: exit:
; CHECK-V8-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %count, %loop ]
%addr.a = getelementptr i32, i32* %a, i32 %iv
%addr.b = getelementptr i32, i32* %b, i32 %iv
%data.a = load i32, i32* %addr.a
%data.b = load i32, i32* %addr.b
%res = add i32 %data.a, %data.b
%addr.c = getelementptr i32, i32* %c, i32 %iv
store i32 %res, i32* %addr.c
%count = add nuw i32 %iv, 1
%end = icmp ne i32 %count, 100
br i1 %end, label %loop, label %exit
exit:
ret void
}
define void @test_i32_add_minsize(i32* %a, i32* %b, i32* %c) #1 {
; CHECK-V8-LABEL: @test_i32_add_minsize(
; CHECK-V8-NEXT: entry:
; CHECK-V8-NEXT: br label [[LOOP:%.*]]
; CHECK-V8: loop:
; CHECK-V8-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ADDR_A:%.*]] = getelementptr i32, i32* [[A:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[ADDR_B:%.*]] = getelementptr i32, i32* [[B:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[DATA_A:%.*]] = load i32, i32* [[ADDR_A]], align 4
; CHECK-V8-NEXT: [[DATA_B:%.*]] = load i32, i32* [[ADDR_B]], align 4
; CHECK-V8-NEXT: [[RES:%.*]] = add i32 [[DATA_A]], [[DATA_B]]
; CHECK-V8-NEXT: [[ADDR_C:%.*]] = getelementptr i32, i32* [[C:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: store i32 [[RES]], i32* [[ADDR_C]], align 4
; CHECK-V8-NEXT: [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
; CHECK-V8-NEXT: [[ADDR_A_1:%.*]] = getelementptr i32, i32* [[A]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[ADDR_B_1:%.*]] = getelementptr i32, i32* [[B]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[DATA_A_1:%.*]] = load i32, i32* [[ADDR_A_1]], align 4
; CHECK-V8-NEXT: [[DATA_B_1:%.*]] = load i32, i32* [[ADDR_B_1]], align 4
; CHECK-V8-NEXT: [[RES_1:%.*]] = add i32 [[DATA_A_1]], [[DATA_B_1]]
; CHECK-V8-NEXT: [[ADDR_C_1:%.*]] = getelementptr i32, i32* [[C]], i32 [[COUNT]]
; CHECK-V8-NEXT: store i32 [[RES_1]], i32* [[ADDR_C_1]], align 4
; CHECK-V8-NEXT: [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
; CHECK-V8-NEXT: [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
; CHECK-V8-NEXT: br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-V8: exit:
; CHECK-V8-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %count, %loop ]
%addr.a = getelementptr i32, i32* %a, i32 %iv
%addr.b = getelementptr i32, i32* %b, i32 %iv
%data.a = load i32, i32* %addr.a
%data.b = load i32, i32* %addr.b
%res = add i32 %data.a, %data.b
%addr.c = getelementptr i32, i32* %c, i32 %iv
store i32 %res, i32* %addr.c
%count = add nuw i32 %iv, 1
%end = icmp ne i32 %count, 100
br i1 %end, label %loop, label %exit
exit:
ret void
}
define void @test_i64_add_optsize(i64* %a, i64* %b, i64* %c) #0 {
; CHECK-V8-LABEL: @test_i64_add_optsize(
; CHECK-V8-NEXT: entry:
; CHECK-V8-NEXT: br label [[LOOP:%.*]]
; CHECK-V8: loop:
; CHECK-V8-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ADDR_A:%.*]] = getelementptr i64, i64* [[A:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[ADDR_B:%.*]] = getelementptr i64, i64* [[B:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[DATA_A:%.*]] = load i64, i64* [[ADDR_A]], align 4
; CHECK-V8-NEXT: [[DATA_B:%.*]] = load i64, i64* [[ADDR_B]], align 4
; CHECK-V8-NEXT: [[RES:%.*]] = add i64 [[DATA_A]], [[DATA_B]]
; CHECK-V8-NEXT: [[ADDR_C:%.*]] = getelementptr i64, i64* [[C:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: store i64 [[RES]], i64* [[ADDR_C]], align 4
; CHECK-V8-NEXT: [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
; CHECK-V8-NEXT: [[ADDR_A_1:%.*]] = getelementptr i64, i64* [[A]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[ADDR_B_1:%.*]] = getelementptr i64, i64* [[B]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[DATA_A_1:%.*]] = load i64, i64* [[ADDR_A_1]], align 4
; CHECK-V8-NEXT: [[DATA_B_1:%.*]] = load i64, i64* [[ADDR_B_1]], align 4
; CHECK-V8-NEXT: [[RES_1:%.*]] = add i64 [[DATA_A_1]], [[DATA_B_1]]
; CHECK-V8-NEXT: [[ADDR_C_1:%.*]] = getelementptr i64, i64* [[C]], i32 [[COUNT]]
; CHECK-V8-NEXT: store i64 [[RES_1]], i64* [[ADDR_C_1]], align 4
; CHECK-V8-NEXT: [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
; CHECK-V8-NEXT: [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
; CHECK-V8-NEXT: br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-V8: exit:
; CHECK-V8-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %count, %loop ]
%addr.a = getelementptr i64, i64* %a, i32 %iv
%addr.b = getelementptr i64, i64* %b, i32 %iv
%data.a = load i64, i64* %addr.a
%data.b = load i64, i64* %addr.b
%res = add i64 %data.a, %data.b
%addr.c = getelementptr i64, i64* %c, i32 %iv
store i64 %res, i64* %addr.c
%count = add nuw i32 %iv, 1
%end = icmp ne i32 %count, 100
br i1 %end, label %loop, label %exit
exit:
ret void
}
define void @test_i64_add_minsize(i64* %a, i64* %b, i64* %c) #1 {
; CHECK-V8-LABEL: @test_i64_add_minsize(
; CHECK-V8-NEXT: entry:
; CHECK-V8-NEXT: br label [[LOOP:%.*]]
; CHECK-V8: loop:
; CHECK-V8-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ADDR_A:%.*]] = getelementptr i64, i64* [[A:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[ADDR_B:%.*]] = getelementptr i64, i64* [[B:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[DATA_A:%.*]] = load i64, i64* [[ADDR_A]], align 4
; CHECK-V8-NEXT: [[DATA_B:%.*]] = load i64, i64* [[ADDR_B]], align 4
; CHECK-V8-NEXT: [[RES:%.*]] = add i64 [[DATA_A]], [[DATA_B]]
; CHECK-V8-NEXT: [[ADDR_C:%.*]] = getelementptr i64, i64* [[C:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: store i64 [[RES]], i64* [[ADDR_C]], align 4
; CHECK-V8-NEXT: [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
; CHECK-V8-NEXT: [[ADDR_A_1:%.*]] = getelementptr i64, i64* [[A]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[ADDR_B_1:%.*]] = getelementptr i64, i64* [[B]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[DATA_A_1:%.*]] = load i64, i64* [[ADDR_A_1]], align 4
; CHECK-V8-NEXT: [[DATA_B_1:%.*]] = load i64, i64* [[ADDR_B_1]], align 4
; CHECK-V8-NEXT: [[RES_1:%.*]] = add i64 [[DATA_A_1]], [[DATA_B_1]]
; CHECK-V8-NEXT: [[ADDR_C_1:%.*]] = getelementptr i64, i64* [[C]], i32 [[COUNT]]
; CHECK-V8-NEXT: store i64 [[RES_1]], i64* [[ADDR_C_1]], align 4
; CHECK-V8-NEXT: [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
; CHECK-V8-NEXT: [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
; CHECK-V8-NEXT: br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-V8: exit:
; CHECK-V8-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %count, %loop ]
%addr.a = getelementptr i64, i64* %a, i32 %iv
%addr.b = getelementptr i64, i64* %b, i32 %iv
%data.a = load i64, i64* %addr.a
%data.b = load i64, i64* %addr.b
%res = add i64 %data.a, %data.b
%addr.c = getelementptr i64, i64* %c, i32 %iv
store i64 %res, i64* %addr.c
%count = add nuw i32 %iv, 1
%end = icmp ne i32 %count, 100
br i1 %end, label %loop, label %exit
exit:
ret void
}
define i32 @test_i32_select_optsize(i32* %a, i32* %b, i32* %c) #0 {
; CHECK-V8-LABEL: @test_i32_select_optsize(
; CHECK-V8-NEXT: entry:
; CHECK-V8-NEXT: br label [[LOOP:%.*]]
; CHECK-V8: loop:
; CHECK-V8-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACC_NEXT_1:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ADDR_A:%.*]] = getelementptr i32, i32* [[A:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[ADDR_B:%.*]] = getelementptr i32, i32* [[B:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[DATA_A:%.*]] = load i32, i32* [[ADDR_A]], align 4
; CHECK-V8-NEXT: [[DATA_B:%.*]] = load i32, i32* [[ADDR_B]], align 4
; CHECK-V8-NEXT: [[UGT:%.*]] = icmp ugt i32 [[DATA_A]], [[DATA_B]]
; CHECK-V8-NEXT: [[UMAX:%.*]] = select i1 [[UGT]], i32 [[DATA_A]], i32 [[DATA_B]]
; CHECK-V8-NEXT: [[ACC_NEXT:%.*]] = add i32 [[UMAX]], [[ACC]]
; CHECK-V8-NEXT: [[ADDR_C:%.*]] = getelementptr i32, i32* [[C:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: store i32 [[UMAX]], i32* [[ADDR_C]], align 4
; CHECK-V8-NEXT: [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
; CHECK-V8-NEXT: [[ADDR_A_1:%.*]] = getelementptr i32, i32* [[A]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[ADDR_B_1:%.*]] = getelementptr i32, i32* [[B]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[DATA_A_1:%.*]] = load i32, i32* [[ADDR_A_1]], align 4
; CHECK-V8-NEXT: [[DATA_B_1:%.*]] = load i32, i32* [[ADDR_B_1]], align 4
; CHECK-V8-NEXT: [[UGT_1:%.*]] = icmp ugt i32 [[DATA_A_1]], [[DATA_B_1]]
; CHECK-V8-NEXT: [[UMAX_1:%.*]] = select i1 [[UGT_1]], i32 [[DATA_A_1]], i32 [[DATA_B_1]]
; CHECK-V8-NEXT: [[ACC_NEXT_1]] = add i32 [[UMAX_1]], [[ACC_NEXT]]
; CHECK-V8-NEXT: [[ADDR_C_1:%.*]] = getelementptr i32, i32* [[C]], i32 [[COUNT]]
; CHECK-V8-NEXT: store i32 [[UMAX_1]], i32* [[ADDR_C_1]], align 4
; CHECK-V8-NEXT: [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
; CHECK-V8-NEXT: [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
; CHECK-V8-NEXT: br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-V8: exit:
; CHECK-V8-NEXT: [[ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[ACC_NEXT_1]], [[LOOP]] ]
; CHECK-V8-NEXT: ret i32 [[ACC_NEXT_LCSSA]]
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %count, %loop ]
%acc = phi i32 [ 0, %entry], [ %acc.next, %loop ]
%addr.a = getelementptr i32, i32* %a, i32 %iv
%addr.b = getelementptr i32, i32* %b, i32 %iv
%data.a = load i32, i32* %addr.a
%data.b = load i32, i32* %addr.b
%ugt = icmp ugt i32 %data.a, %data.b
%umax = select i1 %ugt, i32 %data.a, i32 %data.b
%acc.next = add i32 %umax, %acc
%addr.c = getelementptr i32, i32* %c, i32 %iv
store i32 %umax, i32* %addr.c
%count = add nuw i32 %iv, 1
%end = icmp ne i32 %count, 100
br i1 %end, label %loop, label %exit
exit:
ret i32 %acc.next
}
define i32 @test_i32_select_minsize(i32* %a, i32* %b, i32* %c) #1 {
; CHECK-V8-LABEL: @test_i32_select_minsize(
; CHECK-V8-NEXT: entry:
; CHECK-V8-NEXT: br label [[LOOP:%.*]]
; CHECK-V8: loop:
; CHECK-V8-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACC_NEXT_1:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ADDR_A:%.*]] = getelementptr i32, i32* [[A:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[ADDR_B:%.*]] = getelementptr i32, i32* [[B:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[DATA_A:%.*]] = load i32, i32* [[ADDR_A]], align 4
; CHECK-V8-NEXT: [[DATA_B:%.*]] = load i32, i32* [[ADDR_B]], align 4
; CHECK-V8-NEXT: [[UGT:%.*]] = icmp ugt i32 [[DATA_A]], [[DATA_B]]
; CHECK-V8-NEXT: [[UMAX:%.*]] = select i1 [[UGT]], i32 [[DATA_A]], i32 [[DATA_B]]
; CHECK-V8-NEXT: [[ACC_NEXT:%.*]] = add i32 [[UMAX]], [[ACC]]
; CHECK-V8-NEXT: [[ADDR_C:%.*]] = getelementptr i32, i32* [[C:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: store i32 [[UMAX]], i32* [[ADDR_C]], align 4
; CHECK-V8-NEXT: [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
; CHECK-V8-NEXT: [[ADDR_A_1:%.*]] = getelementptr i32, i32* [[A]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[ADDR_B_1:%.*]] = getelementptr i32, i32* [[B]], i32 [[COUNT]]
; CHECK-V8-NEXT: [[DATA_A_1:%.*]] = load i32, i32* [[ADDR_A_1]], align 4
; CHECK-V8-NEXT: [[DATA_B_1:%.*]] = load i32, i32* [[ADDR_B_1]], align 4
; CHECK-V8-NEXT: [[UGT_1:%.*]] = icmp ugt i32 [[DATA_A_1]], [[DATA_B_1]]
; CHECK-V8-NEXT: [[UMAX_1:%.*]] = select i1 [[UGT_1]], i32 [[DATA_A_1]], i32 [[DATA_B_1]]
; CHECK-V8-NEXT: [[ACC_NEXT_1]] = add i32 [[UMAX_1]], [[ACC_NEXT]]
; CHECK-V8-NEXT: [[ADDR_C_1:%.*]] = getelementptr i32, i32* [[C]], i32 [[COUNT]]
; CHECK-V8-NEXT: store i32 [[UMAX_1]], i32* [[ADDR_C_1]], align 4
; CHECK-V8-NEXT: [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
; CHECK-V8-NEXT: [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
; CHECK-V8-NEXT: br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-V8: exit:
; CHECK-V8-NEXT: [[ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[ACC_NEXT_1]], [[LOOP]] ]
; CHECK-V8-NEXT: ret i32 [[ACC_NEXT_LCSSA]]
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %count, %loop ]
%acc = phi i32 [ 0, %entry], [ %acc.next, %loop ]
%addr.a = getelementptr i32, i32* %a, i32 %iv
%addr.b = getelementptr i32, i32* %b, i32 %iv
%data.a = load i32, i32* %addr.a
%data.b = load i32, i32* %addr.b
%ugt = icmp ugt i32 %data.a, %data.b
%umax = select i1 %ugt, i32 %data.a, i32 %data.b
%acc.next = add i32 %umax, %acc
%addr.c = getelementptr i32, i32* %c, i32 %iv
store i32 %umax, i32* %addr.c
%count = add nuw i32 %iv, 1
%end = icmp ne i32 %count, 100
br i1 %end, label %loop, label %exit
exit:
ret i32 %acc.next
}
define i64 @test_i64_select_optsize(i64* %a, i64* %b, i64* %c) #0 {
; CHECK-V8-LABEL: @test_i64_select_optsize(
; CHECK-V8-NEXT: entry:
; CHECK-V8-NEXT: br label [[LOOP:%.*]]
; CHECK-V8: loop:
; CHECK-V8-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ACC:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[ACC_NEXT:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ADDR_A:%.*]] = getelementptr i64, i64* [[A:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[ADDR_B:%.*]] = getelementptr i64, i64* [[B:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[DATA_A:%.*]] = load i64, i64* [[ADDR_A]], align 4
; CHECK-V8-NEXT: [[DATA_B:%.*]] = load i64, i64* [[ADDR_B]], align 4
; CHECK-V8-NEXT: [[UGT:%.*]] = icmp ugt i64 [[DATA_A]], [[DATA_B]]
; CHECK-V8-NEXT: [[UMAX:%.*]] = select i1 [[UGT]], i64 [[DATA_A]], i64 [[DATA_B]]
; CHECK-V8-NEXT: [[ACC_NEXT]] = add i64 [[UMAX]], [[ACC]]
; CHECK-V8-NEXT: [[ADDR_C:%.*]] = getelementptr i64, i64* [[C:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: store i64 [[UMAX]], i64* [[ADDR_C]], align 4
; CHECK-V8-NEXT: [[COUNT]] = add nuw i32 [[IV]], 1
; CHECK-V8-NEXT: [[END:%.*]] = icmp ne i32 [[COUNT]], 100
; CHECK-V8-NEXT: br i1 [[END]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-V8: exit:
; CHECK-V8-NEXT: [[ACC_NEXT_LCSSA:%.*]] = phi i64 [ [[ACC_NEXT]], [[LOOP]] ]
; CHECK-V8-NEXT: ret i64 [[ACC_NEXT_LCSSA]]
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %count, %loop ]
%acc = phi i64 [ 0, %entry], [ %acc.next, %loop ]
%addr.a = getelementptr i64, i64* %a, i32 %iv
%addr.b = getelementptr i64, i64* %b, i32 %iv
%data.a = load i64, i64* %addr.a
%data.b = load i64, i64* %addr.b
%ugt = icmp ugt i64 %data.a, %data.b
%umax = select i1 %ugt, i64 %data.a, i64 %data.b
%acc.next = add i64 %umax, %acc
%addr.c = getelementptr i64, i64* %c, i32 %iv
store i64 %umax, i64* %addr.c
%count = add nuw i32 %iv, 1
%end = icmp ne i32 %count, 100
br i1 %end, label %loop, label %exit
exit:
ret i64 %acc.next
}
define i64 @test_i64_select_minsize(i64* %a, i64* %b, i64* %c) #1 {
; CHECK-V8-LABEL: @test_i64_select_minsize(
; CHECK-V8-NEXT: entry:
; CHECK-V8-NEXT: br label [[LOOP:%.*]]
; CHECK-V8: loop:
; CHECK-V8-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ACC:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[ACC_NEXT:%.*]], [[LOOP]] ]
; CHECK-V8-NEXT: [[ADDR_A:%.*]] = getelementptr i64, i64* [[A:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[ADDR_B:%.*]] = getelementptr i64, i64* [[B:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: [[DATA_A:%.*]] = load i64, i64* [[ADDR_A]], align 4
; CHECK-V8-NEXT: [[DATA_B:%.*]] = load i64, i64* [[ADDR_B]], align 4
; CHECK-V8-NEXT: [[UGT:%.*]] = icmp ugt i64 [[DATA_A]], [[DATA_B]]
; CHECK-V8-NEXT: [[UMAX:%.*]] = select i1 [[UGT]], i64 [[DATA_A]], i64 [[DATA_B]]
; CHECK-V8-NEXT: [[ACC_NEXT]] = add i64 [[UMAX]], [[ACC]]
; CHECK-V8-NEXT: [[ADDR_C:%.*]] = getelementptr i64, i64* [[C:%.*]], i32 [[IV]]
; CHECK-V8-NEXT: store i64 [[UMAX]], i64* [[ADDR_C]], align 4
; CHECK-V8-NEXT: [[COUNT]] = add nuw i32 [[IV]], 1
; CHECK-V8-NEXT: [[END:%.*]] = icmp ne i32 [[COUNT]], 100
; CHECK-V8-NEXT: br i1 [[END]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK-V8: exit:
; CHECK-V8-NEXT: [[ACC_NEXT_LCSSA:%.*]] = phi i64 [ [[ACC_NEXT]], [[LOOP]] ]
; CHECK-V8-NEXT: ret i64 [[ACC_NEXT_LCSSA]]
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %count, %loop ]
%acc = phi i64 [ 0, %entry], [ %acc.next, %loop ]
%addr.a = getelementptr i64, i64* %a, i32 %iv
%addr.b = getelementptr i64, i64* %b, i32 %iv
%data.a = load i64, i64* %addr.a
%data.b = load i64, i64* %addr.b
%ugt = icmp ugt i64 %data.a, %data.b
%umax = select i1 %ugt, i64 %data.a, i64 %data.b
%acc.next = add i64 %umax, %acc
%addr.c = getelementptr i64, i64* %c, i32 %iv
store i64 %umax, i64* %addr.c
%count = add nuw i32 %iv, 1
%end = icmp ne i32 %count, 100
br i1 %end, label %loop, label %exit
exit:
ret i64 %acc.next
}
attributes #0 = { optsize }
attributes #1 = { minsize optsize }