mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 00:24:26 +00:00
Add custom lowering for add/sub with overflow intrinsics to ARM
This patch adds support to ARM for custom lowering of the llvm.{u|s}add.with.overflow.i32 intrinsics for i32/i64. This is particularly useful for handling idiomatic saturating math functions as generated by InstCombineCompare. Test cases included. rdar://14853450 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208435 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
57
test/CodeGen/ARM/intrinsics-overflow.ll
Normal file
57
test/CodeGen/ARM/intrinsics-overflow.ll
Normal file
@ -0,0 +1,57 @@
|
||||
; RUN: llc < %s -march=arm -mcpu=generic | FileCheck %s
|
||||
|
||||
define i32 @uadd_overflow(i32 %a, i32 %b) #0 {
|
||||
%sadd = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
|
||||
%1 = extractvalue { i32, i1 } %sadd, 1
|
||||
%2 = zext i1 %1 to i32
|
||||
ret i32 %2
|
||||
|
||||
; CHECK-LABEL: uadd_overflow:
|
||||
; CHECK: add r[[R2:[0-9]+]], r[[R0:[0-9]+]], r[[R1:[0-9]+]]
|
||||
; CHECK: mov r[[R1]], #1
|
||||
; CHECK: cmp r[[R2]], r[[R0]]
|
||||
; CHECK: movhs r[[R1]], #0
|
||||
}
|
||||
|
||||
|
||||
define i32 @sadd_overflow(i32 %a, i32 %b) #0 {
|
||||
%sadd = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
|
||||
%1 = extractvalue { i32, i1 } %sadd, 1
|
||||
%2 = zext i1 %1 to i32
|
||||
ret i32 %2
|
||||
|
||||
; CHECK-LABEL: sadd_overflow:
|
||||
; CHECK: add r[[R2:[0-9]+]], r[[R0:[0-9]+]], r[[R1:[0-9]+]]
|
||||
; CHECK: mov r[[R1]], #1
|
||||
; CHECK: cmp r[[R2]], r[[R0]]
|
||||
; CHECK: movvc r[[R1]], #0
|
||||
}
|
||||
|
||||
define i32 @usub_overflow(i32 %a, i32 %b) #0 {
|
||||
%sadd = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
|
||||
%1 = extractvalue { i32, i1 } %sadd, 1
|
||||
%2 = zext i1 %1 to i32
|
||||
ret i32 %2
|
||||
|
||||
; CHECK-LABEL: usub_overflow:
|
||||
; CHECK: mov r[[R2]], #1
|
||||
; CHECK: cmp r[[R0]], r[[R1]]
|
||||
; CHECK: movhs r[[R2]], #0
|
||||
}
|
||||
|
||||
define i32 @ssub_overflow(i32 %a, i32 %b) #0 {
|
||||
%sadd = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
|
||||
%1 = extractvalue { i32, i1 } %sadd, 1
|
||||
%2 = zext i1 %1 to i32
|
||||
ret i32 %2
|
||||
|
||||
; CHECK-LABEL: ssub_overflow:
|
||||
; CHECK: mov r[[R2]], #1
|
||||
; CHECK: cmp r[[R0]], r[[R1]]
|
||||
; CHECK: movvc r[[R2]], #0
|
||||
}
|
||||
|
||||
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1
|
||||
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) #2
|
||||
declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) #3
|
||||
declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) #4
|
Reference in New Issue
Block a user