instr-size-costs.ll 18.2 KB
; 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 }