73 lines
3 KiB
LLVM
73 lines
3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
|
|
; RUN: opt < %s -passes=infer-alignment -S | FileCheck %s
|
|
|
|
; A multi-dimensional array in a nested loop.inner doing vector stores that
|
|
; aren't yet aligned. InferAlignment can understand the addressing in the
|
|
; Nice case to prove 16 byte alignment. In the Awkward case, the inner
|
|
; array dimension is not even, so the stores to it won't always be aligned.
|
|
;
|
|
; InferAlignment should prove alignment in exactly one of the two cases.
|
|
|
|
@Nice = global [1001 x [20000 x double]] zeroinitializer, align 32
|
|
@Awkward = global [1001 x [20001 x double]] zeroinitializer, align 32
|
|
|
|
define void @nested_loop() {
|
|
; CHECK-LABEL: define void @nested_loop() {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP_OUTER:%.*]]
|
|
; CHECK: loop.outer:
|
|
; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_OUTER_TAIL:%.*]] ]
|
|
; CHECK-NEXT: br label [[LOOP_INNER:%.*]]
|
|
; CHECK: loop.inner:
|
|
; CHECK-NEXT: [[J:%.*]] = phi i64 [ 0, [[LOOP_OUTER]] ], [ [[J_NEXT:%.*]], [[LOOP_INNER_TAIL:%.*]] ]
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr [1001 x [20000 x double]], ptr @Nice, i64 0, i64 [[I]], i64 [[J]]
|
|
; CHECK-NEXT: store <2 x double> zeroinitializer, ptr [[GEP_1]], align 16
|
|
; CHECK-NEXT: [[LOAD_1:%.*]] = load <2 x double>, ptr [[GEP_1]], align 16
|
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr [1001 x [20001 x double]], ptr @Awkward, i64 0, i64 [[I]], i64 [[J]]
|
|
; CHECK-NEXT: store <2 x double> zeroinitializer, ptr [[GEP_2]], align 8
|
|
; CHECK-NEXT: [[LOAD_2:%.*]] = load <2 x double>, ptr [[GEP_2]], align 8
|
|
; CHECK-NEXT: br label [[LOOP_INNER_TAIL]]
|
|
; CHECK: loop.inner.tail:
|
|
; CHECK-NEXT: [[J_NEXT]] = add i64 [[J]], 2
|
|
; CHECK-NEXT: [[J_CMP:%.*]] = icmp eq i64 [[J_NEXT]], 556
|
|
; CHECK-NEXT: br i1 [[J_CMP]], label [[LOOP_OUTER_TAIL]], label [[LOOP_INNER]]
|
|
; CHECK: loop.outer.tail:
|
|
; CHECK-NEXT: [[I_NEXT]] = add i64 [[I]], 1
|
|
; CHECK-NEXT: [[I_CMP:%.*]] = icmp eq i64 [[I_NEXT]], 991
|
|
; CHECK-NEXT: br i1 [[I_CMP]], label [[RETURN:%.*]], label [[LOOP_OUTER]]
|
|
; CHECK: return:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.outer
|
|
|
|
loop.outer:
|
|
%i = phi i64 [ 0, %entry ], [ %i.next, %loop.outer.tail ]
|
|
br label %loop.inner
|
|
|
|
loop.inner:
|
|
%j = phi i64 [ 0, %loop.outer ], [ %j.next, %loop.inner.tail ]
|
|
|
|
%gep.1 = getelementptr [1001 x [20000 x double]], ptr @Nice, i64 0, i64 %i, i64 %j
|
|
store <2 x double><double 0.0, double 0.0>, ptr %gep.1, align 8
|
|
%load.1 = load <2 x double>, ptr %gep.1, align 8
|
|
|
|
%gep.2 = getelementptr [1001 x [20001 x double]], ptr @Awkward, i64 0, i64 %i, i64 %j
|
|
store <2 x double><double 0.0, double 0.0>, ptr %gep.2, align 8
|
|
%load.2 = load <2 x double>, ptr %gep.2, align 8
|
|
|
|
br label %loop.inner.tail
|
|
|
|
loop.inner.tail:
|
|
%j.next = add i64 %j, 2
|
|
%j.cmp = icmp eq i64 %j.next, 556
|
|
br i1 %j.cmp, label %loop.outer.tail, label %loop.inner
|
|
|
|
loop.outer.tail:
|
|
%i.next = add i64 %i, 1
|
|
%i.cmp = icmp eq i64 %i.next, 991
|
|
br i1 %i.cmp, label %return, label %loop.outer
|
|
|
|
return:
|
|
ret void
|
|
}
|