Nikita Popov d69033d245 [SCEVExpander] Fix GEP IV inc reuse logic for opaque pointers
Instead of checking the pointer type, check the element type of
the GEP.

Previously we ended up reusing GEP increments that were not in
expanded form, thus not respecting LSRs choice of representation.

The change in 2011-10-06-ReusePhi.ll recovers a regression that
appeared when converting that test to opaque pointers.

Changes in various Thumb tests now compute the step outside the
loop instead of using add.w inside the loop, which is LSR's
preferred representation for this target.
2023-07-12 11:32:13 +02:00

73 lines
3.6 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
; RUN: opt -loop-reduce -S < %s | FileCheck %s
;
; Test LSR's intelligence regarding phi reuse.
; Verify that scaled GEPs are not reused. rdar://5064068
target triple = "x86_64-apple-darwin"
; Provide legal integer types.
target datalayout = "n8:16:32:64"
define float @test(ptr nocapture %A, ptr nocapture %B, i32 %N, i32 %IA, i32 %IB) nounwind uwtable readonly ssp {
; CHECK-LABEL: define float @test
; CHECK-SAME: (ptr nocapture [[A:%.*]], ptr nocapture [[B:%.*]], i32 [[N:%.*]], i32 [[IA:%.*]], i32 [[IB:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[N]], 0
; CHECK-NEXT: br i1 [[CMP1]], label [[WHILE_BODY_LR_PH:%.*]], label [[WHILE_END:%.*]]
; CHECK: while.body.lr.ph:
; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[IA]] to i64
; CHECK-NEXT: [[IDX_EXT2:%.*]] = sext i32 [[IB]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = shl nsw i64 [[IDX_EXT]], 2
; CHECK-NEXT: [[TMP1:%.*]] = shl nsw i64 [[IDX_EXT2]], 2
; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
; CHECK: while.body:
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[SCEVGEP2:%.*]], [[WHILE_BODY]] ], [ [[B]], [[WHILE_BODY_LR_PH]] ]
; CHECK-NEXT: [[LSR_IV:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_LR_PH]] ]
; CHECK-NEXT: [[N_ADDR_03:%.*]] = phi i32 [ [[N]], [[WHILE_BODY_LR_PH]] ], [ [[SUB:%.*]], [[WHILE_BODY]] ]
; CHECK-NEXT: [[SUM0_02:%.*]] = phi float [ 0.000000e+00, [[WHILE_BODY_LR_PH]] ], [ [[ADD:%.*]], [[WHILE_BODY]] ]
; CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[LSR_IV]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[LSR_IV1]], align 4
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP2]], [[TMP3]]
; CHECK-NEXT: [[ADD]] = fadd float [[SUM0_02]], [[MUL]]
; CHECK-NEXT: [[SUB]] = add nsw i32 [[N_ADDR_03]], -1
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV]], i64 [[TMP0]]
; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i64 [[TMP1]]
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[SUB]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY]], label [[WHILE_END_LOOPEXIT:%.*]]
; CHECK: while.end.loopexit:
; CHECK-NEXT: br label [[WHILE_END]]
; CHECK: while.end:
; CHECK-NEXT: [[SUM0_0_LCSSA:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[ADD]], [[WHILE_END_LOOPEXIT]] ]
; CHECK-NEXT: ret float [[SUM0_0_LCSSA]]
;
entry:
%cmp1 = icmp sgt i32 %N, 0
br i1 %cmp1, label %while.body.lr.ph, label %while.end
while.body.lr.ph: ; preds = %entry
%idx.ext = sext i32 %IA to i64
%idx.ext2 = sext i32 %IB to i64
br label %while.body
while.body: ; preds = %while.body.lr.ph, %while.body
%A.addr.05 = phi ptr [ %A, %while.body.lr.ph ], [ %add.ptr, %while.body ]
%B.addr.04 = phi ptr [ %B, %while.body.lr.ph ], [ %add.ptr3, %while.body ]
%N.addr.03 = phi i32 [ %N, %while.body.lr.ph ], [ %sub, %while.body ]
%Sum0.02 = phi float [ 0.000000e+00, %while.body.lr.ph ], [ %add, %while.body ]
%0 = load float, ptr %A.addr.05, align 4
%1 = load float, ptr %B.addr.04, align 4
%mul = fmul float %0, %1
%add = fadd float %Sum0.02, %mul
%add.ptr = getelementptr inbounds float, ptr %A.addr.05, i64 %idx.ext
%add.ptr3 = getelementptr inbounds float, ptr %B.addr.04, i64 %idx.ext2
%sub = add nsw i32 %N.addr.03, -1
%cmp = icmp sgt i32 %sub, 0
br i1 %cmp, label %while.body, label %while.end
while.end: ; preds = %while.body, %entry
%Sum0.0.lcssa = phi float [ 0.000000e+00, %entry ], [ %add, %while.body ]
ret float %Sum0.0.lcssa
}