Add additional tests showing missed opportunities when using loop guards for reasoning in SCEV, depending on the order the guards appear in the IR.
99 lines
3.7 KiB
LLVM
99 lines
3.7 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt -p indvars -S %s | FileCheck %s
|
|
|
|
declare void @foo()
|
|
|
|
define void @narrow_iv_precondition_order_1(ptr %start, i32 %base, i8 %n) {
|
|
; CHECK-LABEL: define void @narrow_iv_precondition_order_1(
|
|
; CHECK-SAME: ptr [[START:%.*]], i32 [[BASE:%.*]], i8 [[N:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[PRE_0:%.*]] = icmp sgt i32 [[BASE]], 0
|
|
; CHECK-NEXT: br i1 [[PRE_0]], label %[[EXIT:.*]], label %[[PH:.*]]
|
|
; CHECK: [[PH]]:
|
|
; CHECK-NEXT: [[N_EXT:%.*]] = zext i8 [[N]] to i32
|
|
; CHECK-NEXT: [[PRE_1:%.*]] = icmp sgt i32 [[BASE]], [[N_EXT]]
|
|
; CHECK-NEXT: br i1 [[PRE_1]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT]]
|
|
; CHECK: [[LOOP_PREHEADER]]:
|
|
; CHECK-NEXT: br label %[[LOOP:.*]]
|
|
; CHECK: [[LOOP]]:
|
|
; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[GEP:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
|
|
; CHECK-NEXT: call void @foo()
|
|
; CHECK-NEXT: [[END:%.*]] = load i8, ptr [[IV]], align 1
|
|
; CHECK-NEXT: [[END_EXT:%.*]] = zext i8 [[END]] to i32
|
|
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i8, ptr [[IV]], i64 1
|
|
; CHECK-NEXT: [[EC:%.*]] = icmp sgt i32 [[BASE]], [[END_EXT]]
|
|
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
|
|
; CHECK: [[EXIT_LOOPEXIT]]:
|
|
; CHECK-NEXT: br label %[[EXIT]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%pre.0 = icmp sgt i32 %base, 0
|
|
br i1 %pre.0, label %exit, label %ph
|
|
|
|
ph: ; preds = %entry
|
|
%n.ext = zext i8 %n to i32
|
|
%pre.1 = icmp sgt i32 %base, %n.ext
|
|
br i1 %pre.1, label %loop, label %exit
|
|
|
|
loop:
|
|
%iv = phi ptr [ %start, %ph ], [ %gep, %loop ]
|
|
call void @foo()
|
|
%end = load i8, ptr %iv, align 1
|
|
%end.ext = zext i8 %end to i32
|
|
%gep = getelementptr inbounds i8, ptr %iv, i64 1
|
|
%ec = icmp sgt i32 %base, %end.ext
|
|
br i1 %ec, label %loop, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @narrow_iv_precondition_order_2(ptr %start, i32 %base, i8 %n) {
|
|
; CHECK-LABEL: define void @narrow_iv_precondition_order_2(
|
|
; CHECK-SAME: ptr [[START:%.*]], i32 [[BASE:%.*]], i8 [[N:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[N_EXT:%.*]] = zext i8 [[N]] to i32
|
|
; CHECK-NEXT: [[PRE_1:%.*]] = icmp sgt i32 [[BASE]], [[N_EXT]]
|
|
; CHECK-NEXT: br i1 [[PRE_1]], label %[[EXIT:.*]], label %[[PH:.*]]
|
|
; CHECK: [[PH]]:
|
|
; CHECK-NEXT: [[PRE_0:%.*]] = icmp sgt i32 [[BASE]], 0
|
|
; CHECK-NEXT: br i1 [[PRE_0]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT]]
|
|
; CHECK: [[LOOP_PREHEADER]]:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[BASE]] to i8
|
|
; CHECK-NEXT: br label %[[LOOP:.*]]
|
|
; CHECK: [[LOOP]]:
|
|
; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[GEP:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
|
|
; CHECK-NEXT: call void @foo()
|
|
; CHECK-NEXT: [[END:%.*]] = load i8, ptr [[IV]], align 1
|
|
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i8, ptr [[IV]], i64 1
|
|
; CHECK-NEXT: [[EC:%.*]] = icmp ugt i8 [[TMP0]], [[END]]
|
|
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
|
|
; CHECK: [[EXIT_LOOPEXIT]]:
|
|
; CHECK-NEXT: br label %[[EXIT]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%n.ext = zext i8 %n to i32
|
|
%pre.1 = icmp sgt i32 %base, %n.ext
|
|
br i1 %pre.1, label %exit, label %ph
|
|
|
|
ph: ; preds = %entry
|
|
%pre.0 = icmp sgt i32 %base, 0
|
|
br i1 %pre.0, label %loop, label %exit
|
|
|
|
loop:
|
|
%iv = phi ptr [ %start, %ph ], [ %gep, %loop ]
|
|
call void @foo()
|
|
%end = load i8, ptr %iv, align 1
|
|
%end.ext = zext i8 %end to i32
|
|
%gep = getelementptr inbounds i8, ptr %iv, i64 1
|
|
%ec = icmp sgt i32 %base, %end.ext
|
|
br i1 %ec, label %loop, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|