mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-20 19:04:10 -04:00
bf4a9f7325
If we can detect that saturating math that depends on an IV cannot overflow, replace it with simple math. This is similar to the CVP optimization from D62703, just based on a different underlying analysis (SCEV vs LVI) that catches different cases. Differential Revision: https://reviews.llvm.org/D62792 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363489 91177308-0d34-0410-b5e6-96231b3b80d8
124 lines
3.6 KiB
LLVM
124 lines
3.6 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -S -indvars | FileCheck %s
|
|
|
|
declare i32 @llvm.uadd.sat.i32(i32, i32)
|
|
declare i32 @llvm.sadd.sat.i32(i32, i32)
|
|
declare i32 @llvm.usub.sat.i32(i32, i32)
|
|
declare i32 @llvm.ssub.sat.i32(i32, i32)
|
|
|
|
define void @uadd_sat(i32* %p) {
|
|
; CHECK-LABEL: @uadd_sat(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
|
|
; CHECK-NEXT: [[SAT1:%.*]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: store volatile i32 [[SAT1]], i32* [[P:%.*]]
|
|
; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
|
|
; CHECK: end:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
|
|
%sat = call i32 @llvm.uadd.sat.i32(i32 %i, i32 1)
|
|
store volatile i32 %sat, i32* %p
|
|
%i.inc = add nuw nsw i32 %i, 1
|
|
%cmp = icmp ne i32 %i.inc, 100
|
|
br i1 %cmp, label %loop, label %end
|
|
|
|
end:
|
|
ret void
|
|
}
|
|
|
|
define void @sadd_sat(i32* %p) {
|
|
; CHECK-LABEL: @sadd_sat(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
|
|
; CHECK-NEXT: [[SAT1:%.*]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: store volatile i32 [[SAT1]], i32* [[P:%.*]]
|
|
; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
|
|
; CHECK: end:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
|
|
%sat = call i32 @llvm.sadd.sat.i32(i32 %i, i32 1)
|
|
store volatile i32 %sat, i32* %p
|
|
%i.inc = add nuw nsw i32 %i, 1
|
|
%cmp = icmp ne i32 %i.inc, 100
|
|
br i1 %cmp, label %loop, label %end
|
|
|
|
end:
|
|
ret void
|
|
}
|
|
|
|
define void @usub_sat(i32* %p) {
|
|
; CHECK-LABEL: @usub_sat(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
|
|
; CHECK-NEXT: [[SAT1:%.*]] = sub nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: store volatile i32 [[SAT1]], i32* [[P:%.*]]
|
|
; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
|
|
; CHECK: end:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%i = phi i32 [ 1, %entry ], [ %i.inc, %loop ]
|
|
%sat = call i32 @llvm.usub.sat.i32(i32 %i, i32 1)
|
|
store volatile i32 %sat, i32* %p
|
|
%i.inc = add nuw nsw i32 %i, 1
|
|
%cmp = icmp ne i32 %i.inc, 100
|
|
br i1 %cmp, label %loop, label %end
|
|
|
|
end:
|
|
ret void
|
|
}
|
|
|
|
define void @ssub_sat(i32* %p) {
|
|
; CHECK-LABEL: @ssub_sat(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
|
|
; CHECK-NEXT: [[SAT1:%.*]] = sub nsw i32 [[I]], 1
|
|
; CHECK-NEXT: store volatile i32 [[SAT1]], i32* [[P:%.*]]
|
|
; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
|
|
; CHECK: end:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
|
|
%sat = call i32 @llvm.ssub.sat.i32(i32 %i, i32 1)
|
|
store volatile i32 %sat, i32* %p
|
|
%i.inc = add nuw nsw i32 %i, 1
|
|
%cmp = icmp ne i32 %i.inc, 100
|
|
br i1 %cmp, label %loop, label %end
|
|
|
|
end:
|
|
ret void
|
|
}
|