Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[LoopVersioning] Add test case with foldable icmp in runtime check.
Test case showing a foldable icmp ('icmp ult i8* [[SCEVGEP1]], [[SCEVGEP1]]'). This can be simplified in a follow-up change.
- Loading branch information
Showing
1 changed file
with
48 additions
and
0 deletions.
There are no files selected for viewing
48 changes: 48 additions & 0 deletions
48
llvm/test/Transforms/LoopVersioning/bound-check-partially-known.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
; RUN: opt -aa-pipeline=basic-aa -passes=loop-versioning -S %s | FileCheck %s | ||
|
||
%struct.foo = type { [32000 x double], [32000 x double] } | ||
|
||
@global = external global %struct.foo, align 32 | ||
|
||
define void @bound_check_partially_known_1(i32 %N) { | ||
; CHECK-LABEL: @bound_check_partially_known_1( | ||
; CHECK-NEXT: loop.lver.check: | ||
; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64 | ||
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr [[STRUCT_FOO:%.*]], %struct.foo* @global, i64 0, i32 0, i64 [[N_EXT]] | ||
; CHECK-NEXT: [[SCEVGEP1:%.*]] = bitcast double* [[SCEVGEP]] to i8* | ||
; CHECK-NEXT: [[TMP0:%.*]] = shl nuw nsw i64 [[N_EXT]], 1 | ||
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr [[STRUCT_FOO]], %struct.foo* @global, i64 0, i32 0, i64 [[TMP0]] | ||
; CHECK-NEXT: [[SCEVGEP23:%.*]] = bitcast double* [[SCEVGEP2]] to i8* | ||
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[N_EXT]], 32000 | ||
; CHECK-NEXT: [[SCEVGEP4:%.*]] = getelementptr [[STRUCT_FOO]], %struct.foo* @global, i64 0, i32 0, i64 [[TMP1]] | ||
; CHECK-NEXT: [[SCEVGEP45:%.*]] = bitcast double* [[SCEVGEP4]] to i8* | ||
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[SCEVGEP1]], [[SCEVGEP1]] | ||
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* bitcast (%struct.foo* @global to i8*), [[SCEVGEP23]] | ||
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] | ||
; CHECK-NEXT: [[BOUND06:%.*]] = icmp ult i8* [[SCEVGEP1]], [[SCEVGEP45]] | ||
; CHECK-NEXT: [[BOUND17:%.*]] = icmp ult i8* bitcast (double* getelementptr inbounds ([[STRUCT_FOO]], %struct.foo* @global, i64 0, i32 1, i64 0) to i8*), [[SCEVGEP23]] | ||
; CHECK-NEXT: [[FOUND_CONFLICT8:%.*]] = and i1 [[BOUND06]], [[BOUND17]] | ||
; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT8]] | ||
; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label %loop.ph.lver.orig, label %loop.ph | ||
; | ||
entry: | ||
%N.ext = zext i32 %N to i64 | ||
br label %loop | ||
|
||
loop: | ||
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | ||
%gep.0.iv = getelementptr inbounds %struct.foo, %struct.foo* @global, i64 0, i32 0, i64 %iv | ||
%l.0 = load double, double* %gep.0.iv, align 8 | ||
%gep.1.iv = getelementptr inbounds %struct.foo, %struct.foo* @global, i64 0, i32 1, i64 %iv | ||
%l.1 = load double, double* %gep.1.iv, align 8 | ||
%add = fadd double %l.0, %l.1 | ||
%iv.N = add nuw nsw i64 %iv, %N.ext | ||
%gep.0.iv.N = getelementptr inbounds %struct.foo, %struct.foo* @global, i64 0, i32 0, i64 %iv.N | ||
store double %add, double* %gep.0.iv.N, align 8 | ||
%iv.next = add nuw nsw i64 %iv, 1 | ||
%exitcond = icmp eq i64 %iv.next, %N.ext | ||
br i1 %exitcond, label %exit, label %loop | ||
|
||
exit: | ||
ret void | ||
} |