mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-25 14:32:53 +00:00
c7b0b7dc8f
Split sadd.with.overflow into add + sadd.with.overflow to allow analysis and optimization. This should ideally be done after InstCombine, which can perform code motion (eventually indvars should run after all canonical instcombines). We want ISEL to recombine the add and the check, at least on x86. This is currently under an option for reducing live induction variables: -liv-reduce. The next step is reducing liveness of IVs that are live out of the overflow check paths. Once the related optimizations are fully developed, reviewed and tested, I do expect this to become default. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197926 91177308-0d34-0410-b5e6-96231b3b80d8
57 lines
1.6 KiB
LLVM
57 lines
1.6 KiB
LLVM
; RUN: opt < %s -indvars -liv-reduce -S | FileCheck %s
|
|
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-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-apple-macosx"
|
|
|
|
; CHECK-LABEL: @addwithoverflow
|
|
; CHECK-LABEL: loop1:
|
|
; CHECK-NOT: zext
|
|
; CHECK: add nsw
|
|
; CHECK: @llvm.sadd.with.overflow
|
|
; CHECK-LABEL: loop2:
|
|
; CHECK-NOT: extractvalue
|
|
; CHECK: add nuw nsw
|
|
; CHECK: @llvm.sadd.with.overflow
|
|
; CHECK-LABEL: loop3:
|
|
; CHECK-NOT: extractvalue
|
|
; CHECK: ret
|
|
define i64 @addwithoverflow(i32 %n, i64* %a) {
|
|
entry:
|
|
br label %loop0
|
|
|
|
loop0:
|
|
%i = phi i32 [ 0, %entry ], [ %i1val, %loop3 ]
|
|
%s = phi i32 [ 0, %entry ], [ %addsval, %loop3 ]
|
|
%bc = icmp ult i32 %i, %n
|
|
br i1 %bc, label %loop1, label %exit
|
|
|
|
loop1:
|
|
%zxt = zext i32 %i to i64
|
|
%ofs = shl nuw nsw i64 %zxt, 3
|
|
%gep = getelementptr i64* %a, i64 %zxt
|
|
%v = load i64* %gep, align 8
|
|
%truncv = trunc i64 %v to i32
|
|
%adds = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %s, i32 %truncv)
|
|
%ovflows = extractvalue { i32, i1 } %adds, 1
|
|
br i1 %ovflows, label %exit, label %loop2
|
|
|
|
loop2:
|
|
%addsval = extractvalue { i32, i1 } %adds, 0
|
|
%i1 = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i, i32 1)
|
|
%i1check = extractvalue { i32, i1 } %i1, 1
|
|
br i1 %i1check, label %exit, label %loop3
|
|
|
|
loop3:
|
|
%i1val = extractvalue { i32, i1 } %i1, 0
|
|
%test = icmp slt i32 %i1val, %n
|
|
br i1 %test, label %return, label %loop0
|
|
|
|
return:
|
|
%ret = zext i32 %addsval to i64
|
|
ret i64 %ret
|
|
|
|
exit:
|
|
unreachable
|
|
}
|
|
|
|
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
|