blob: 17ea79bd5dc8be705b2f2a79608e729e0b64d8c6 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes=loop-load-elim -S %s | FileCheck %s
; %stride stride may be poison, if it never executes.
define void @stride_used_conditionally(ptr noalias %a, ptr noalias %b, i64 %stride, i64 %x) {
; CHECK-LABEL: define void @stride_used_conditionally(
; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[STRIDE:%.*]], i64 [[X:%.*]]) {
; CHECK-NEXT: [[LOOP_HEADER_LVER_CHECK:.*:]]
; CHECK-NEXT: [[IDENT_CHECK:%.*]] = icmp ne i64 [[STRIDE]], 1
; CHECK-NEXT: br i1 [[IDENT_CHECK]], label %[[LOOP_HEADER_PH_LVER_ORIG:.*]], label %[[LOOP_HEADER_PH:.*]]
; CHECK: [[LOOP_HEADER_PH_LVER_ORIG]]:
; CHECK-NEXT: br label %[[LOOP_HEADER_LVER_ORIG:.*]]
; CHECK: [[LOOP_HEADER_LVER_ORIG]]:
; CHECK-NEXT: [[IV_LVER_ORIG:%.*]] = phi i64 [ 0, %[[LOOP_HEADER_PH_LVER_ORIG]] ], [ [[IV_NEXT_LVER_ORIG:%.*]], %[[LOOP_LATCH_LVER_ORIG:.*]] ]
; CHECK-NEXT: [[IV_NEXT_LVER_ORIG]] = add nuw nsw i64 [[IV_LVER_ORIG]], 1
; CHECK-NEXT: [[GEP_A_LVER_ORIG:%.*]] = getelementptr i64, ptr [[A]], i64 [[IV_LVER_ORIG]]
; CHECK-NEXT: [[L_A_LVER_ORIG:%.*]] = load i64, ptr [[GEP_A_LVER_ORIG]], align 8
; CHECK-NEXT: [[GEP_A_NEXT_LVER_ORIG:%.*]] = getelementptr i64, ptr [[A]], i64 [[IV_NEXT_LVER_ORIG]]
; CHECK-NEXT: store i64 [[L_A_LVER_ORIG]], ptr [[GEP_A_NEXT_LVER_ORIG]], align 8
; CHECK-NEXT: [[C_LVER_ORIG:%.*]] = icmp sge i64 [[IV_LVER_ORIG]], [[X]]
; CHECK-NEXT: br i1 [[C_LVER_ORIG]], label %[[THEN_LVER_ORIG:.*]], label %[[LOOP_LATCH_LVER_ORIG]]
; CHECK: [[THEN_LVER_ORIG]]:
; CHECK-NEXT: [[IDX_LVER_ORIG:%.*]] = mul i64 [[IV_LVER_ORIG]], [[STRIDE]]
; CHECK-NEXT: [[GEP_A_IDX_LVER_ORIG:%.*]] = getelementptr i64, ptr [[A]], i64 [[IDX_LVER_ORIG]]
; CHECK-NEXT: [[L_A_IDX_LVER_ORIG:%.*]] = load i64, ptr [[GEP_A_IDX_LVER_ORIG]], align 8
; CHECK-NEXT: [[GEP_B_LVER_ORIG:%.*]] = getelementptr i64, ptr [[B]], i64 [[IV_LVER_ORIG]]
; CHECK-NEXT: store i64 [[L_A_IDX_LVER_ORIG]], ptr [[GEP_B_LVER_ORIG]], align 8
; CHECK-NEXT: br label %[[LOOP_LATCH_LVER_ORIG]]
; CHECK: [[LOOP_LATCH_LVER_ORIG]]:
; CHECK-NEXT: [[EC_LVER_ORIG:%.*]] = icmp eq i64 [[IV_NEXT_LVER_ORIG]], 100
; CHECK-NEXT: br i1 [[EC_LVER_ORIG]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP_HEADER_LVER_ORIG]]
; CHECK: [[LOOP_HEADER_PH]]:
; CHECK-NEXT: [[LOAD_INITIAL:%.*]] = load i64, ptr [[A]], align 8
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
; CHECK: [[LOOP_HEADER]]:
; CHECK-NEXT: [[STORE_FORWARDED:%.*]] = phi i64 [ [[LOAD_INITIAL]], %[[LOOP_HEADER_PH]] ], [ [[STORE_FORWARDED]], %[[LOOP_LATCH:.*]] ]
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[LOOP_HEADER_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i64, ptr [[A]], i64 [[IV]]
; CHECK-NEXT: [[L_A:%.*]] = load i64, ptr [[GEP_A]], align 8
; CHECK-NEXT: [[GEP_A_NEXT:%.*]] = getelementptr i64, ptr [[A]], i64 [[IV_NEXT]]
; CHECK-NEXT: store i64 [[STORE_FORWARDED]], ptr [[GEP_A_NEXT]], align 8
; CHECK-NEXT: [[C:%.*]] = icmp sge i64 [[IV]], [[X]]
; CHECK-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[LOOP_LATCH]]
; CHECK: [[THEN]]:
; CHECK-NEXT: [[IDX:%.*]] = mul i64 [[IV]], [[STRIDE]]
; CHECK-NEXT: [[GEP_A_IDX:%.*]] = getelementptr i64, ptr [[A]], i64 [[IDX]]
; CHECK-NEXT: [[L_A_IDX:%.*]] = load i64, ptr [[GEP_A_IDX]], align 8
; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr i64, ptr [[B]], i64 [[IV]]
; CHECK-NEXT: store i64 [[L_A_IDX]], ptr [[GEP_B]], align 8
; CHECK-NEXT: br label %[[LOOP_LATCH]]
; CHECK: [[LOOP_LATCH]]:
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 100
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT1:.*]], label %[[LOOP_HEADER]]
; CHECK: [[EXIT_LOOPEXIT]]:
; CHECK-NEXT: br label %[[EXIT:.*]]
; CHECK: [[EXIT_LOOPEXIT1]]:
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%iv.next = add nuw nsw i64 %iv, 1
%gep.a = getelementptr i64, ptr %a, i64 %iv
%l.a = load i64, ptr %gep.a, align 8
%gep.a.next = getelementptr i64, ptr %a, i64 %iv.next
store i64 %l.a, ptr %gep.a.next, align 8
%c = icmp sge i64 %iv, %x
br i1 %c, label %then, label %loop.latch
then:
%idx = mul i64 %iv, %stride
%gep.a.idx = getelementptr i64, ptr %a, i64 %idx
%l.a.idx = load i64, ptr %gep.a.idx, align 8
%gep.b = getelementptr i64, ptr %b, i64 %iv
store i64 %l.a.idx, ptr %gep.b, align 8
br label %loop.latch
loop.latch:
%ec = icmp eq i64 %iv.next, 100
br i1 %ec, label %exit, label %loop.header
exit:
ret void
}