Add additional tests showing missed opportunities when using loop guards for reasoning in SCEV, depending on the order the guards appear in the IR.
65 lines
2.9 KiB
LLVM
65 lines
2.9 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
|
|
|
|
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
|
|
target triple = "arm64-apple-macosx15.0.0"
|
|
|
|
define i32 @guards_applied_to_add_rec(ptr %dst) {
|
|
; CHECK-LABEL: define i32 @guards_applied_to_add_rec(
|
|
; CHECK-SAME: ptr [[DST:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*]]:
|
|
; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
|
|
; CHECK: [[OUTER_HEADER]]:
|
|
; CHECK-NEXT: [[OUTER_IV_0:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[OUTER_IV_0_NEXT:%.*]], %[[OUTER_LATCH:.*]] ]
|
|
; CHECK-NEXT: [[OUTER_IV_1:%.*]] = phi i32 [ 1, %[[ENTRY]] ], [ [[OUTER_IV_0]], %[[OUTER_LATCH]] ]
|
|
; CHECK-NEXT: [[SHR28:%.*]] = lshr i32 [[OUTER_IV_1]], 1
|
|
; CHECK-NEXT: [[PRE:%.*]] = icmp samesign ult i32 [[OUTER_IV_1]], 2
|
|
; CHECK-NEXT: br i1 [[PRE]], label %[[OUTER_LATCH]], label %[[INNER_PREHEADER:.*]]
|
|
; CHECK: [[INNER_PREHEADER]]:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[SHR28]] to i64
|
|
; CHECK-NEXT: br label %[[INNER:.*]]
|
|
; CHECK: [[INNER]]:
|
|
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER]] ]
|
|
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i32, ptr [[DST]], i64 [[INDVARS_IV]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
|
|
; CHECK-NEXT: store i32 [[TMP1]], ptr [[GEP_DST]], align 4
|
|
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
|
|
; CHECK-NEXT: [[CMP29:%.*]] = icmp samesign ult i64 [[INDVARS_IV_NEXT]], [[TMP0]]
|
|
; CHECK-NEXT: br i1 [[CMP29]], label %[[INNER]], label %[[OUTER_LATCH_LOOPEXIT:.*]]
|
|
; CHECK: [[OUTER_LATCH_LOOPEXIT]]:
|
|
; CHECK-NEXT: br label %[[OUTER_LATCH]]
|
|
; CHECK: [[OUTER_LATCH]]:
|
|
; CHECK-NEXT: [[OUTER_IV_0_NEXT]] = add nuw i32 [[OUTER_IV_0]], 1
|
|
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[OUTER_IV_0_NEXT]], -2147483647
|
|
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[OUTER_HEADER]], label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
entry:
|
|
br label %outer.header
|
|
|
|
outer.header:
|
|
%outer.iv.0 = phi i32 [ 2, %entry ], [ %outer.iv.0.next, %outer.latch ]
|
|
%outer.iv.1 = phi i32 [ 1, %entry ], [ %outer.iv.0, %outer.latch ]
|
|
%shr28 = lshr i32 %outer.iv.1, 1
|
|
%pre = icmp samesign ult i32 %outer.iv.1, 2
|
|
br i1 %pre, label %outer.latch, label %inner
|
|
|
|
inner:
|
|
%inner.iv = phi i32 [ 0, %outer.header ], [ %inc, %inner ]
|
|
%ext.iv = zext nneg i32 %inner.iv to i64
|
|
%gep.dst = getelementptr i32, ptr %dst, i64 %ext.iv
|
|
store i32 %inner.iv, ptr %gep.dst, align 4
|
|
%inc = add nuw nsw i32 %inner.iv, 1
|
|
%cmp29 = icmp samesign ult i32 %inc, %shr28
|
|
br i1 %cmp29, label %inner, label %outer.latch
|
|
|
|
outer.latch:
|
|
%outer.iv.0.next = add i32 %outer.iv.0, 1
|
|
%outer.ec = icmp sgt i32 %outer.iv.0, 0
|
|
br i1 %outer.ec, label %outer.header, label %exit
|
|
|
|
exit:
|
|
ret i32 0
|
|
}
|