mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
When emitting the increment operation, SCEVExpander marks the operation as nuw or nsw based on the flags on the preincrement SCEV. This is incorrect because, for instance, it is possible that {-6,+,1} is <nuw> while {-6,+,1}+1 = {-5,+,1} is not. This change teaches SCEV to mark the increment as nuw/nsw only if it can explicitly prove that the increment operation won't overflow. Apart from the attached test case, another (more realistic) manifestation of the bug can be seen in Transforms/IndVarSimplify/pr20680.ll. NOTE: this change was landed with an incorrect commit message in rL230275 and was reverted for that reason in rL230279. This commit message is the correct one. Differential Revision: http://reviews.llvm.org/D7778 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230280 91177308-0d34-0410-b5e6-96231b3b80d8
39 lines
1.7 KiB
LLVM
39 lines
1.7 KiB
LLVM
; RUN: opt -S -loop-reduce < %s | FileCheck %s
|
|
; Scaling factor in addressing mode are costly.
|
|
; Make loop-reduce prefer unscaled accesses.
|
|
; <rdar://problem/13806271>
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64-S128"
|
|
target triple = "arm64-apple-ios7.0.0"
|
|
|
|
; Function Attrs: nounwind ssp
|
|
define void @mulDouble(double* nocapture %a, double* nocapture %b, double* nocapture %c) {
|
|
; CHECK: @mulDouble
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %for.body, %entry
|
|
; CHECK: [[IV:%[^ ]+]] = phi i64 [ [[IVNEXT:%[^,]+]], %for.body ], [ 0, %entry ]
|
|
; Only one induction variable should have been generated.
|
|
; CHECK-NOT: phi
|
|
%indvars.iv = phi i64 [ 1, %entry ], [ %indvars.iv.next, %for.body ]
|
|
%tmp = add nsw i64 %indvars.iv, -1
|
|
%arrayidx = getelementptr inbounds double* %b, i64 %tmp
|
|
%tmp1 = load double* %arrayidx, align 8
|
|
; The induction variable should carry the scaling factor: 1 * 8 = 8.
|
|
; CHECK: [[IVNEXT]] = add nuw nsw i64 [[IV]], 8
|
|
%indvars.iv.next = add i64 %indvars.iv, 1
|
|
%arrayidx2 = getelementptr inbounds double* %c, i64 %indvars.iv.next
|
|
%tmp2 = load double* %arrayidx2, align 8
|
|
%mul = fmul double %tmp1, %tmp2
|
|
%arrayidx4 = getelementptr inbounds double* %a, i64 %indvars.iv
|
|
store double %mul, double* %arrayidx4, align 8
|
|
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
|
|
; Comparison should be 19 * 8 = 152.
|
|
; CHECK: icmp eq i32 {{%[^,]+}}, 152
|
|
%exitcond = icmp eq i32 %lftr.wideiv, 20
|
|
br i1 %exitcond, label %for.end, label %for.body
|
|
|
|
for.end: ; preds = %for.body
|
|
ret void
|
|
}
|