mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
e4d0a5ec18
Summary: With this patch, range metadata can be added to call/invoke including IntrinsicInst. Previously, it could only be added to load. Rename computeKnownBitsLoad to computeKnownBitsFromRangeMetadata because range metadata is not only used by load. Update the language reference to reflect this change. Test Plan: Add several tests in range-2.ll to confirm the verifier is happy with having range metadata on call/invoke. Add two tests in AddOverFlow.ll to confirm annotating range metadata to call/invoke can benefit InstCombine. Reviewers: meheff, nlewycky, reames, hfinkel, eliben Reviewed By: eliben Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D4187 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211281 91177308-0d34-0410-b5e6-96231b3b80d8
119 lines
2.9 KiB
LLVM
119 lines
2.9 KiB
LLVM
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
; CHECK-LABEL: @oppositesign
|
|
; CHECK: add nsw i16 %a, %b
|
|
define i16 @oppositesign(i16 %x, i16 %y) {
|
|
; %a is negative, %b is positive
|
|
%a = or i16 %x, 32768
|
|
%b = and i16 %y, 32767
|
|
%c = add i16 %a, %b
|
|
ret i16 %c
|
|
}
|
|
|
|
define i16 @zero_sign_bit(i16 %a) {
|
|
; CHECK-LABEL: @zero_sign_bit(
|
|
; CHECK-NEXT: and
|
|
; CHECK-NEXT: add nuw
|
|
; CHECK-NEXT: ret
|
|
%1 = and i16 %a, 32767
|
|
%2 = add i16 %1, 512
|
|
ret i16 %2
|
|
}
|
|
|
|
define i16 @zero_sign_bit2(i16 %a, i16 %b) {
|
|
; CHECK-LABEL: @zero_sign_bit2(
|
|
; CHECK-NEXT: and
|
|
; CHECK-NEXT: and
|
|
; CHECK-NEXT: add nuw
|
|
; CHECK-NEXT: ret
|
|
%1 = and i16 %a, 32767
|
|
%2 = and i16 %b, 32767
|
|
%3 = add i16 %1, %2
|
|
ret i16 %3
|
|
}
|
|
|
|
declare i16 @bounded(i16 %input);
|
|
declare i32 @__gxx_personality_v0(...);
|
|
!0 = metadata !{i16 0, i16 32768} ; [0, 32767]
|
|
!1 = metadata !{i16 0, i16 32769} ; [0, 32768]
|
|
|
|
define i16 @add_bounded_values(i16 %a, i16 %b) {
|
|
; CHECK-LABEL: @add_bounded_values(
|
|
entry:
|
|
%c = call i16 @bounded(i16 %a), !range !0
|
|
%d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !0
|
|
cont:
|
|
; %c and %d are in [0, 32767]. Therefore, %c + %d doesn't unsigned overflow.
|
|
%e = add i16 %c, %d
|
|
; CHECK: add nuw i16 %c, %d
|
|
ret i16 %e
|
|
lpad:
|
|
%0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
|
filter [0 x i8*] zeroinitializer
|
|
ret i16 42
|
|
}
|
|
|
|
define i16 @add_bounded_values_2(i16 %a, i16 %b) {
|
|
; CHECK-LABEL: @add_bounded_values_2(
|
|
entry:
|
|
%c = call i16 @bounded(i16 %a), !range !1
|
|
%d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !1
|
|
cont:
|
|
; Similar to add_bounded_values, but %c and %d are in [0, 32768]. Therefore,
|
|
; %c + %d may unsigned overflow and we cannot add NUW.
|
|
%e = add i16 %c, %d
|
|
; CHECK: add i16 %c, %d
|
|
ret i16 %e
|
|
lpad:
|
|
%0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
|
filter [0 x i8*] zeroinitializer
|
|
ret i16 42
|
|
}
|
|
|
|
; CHECK-LABEL: @ripple_nsw1
|
|
; CHECK: add nsw i16 %a, %b
|
|
define i16 @ripple_nsw1(i16 %x, i16 %y) {
|
|
; %a has at most one bit set
|
|
%a = and i16 %y, 1
|
|
|
|
; %b has a 0 bit other than the sign bit
|
|
%b = and i16 %x, 49151
|
|
|
|
%c = add i16 %a, %b
|
|
ret i16 %c
|
|
}
|
|
|
|
; Like the previous test, but flip %a and %b
|
|
; CHECK-LABEL: @ripple_nsw2
|
|
; CHECK: add nsw i16 %b, %a
|
|
define i16 @ripple_nsw2(i16 %x, i16 %y) {
|
|
%a = and i16 %y, 1
|
|
%b = and i16 %x, 49151
|
|
%c = add i16 %b, %a
|
|
ret i16 %c
|
|
}
|
|
|
|
; CHECK-LABEL: @ripple_no_nsw1
|
|
; CHECK: add i32 %a, %x
|
|
define i32 @ripple_no_nsw1(i32 %x, i32 %y) {
|
|
; We know nothing about %x
|
|
%a = and i32 %y, 1
|
|
%b = add i32 %a, %x
|
|
ret i32 %b
|
|
}
|
|
|
|
; CHECK-LABEL: @ripple_no_nsw2
|
|
; CHECK: add nuw i16 %a, %b
|
|
define i16 @ripple_no_nsw2(i16 %x, i16 %y) {
|
|
; %a has at most one bit set
|
|
%a = and i16 %y, 1
|
|
|
|
; %b has a 0 bit, but it is the sign bit
|
|
%b = and i16 %x, 32767
|
|
|
|
%c = add i16 %a, %b
|
|
ret i16 %c
|
|
}
|