You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.205
Former-commit-id: 7f59f7e792705db773f1caecdaa823092f4e2927
This commit is contained in:
parent
5cd5df71cc
commit
8e12397d70
33
external/llvm/test/Analysis/ValueTracking/assume.ll
vendored
Normal file
33
external/llvm/test/Analysis/ValueTracking/assume.ll
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
|
||||
define i32 @assume_add(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @assume_add(
|
||||
; CHECK-NEXT: [[T1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[LAST_TWO_DIGITS:%.*]] = and i32 [[T1]], 3
|
||||
; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[LAST_TWO_DIGITS]], 0
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[T2]])
|
||||
; CHECK-NEXT: [[T3:%.*]] = or i32 [[T1]], 3
|
||||
; CHECK-NEXT: ret i32 [[T3]]
|
||||
;
|
||||
%t1 = add i32 %a, %b
|
||||
%last_two_digits = and i32 %t1, 3
|
||||
%t2 = icmp eq i32 %last_two_digits, 0
|
||||
call void @llvm.assume(i1 %t2)
|
||||
%t3 = add i32 %t1, 3
|
||||
ret i32 %t3
|
||||
}
|
||||
|
||||
|
||||
define void @assume_not() {
|
||||
; CHECK-LABEL: @assume_not(
|
||||
entry-block:
|
||||
%0 = call i1 @get_val()
|
||||
; CHECK: call void @llvm.assume
|
||||
%1 = xor i1 %0, true
|
||||
call void @llvm.assume(i1 %1)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i1 @get_val()
|
||||
declare void @llvm.assume(i1)
|
82
external/llvm/test/Analysis/ValueTracking/deref-bitcast-of-gep.ll
vendored
Normal file
82
external/llvm/test/Analysis/ValueTracking/deref-bitcast-of-gep.ll
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
; RUN: opt -S -licm < %s | FileCheck %s
|
||||
|
||||
; Note: the !invariant.load is there just solely to let us call @use()
|
||||
; to add a fake use, and still have the aliasing work out. The call
|
||||
; to @use(0) is just to provide a may-unwind exit out of the loop, so
|
||||
; that LICM cannot hoist out the load simply because it is guaranteed
|
||||
; to execute.
|
||||
|
||||
declare void @use(i32)
|
||||
|
||||
define void @f_0(i8* align 4 dereferenceable(1024) %ptr) {
|
||||
; CHECK-LABEL: @f_0(
|
||||
; CHECK: entry:
|
||||
; CHECK: %val = load i32, i32* %ptr.i32
|
||||
; CHECK: br label %loop
|
||||
; CHECK: loop:
|
||||
; CHECK: call void @use(i32 0)
|
||||
; CHECK-NEXT: call void @use(i32 %val)
|
||||
|
||||
|
||||
entry:
|
||||
%ptr.gep = getelementptr i8, i8* %ptr, i32 32
|
||||
%ptr.i32 = bitcast i8* %ptr.gep to i32*
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
call void @use(i32 0)
|
||||
%val = load i32, i32* %ptr.i32, !invariant.load !{}
|
||||
call void @use(i32 %val)
|
||||
br label %loop
|
||||
}
|
||||
|
||||
define void @f_1(i8* align 4 dereferenceable_or_null(1024) %ptr) {
|
||||
; CHECK-LABEL: @f_1(
|
||||
entry:
|
||||
%ptr.gep = getelementptr i8, i8* %ptr, i32 32
|
||||
%ptr.i32 = bitcast i8* %ptr.gep to i32*
|
||||
%ptr_is_null = icmp eq i8* %ptr, null
|
||||
br i1 %ptr_is_null, label %leave, label %loop
|
||||
|
||||
; CHECK: loop.preheader:
|
||||
; CHECK: %val = load i32, i32* %ptr.i32
|
||||
; CHECK: br label %loop
|
||||
; CHECK: loop:
|
||||
; CHECK: call void @use(i32 0)
|
||||
; CHECK-NEXT: call void @use(i32 %val)
|
||||
|
||||
loop:
|
||||
call void @use(i32 0)
|
||||
%val = load i32, i32* %ptr.i32, !invariant.load !{}
|
||||
call void @use(i32 %val)
|
||||
br label %loop
|
||||
|
||||
leave:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @f_2(i8* align 4 dereferenceable_or_null(1024) %ptr) {
|
||||
; CHECK-LABEL: @f_2(
|
||||
; CHECK-NOT: load
|
||||
; CHECK: call void @use(i32 0)
|
||||
; CHECK-NEXT: %val = load i32, i32* %ptr.i32, !invariant.load !0
|
||||
; CHECK-NEXT: call void @use(i32 %val)
|
||||
|
||||
entry:
|
||||
;; Can't hoist, since the alignment does not work out -- (<4 byte
|
||||
;; aligned> + 30) is not necessarily 4 byte aligned.
|
||||
|
||||
%ptr.gep = getelementptr i8, i8* %ptr, i32 30
|
||||
%ptr.i32 = bitcast i8* %ptr.gep to i32*
|
||||
%ptr_is_null = icmp eq i8* %ptr, null
|
||||
br i1 %ptr_is_null, label %leave, label %loop
|
||||
|
||||
loop:
|
||||
call void @use(i32 0)
|
||||
%val = load i32, i32* %ptr.i32, !invariant.load !{}
|
||||
call void @use(i32 %val)
|
||||
br label %loop
|
||||
|
||||
leave:
|
||||
ret void
|
||||
}
|
21
external/llvm/test/Analysis/ValueTracking/dereferenceable-and-aligned.ll
vendored
Normal file
21
external/llvm/test/Analysis/ValueTracking/dereferenceable-and-aligned.ll
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
; RUN: opt < %s -licm -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:32:32-p1:64:64-p4:64:64"
|
||||
|
||||
; Make sure isDereferenceableAndAlignePointer() doesn't crash when looking
|
||||
; walking pointer defs with an addrspacecast that changes pointer size.
|
||||
; CHECK-LABEL: @addrspacecast_crash
|
||||
define void @addrspacecast_crash() {
|
||||
bb:
|
||||
%tmp = alloca [256 x i32]
|
||||
br label %bb1
|
||||
|
||||
bb1:
|
||||
%tmp2 = getelementptr inbounds [256 x i32], [256 x i32]* %tmp, i32 0, i32 36
|
||||
%tmp3 = bitcast i32* %tmp2 to <4 x i32>*
|
||||
%tmp4 = addrspacecast <4 x i32>* %tmp3 to <4 x i32> addrspace(4)*
|
||||
%tmp5 = load <4 x i32>, <4 x i32> addrspace(4)* %tmp4
|
||||
%tmp6 = xor <4 x i32> %tmp5, undef
|
||||
store <4 x i32> %tmp6, <4 x i32> addrspace(1)* undef
|
||||
br label %bb1
|
||||
}
|
26
external/llvm/test/Analysis/ValueTracking/get-pointer-base-with-const-off.ll
vendored
Normal file
26
external/llvm/test/Analysis/ValueTracking/get-pointer-base-with-const-off.ll
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: opt -gvn -S < %s | FileCheck %s
|
||||
|
||||
; Make sure we don't crash when analyzing an addrspacecast in
|
||||
; GetPointerBaseWithConstantOffset()
|
||||
|
||||
target datalayout = "e-p:32:32-p4:64:64"
|
||||
|
||||
define i32 @addrspacecast-crash() {
|
||||
; CHECK-LABEL: @addrspacecast-crash
|
||||
; CHECK: %tmp = alloca [25 x i64]
|
||||
; CHECK: %tmp1 = getelementptr inbounds [25 x i64], [25 x i64]* %tmp, i32 0, i32 0
|
||||
; CHECK: %tmp2 = addrspacecast i64* %tmp1 to <8 x i64> addrspace(4)*
|
||||
; CHECK: store <8 x i64> zeroinitializer, <8 x i64> addrspace(4)* %tmp2
|
||||
; CHECK-NOT: load
|
||||
bb:
|
||||
%tmp = alloca [25 x i64]
|
||||
%tmp1 = getelementptr inbounds [25 x i64], [25 x i64]* %tmp, i32 0, i32 0
|
||||
%tmp2 = addrspacecast i64* %tmp1 to <8 x i64> addrspace(4)*
|
||||
%tmp3 = getelementptr inbounds <8 x i64>, <8 x i64> addrspace(4)* %tmp2, i64 0
|
||||
store <8 x i64> zeroinitializer, <8 x i64> addrspace(4)* %tmp3
|
||||
%tmp4 = getelementptr inbounds [25 x i64], [25 x i64]* %tmp, i32 0, i32 0
|
||||
%tmp5 = addrspacecast i64* %tmp4 to i32 addrspace(4)*
|
||||
%tmp6 = getelementptr inbounds i32, i32 addrspace(4)* %tmp5, i64 10
|
||||
%tmp7 = load i32, i32 addrspace(4)* %tmp6, align 4
|
||||
ret i32 %tmp7
|
||||
}
|
34
external/llvm/test/Analysis/ValueTracking/known-bits-from-range-md.ll
vendored
Normal file
34
external/llvm/test/Analysis/ValueTracking/known-bits-from-range-md.ll
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
; RUN: opt -S -instsimplify -instcombine < %s | FileCheck %s
|
||||
|
||||
define i1 @test0(i8* %ptr) {
|
||||
; CHECK-LABEL: @test0(
|
||||
entry:
|
||||
%val = load i8, i8* %ptr, !range !{i8 -50, i8 0}
|
||||
%and = and i8 %val, 128
|
||||
%is.eq = icmp eq i8 %and, 128
|
||||
ret i1 %is.eq
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @test1(i8* %ptr) {
|
||||
; CHECK-LABEL: @test1(
|
||||
entry:
|
||||
%val = load i8, i8* %ptr, !range !{i8 64, i8 128}
|
||||
%and = and i8 %val, 64
|
||||
%is.eq = icmp eq i8 %and, 64
|
||||
ret i1 %is.eq
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @test2(i8* %ptr) {
|
||||
; CHECK-LABEL: @test2(
|
||||
entry:
|
||||
; CHECK: %val = load i8
|
||||
; CHECK: %and = and i8 %val
|
||||
; CHECK: %is.eq = icmp ne i8 %and, 0
|
||||
; CHECK: ret i1 %is.eq
|
||||
%val = load i8, i8* %ptr, !range !{i8 64, i8 129}
|
||||
%and = and i8 %val, 64
|
||||
%is.eq = icmp eq i8 %and, 64
|
||||
ret i1 %is.eq
|
||||
}
|
21
external/llvm/test/Analysis/ValueTracking/known-non-equal.ll
vendored
Normal file
21
external/llvm/test/Analysis/ValueTracking/known-non-equal.ll
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
; RUN: opt -instsimplify < %s -S | FileCheck %s
|
||||
|
||||
; CHECK: define i1 @test
|
||||
define i1 @test(i8* %pq, i8 %B) {
|
||||
%q = load i8, i8* %pq, !range !0 ; %q is known nonzero; no known bits
|
||||
%A = add nsw i8 %B, %q
|
||||
%cmp = icmp eq i8 %A, %B
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK: define i1 @test2
|
||||
define i1 @test2(i8 %a, i8 %b) {
|
||||
%A = or i8 %a, 2 ; %A[1] = 1
|
||||
%B = and i8 %b, -3 ; %B[1] = 0
|
||||
%cmp = icmp eq i8 %A, %B ; %A[1] and %B[1] are contradictory.
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
!0 = !{ i8 1, i8 5 }
|
100
external/llvm/test/Analysis/ValueTracking/known-nonnull-at.ll
vendored
Normal file
100
external/llvm/test/Analysis/ValueTracking/known-nonnull-at.ll
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -instsimplify < %s | FileCheck %s
|
||||
|
||||
declare void @bar(i8* %a, i8* nonnull %b)
|
||||
|
||||
; 'y' must be nonnull.
|
||||
|
||||
define i1 @caller1(i8* %x, i8* %y) {
|
||||
; CHECK-LABEL: @caller1(
|
||||
; CHECK-NEXT: call void @bar(i8* %x, i8* %y)
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
call void @bar(i8* %x, i8* %y)
|
||||
%null_check = icmp eq i8* %y, null
|
||||
ret i1 %null_check
|
||||
}
|
||||
|
||||
; Don't know anything about 'y'.
|
||||
|
||||
define i1 @caller2(i8* %x, i8* %y) {
|
||||
; CHECK-LABEL: @caller2(
|
||||
; CHECK-NEXT: call void @bar(i8* %y, i8* %x)
|
||||
; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %y, null
|
||||
; CHECK-NEXT: ret i1 [[NULL_CHECK]]
|
||||
;
|
||||
call void @bar(i8* %y, i8* %x)
|
||||
%null_check = icmp eq i8* %y, null
|
||||
ret i1 %null_check
|
||||
}
|
||||
|
||||
; 'y' must be nonnull.
|
||||
|
||||
define i1 @caller3(i8* %x, i8* %y) {
|
||||
; CHECK-LABEL: @caller3(
|
||||
; CHECK-NEXT: call void @bar(i8* %x, i8* %y)
|
||||
; CHECK-NEXT: ret i1 true
|
||||
;
|
||||
call void @bar(i8* %x, i8* %y)
|
||||
%null_check = icmp ne i8* %y, null
|
||||
ret i1 %null_check
|
||||
}
|
||||
|
||||
; FIXME: The call is guaranteed to execute, so 'y' must be nonnull throughout.
|
||||
|
||||
define i1 @caller4(i8* %x, i8* %y) {
|
||||
; CHECK-LABEL: @caller4(
|
||||
; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp ne i8* %y, null
|
||||
; CHECK-NEXT: call void @bar(i8* %x, i8* %y)
|
||||
; CHECK-NEXT: ret i1 [[NULL_CHECK]]
|
||||
;
|
||||
%null_check = icmp ne i8* %y, null
|
||||
call void @bar(i8* %x, i8* %y)
|
||||
ret i1 %null_check
|
||||
}
|
||||
|
||||
; The call to bar() does not dominate the null check, so no change.
|
||||
|
||||
define i1 @caller5(i8* %x, i8* %y) {
|
||||
; CHECK-LABEL: @caller5(
|
||||
; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %y, null
|
||||
; CHECK-NEXT: br i1 [[NULL_CHECK]], label %t, label %f
|
||||
; CHECK: t:
|
||||
; CHECK-NEXT: ret i1 [[NULL_CHECK]]
|
||||
; CHECK: f:
|
||||
; CHECK-NEXT: call void @bar(i8* %x, i8* %y)
|
||||
; CHECK-NEXT: ret i1 [[NULL_CHECK]]
|
||||
;
|
||||
%null_check = icmp eq i8* %y, null
|
||||
br i1 %null_check, label %t, label %f
|
||||
t:
|
||||
ret i1 %null_check
|
||||
f:
|
||||
call void @bar(i8* %x, i8* %y)
|
||||
ret i1 %null_check
|
||||
}
|
||||
|
||||
; Make sure that an invoke works similarly to a call.
|
||||
|
||||
declare i32 @esfp(...)
|
||||
|
||||
define i1 @caller6(i8* %x, i8* %y) personality i8* bitcast (i32 (...)* @esfp to i8*){
|
||||
; CHECK-LABEL: @caller6(
|
||||
; CHECK-NEXT: invoke void @bar(i8* %x, i8* nonnull %y)
|
||||
; CHECK-NEXT: to label %cont unwind label %exc
|
||||
; CHECK: cont:
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
invoke void @bar(i8* %x, i8* nonnull %y)
|
||||
to label %cont unwind label %exc
|
||||
|
||||
cont:
|
||||
%null_check = icmp eq i8* %y, null
|
||||
ret i1 %null_check
|
||||
|
||||
exc:
|
||||
%lp = landingpad { i8*, i32 }
|
||||
filter [0 x i8*] zeroinitializer
|
||||
unreachable
|
||||
}
|
||||
|
20
external/llvm/test/Analysis/ValueTracking/known-power-of-two.ll
vendored
Normal file
20
external/llvm/test/Analysis/ValueTracking/known-power-of-two.ll
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
; RUN: opt -S -instcombine < %s | FileCheck %s
|
||||
|
||||
; https://llvm.org/bugs/show_bug.cgi?id=25900
|
||||
; An arithmetic shift right of a power of two is not a power
|
||||
; of two if the original value is the sign bit. Therefore,
|
||||
; we can't transform the sdiv into a udiv.
|
||||
|
||||
define i32 @pr25900(i32 %d) {
|
||||
%and = and i32 %d, -2147483648
|
||||
; The next 3 lines prevent another fold from masking the bug.
|
||||
%ext = zext i32 %and to i64
|
||||
%or = or i64 %ext, 4294967296
|
||||
%trunc = trunc i64 %or to i32
|
||||
%ashr = ashr exact i32 %trunc, 31
|
||||
%div = sdiv i32 4, %ashr
|
||||
ret i32 %div
|
||||
|
||||
; CHECK: sdiv
|
||||
}
|
||||
|
49
external/llvm/test/Analysis/ValueTracking/known-signbit-shift.ll
vendored
Normal file
49
external/llvm/test/Analysis/ValueTracking/known-signbit-shift.ll
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
|
||||
; Result of left shifting a non-negative integer
|
||||
; with nsw flag should also be non-negative
|
||||
define i1 @test_shift_nonnegative(i32 %a) {
|
||||
; CHECK-LABEL: @test_shift_nonnegative(
|
||||
; CHECK-NEXT: ret i1 true
|
||||
;
|
||||
%b = lshr i32 %a, 2
|
||||
%shift = shl nsw i32 %b, 3
|
||||
%cmp = icmp sge i32 %shift, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; Result of left shifting a negative integer with
|
||||
; nsw flag should also be negative
|
||||
define i1 @test_shift_negative(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: @test_shift_negative(
|
||||
; CHECK-NEXT: ret i1 true
|
||||
;
|
||||
%c = or i32 %a, -2147483648
|
||||
%d = and i32 %b, 7
|
||||
%shift = shl nsw i32 %c, %d
|
||||
%cmp = icmp slt i32 %shift, 0
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; If sign bit is a known zero, it cannot be a known one.
|
||||
; This test should not crash opt. The shift produces poison.
|
||||
define i32 @test_no_sign_bit_conflict1(i1 %b) {
|
||||
; CHECK-LABEL: @test_no_sign_bit_conflict1(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%sel = select i1 %b, i32 8193, i32 8192
|
||||
%mul = shl nsw i32 %sel, 18
|
||||
ret i32 %mul
|
||||
}
|
||||
|
||||
; If sign bit is a known one, it cannot be a known zero.
|
||||
; This test should not crash opt. The shift produces poison.
|
||||
define i32 @test_no_sign_bit_conflict2(i1 %b) {
|
||||
; CHECK-LABEL: @test_no_sign_bit_conflict2(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%sel = select i1 %b, i32 -8193, i32 -8194
|
||||
%mul = shl nsw i32 %sel, 18
|
||||
ret i32 %mul
|
||||
}
|
13
external/llvm/test/Analysis/ValueTracking/knownnonzero-shift.ll
vendored
Normal file
13
external/llvm/test/Analysis/ValueTracking/knownnonzero-shift.ll
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
; RUN: opt -instsimplify -S < %s | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @test
|
||||
define i1 @test(i8 %p, i8* %pq) {
|
||||
%q = load i8, i8* %pq, !range !0 ; %q is known nonzero; no known bits
|
||||
%1 = shl i8 %p, %q ; because %q is nonzero, %1[0] is known to be zero.
|
||||
%2 = and i8 %1, 1
|
||||
%x = icmp eq i8 %2, 0
|
||||
; CHECK: ret i1 true
|
||||
ret i1 %x
|
||||
}
|
||||
|
||||
!0 = !{ i8 1, i8 5 }
|
24
external/llvm/test/Analysis/ValueTracking/knownzero-addrspacecast.ll
vendored
Normal file
24
external/llvm/test/Analysis/ValueTracking/knownzero-addrspacecast.ll
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
; RUN: opt -instcombine -S < %s | FileCheck %s
|
||||
|
||||
; When a pointer is addrspacecasted to a another addr space, we cannot assume
|
||||
; anything about the new bits.
|
||||
|
||||
target datalayout = "p:32:32-p3:32:32-p4:64:64"
|
||||
|
||||
; CHECK-LABEL: @test_shift
|
||||
; CHECK-NOT: ret i64 0
|
||||
define i64 @test_shift(i8* %p) {
|
||||
%g = addrspacecast i8* %p to i8 addrspace(4)*
|
||||
%i = ptrtoint i8 addrspace(4)* %g to i64
|
||||
%shift = lshr i64 %i, 32
|
||||
ret i64 %shift
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test_null
|
||||
; A null pointer casted to another addr space may no longer have null value.
|
||||
; CHECK-NOT: ret i32 0
|
||||
define i32 @test_null() {
|
||||
%g = addrspacecast i8* null to i8 addrspace(3)*
|
||||
%i = ptrtoint i8 addrspace(3)* %g to i32
|
||||
ret i32 %i
|
||||
}
|
75
external/llvm/test/Analysis/ValueTracking/knownzero-shift.ll
vendored
Normal file
75
external/llvm/test/Analysis/ValueTracking/knownzero-shift.ll
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -instsimplify -S < %s | FileCheck %s
|
||||
|
||||
define i1 @test(i8 %p, i8* %pq) {
|
||||
; CHECK-LABEL: @test(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
%q = load i8, i8* %pq, !range !0 ; %q is known nonzero; no known bits
|
||||
%1 = or i8 %p, 2 ; %1[1] = 1
|
||||
%2 = and i8 %1, 254 ; %2[0] = 0, %2[1] = 1
|
||||
%A = lshr i8 %2, 1 ; We should know that %A is nonzero.
|
||||
%x = icmp eq i8 %A, 0
|
||||
ret i1 %x
|
||||
}
|
||||
|
||||
!0 = !{ i8 1, i8 5 }
|
||||
|
||||
define i32 @shl_shl(i32 %A) {
|
||||
; CHECK-LABEL: @shl_shl(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%B = shl i32 %A, 6
|
||||
%C = shl i32 %B, 28
|
||||
ret i32 %C
|
||||
}
|
||||
|
||||
define <2 x i33> @shl_shl_splat_vec(<2 x i33> %A) {
|
||||
; CHECK-LABEL: @shl_shl_splat_vec(
|
||||
; CHECK-NEXT: ret <2 x i33> zeroinitializer
|
||||
;
|
||||
%B = shl <2 x i33> %A, <i33 5, i33 5>
|
||||
%C = shl <2 x i33> %B, <i33 28, i33 28>
|
||||
ret <2 x i33> %C
|
||||
}
|
||||
|
||||
; FIXME
|
||||
|
||||
define <2 x i33> @shl_shl_vec(<2 x i33> %A) {
|
||||
; CHECK-LABEL: @shl_shl_vec(
|
||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i33> %A, <i33 6, i33 5>
|
||||
; CHECK-NEXT: [[C:%.*]] = shl <2 x i33> [[B]], <i33 27, i33 28>
|
||||
; CHECK-NEXT: ret <2 x i33> [[C]]
|
||||
;
|
||||
%B = shl <2 x i33> %A, <i33 6, i33 5>
|
||||
%C = shl <2 x i33> %B, <i33 27, i33 28>
|
||||
ret <2 x i33> %C
|
||||
}
|
||||
|
||||
define i232 @lshr_lshr(i232 %A) {
|
||||
; CHECK-LABEL: @lshr_lshr(
|
||||
; CHECK-NEXT: ret i232 0
|
||||
;
|
||||
%B = lshr i232 %A, 231
|
||||
%C = lshr i232 %B, 1
|
||||
ret i232 %C
|
||||
}
|
||||
|
||||
define <2 x i32> @lshr_lshr_splat_vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @lshr_lshr_splat_vec(
|
||||
; CHECK-NEXT: ret <2 x i32> zeroinitializer
|
||||
;
|
||||
%B = lshr <2 x i32> %A, <i32 28, i32 28>
|
||||
%C = lshr <2 x i32> %B, <i32 4, i32 4>
|
||||
ret <2 x i32> %C
|
||||
}
|
||||
|
||||
define <2 x i32> @lshr_lshr_vec(<2 x i32> %A) {
|
||||
; CHECK-LABEL: @lshr_lshr_vec(
|
||||
; CHECK-NEXT: ret <2 x i32> zeroinitializer
|
||||
;
|
||||
%B = lshr <2 x i32> %A, <i32 29, i32 28>
|
||||
%C = lshr <2 x i32> %B, <i32 4, i32 5>
|
||||
ret <2 x i32> %C
|
||||
}
|
||||
|
199
external/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll
vendored
Normal file
199
external/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
; RUN: opt -print-memderefs -analyze -S <%s | FileCheck %s
|
||||
|
||||
; Uses the print-deref (+ analyze to print) pass to run
|
||||
; isDereferenceablePointer() on many load instruction operands
|
||||
|
||||
target datalayout = "e-i32:32:64"
|
||||
|
||||
%TypeOpaque = type opaque
|
||||
|
||||
declare zeroext i1 @return_i1()
|
||||
|
||||
declare i32* @foo()
|
||||
@globalstr = global [6 x i8] c"hello\00"
|
||||
@globali32ptr = external global i32*
|
||||
|
||||
%struct.A = type { [8 x i8], [5 x i8] }
|
||||
@globalstruct = external global %struct.A
|
||||
|
||||
@globalptr.align1 = external global i8, align 1
|
||||
@globalptr.align16 = external global i8, align 16
|
||||
|
||||
; CHECK-LABEL: 'test'
|
||||
define void @test(%struct.A* sret %result,
|
||||
i32 addrspace(1)* dereferenceable(8) %dparam,
|
||||
i8 addrspace(1)* dereferenceable(32) align 1 %dparam.align1,
|
||||
i8 addrspace(1)* dereferenceable(32) align 16 %dparam.align16,
|
||||
i8* byval %i8_byval,
|
||||
%struct.A* byval %A_byval)
|
||||
gc "statepoint-example" {
|
||||
; CHECK: The following are dereferenceable:
|
||||
entry:
|
||||
; CHECK: %globalptr{{.*}}(aligned)
|
||||
%globalptr = getelementptr inbounds [6 x i8], [6 x i8]* @globalstr, i32 0, i32 0
|
||||
%load1 = load i8, i8* %globalptr
|
||||
|
||||
; CHECK: %alloca{{.*}}(aligned)
|
||||
%alloca = alloca i1
|
||||
%load2 = load i1, i1* %alloca
|
||||
|
||||
; Load from empty array alloca
|
||||
; CHECK-NOT: %empty_alloca
|
||||
%empty_alloca = alloca i8, i64 0
|
||||
%empty_load = load i8, i8* %empty_alloca
|
||||
|
||||
; Loads from sret arguments
|
||||
; CHECK: %sret_gep{{.*}}(aligned)
|
||||
%sret_gep = getelementptr inbounds %struct.A, %struct.A* %result, i64 0, i32 1, i64 2
|
||||
load i8, i8* %sret_gep
|
||||
|
||||
; CHECK-NOT: %sret_gep_outside
|
||||
%sret_gep_outside = getelementptr %struct.A, %struct.A* %result, i64 0, i32 1, i64 7
|
||||
load i8, i8* %sret_gep_outside
|
||||
|
||||
; CHECK: %dparam{{.*}}(aligned)
|
||||
%load3 = load i32, i32 addrspace(1)* %dparam
|
||||
|
||||
; CHECK: %relocate{{.*}}(aligned)
|
||||
%tok = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
|
||||
%relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 7, i32 7)
|
||||
%load4 = load i32, i32 addrspace(1)* %relocate
|
||||
|
||||
; CHECK-NOT: %nparam
|
||||
%dpa = call i32 addrspace(1)* @func1(i32 addrspace(1)* %dparam)
|
||||
%nparam = getelementptr i32, i32 addrspace(1)* %dpa, i32 5
|
||||
%load5 = load i32, i32 addrspace(1)* %nparam
|
||||
|
||||
; Load from a non-dereferenceable load
|
||||
; CHECK-NOT: %nd_load
|
||||
%nd_load = load i32*, i32** @globali32ptr
|
||||
%load6 = load i32, i32* %nd_load
|
||||
|
||||
; Load from a dereferenceable load
|
||||
; CHECK: %d4_load{{.*}}(aligned)
|
||||
%d4_load = load i32*, i32** @globali32ptr, !dereferenceable !0
|
||||
%load7 = load i32, i32* %d4_load
|
||||
|
||||
; Load from an offset not covered by the dereferenceable portion
|
||||
; CHECK-NOT: %d2_load
|
||||
%d2_load = load i32*, i32** @globali32ptr, !dereferenceable !1
|
||||
%load8 = load i32, i32* %d2_load
|
||||
|
||||
; Load from a potentially null pointer with dereferenceable_or_null
|
||||
; CHECK-NOT: %d_or_null_load
|
||||
%d_or_null_load = load i32*, i32** @globali32ptr, !dereferenceable_or_null !0
|
||||
%load9 = load i32, i32* %d_or_null_load
|
||||
|
||||
; Load from a non-null pointer with dereferenceable_or_null
|
||||
; CHECK: %d_or_null_non_null_load{{.*}}(aligned)
|
||||
%d_or_null_non_null_load = load i32*, i32** @globali32ptr, !nonnull !2, !dereferenceable_or_null !0
|
||||
%load10 = load i32, i32* %d_or_null_non_null_load
|
||||
|
||||
; It's OK to overrun static array size as long as we stay within underlying object size
|
||||
; CHECK: %within_allocation{{.*}}(aligned)
|
||||
%within_allocation = getelementptr inbounds %struct.A, %struct.A* @globalstruct, i64 0, i32 0, i64 10
|
||||
%load11 = load i8, i8* %within_allocation
|
||||
|
||||
; GEP is outside the underlying object size
|
||||
; CHECK-NOT: %outside_allocation
|
||||
%outside_allocation = getelementptr inbounds %struct.A, %struct.A* @globalstruct, i64 0, i32 1, i64 10
|
||||
%load12 = load i8, i8* %outside_allocation
|
||||
|
||||
; Loads from aligned globals
|
||||
; CHECK: @globalptr.align1{{.*}}(unaligned)
|
||||
; CHECK: @globalptr.align16{{.*}}(aligned)
|
||||
%load13 = load i8, i8* @globalptr.align1, align 16
|
||||
%load14 = load i8, i8* @globalptr.align16, align 16
|
||||
|
||||
; Loads from aligned arguments
|
||||
; CHECK: %dparam.align1{{.*}}(unaligned)
|
||||
; CHECK: %dparam.align16{{.*}}(aligned)
|
||||
%load15 = load i8, i8 addrspace(1)* %dparam.align1, align 16
|
||||
%load16 = load i8, i8 addrspace(1)* %dparam.align16, align 16
|
||||
|
||||
; Loads from byval arguments
|
||||
; CHECK: %i8_byval{{.*}}(aligned)
|
||||
%i8_byval_load = load i8, i8* %i8_byval
|
||||
|
||||
; CHECK-NOT: %byval_cast
|
||||
%byval_cast = bitcast i8* %i8_byval to i32*
|
||||
%bad_byval_load = load i32, i32* %byval_cast
|
||||
|
||||
; CHECK: %byval_gep{{.*}}(aligned)
|
||||
%byval_gep = getelementptr inbounds %struct.A, %struct.A* %A_byval, i64 0, i32 1, i64 2
|
||||
load i8, i8* %byval_gep
|
||||
|
||||
; Loads from aligned allocas
|
||||
; CHECK: %alloca.align1{{.*}}(unaligned)
|
||||
; CHECK: %alloca.align16{{.*}}(aligned)
|
||||
%alloca.align1 = alloca i1, align 1
|
||||
%alloca.align16 = alloca i1, align 16
|
||||
%load17 = load i1, i1* %alloca.align1, align 16
|
||||
%load18 = load i1, i1* %alloca.align16, align 16
|
||||
|
||||
; Loads from GEPs
|
||||
; CHECK: %gep.align1.offset1{{.*}}(unaligned)
|
||||
; CHECK: %gep.align16.offset1{{.*}}(unaligned)
|
||||
; CHECK: %gep.align1.offset16{{.*}}(unaligned)
|
||||
; CHECK: %gep.align16.offset16{{.*}}(aligned)
|
||||
%gep.align1.offset1 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align1, i32 1
|
||||
%gep.align16.offset1 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align16, i32 1
|
||||
%gep.align1.offset16 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align1, i32 16
|
||||
%gep.align16.offset16 = getelementptr inbounds i8, i8 addrspace(1)* %dparam.align16, i32 16
|
||||
%load19 = load i8, i8 addrspace(1)* %gep.align1.offset1, align 16
|
||||
%load20 = load i8, i8 addrspace(1)* %gep.align16.offset1, align 16
|
||||
%load21 = load i8, i8 addrspace(1)* %gep.align1.offset16, align 16
|
||||
%load22 = load i8, i8 addrspace(1)* %gep.align16.offset16, align 16
|
||||
|
||||
; CHECK-NOT: %no_deref_return
|
||||
; CHECK: %deref_return{{.*}}(unaligned)
|
||||
; CHECK: %deref_and_aligned_return{{.*}}(aligned)
|
||||
%no_deref_return = call i32* @foo()
|
||||
%deref_return = call dereferenceable(32) i32* @foo()
|
||||
%deref_and_aligned_return = call dereferenceable(32) align 16 i32* @foo()
|
||||
%load23 = load i32, i32* %no_deref_return
|
||||
%load24 = load i32, i32* %deref_return, align 16
|
||||
%load25 = load i32, i32* %deref_and_aligned_return, align 16
|
||||
|
||||
; Load from a dereferenceable and aligned load
|
||||
; CHECK: %d4_unaligned_load{{.*}}(unaligned)
|
||||
; CHECK: %d4_aligned_load{{.*}}(aligned)
|
||||
%d4_unaligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0
|
||||
%d4_aligned_load = load i32*, i32** @globali32ptr, !dereferenceable !0, !align !{i64 16}
|
||||
%load26 = load i32, i32* %d4_unaligned_load, align 16
|
||||
%load27 = load i32, i32* %d4_aligned_load, align 16
|
||||
|
||||
; Alloca with no explicit alignment is aligned to preferred alignment of
|
||||
; the type (specified by datalayout string).
|
||||
; CHECK: %alloca.noalign{{.*}}(aligned)
|
||||
%alloca.noalign = alloca i32
|
||||
%load28 = load i32, i32* %alloca.noalign, align 8
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
; Just check that we don't crash.
|
||||
; CHECK-LABEL: 'opaque_type_crasher'
|
||||
define void @opaque_type_crasher(%TypeOpaque* dereferenceable(16) %a) {
|
||||
entry:
|
||||
%bc = bitcast %TypeOpaque* %a to i8*
|
||||
%ptr8 = getelementptr inbounds i8, i8* %bc, i32 8
|
||||
%ptr32 = bitcast i8* %ptr8 to i32*
|
||||
br i1 undef, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
%res = load i32, i32* %ptr32, align 4
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
|
||||
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
|
||||
|
||||
declare i32 addrspace(1)* @func1(i32 addrspace(1)* returned) nounwind argmemonly
|
||||
|
||||
!0 = !{i64 4}
|
||||
!1 = !{i64 2}
|
||||
!2 = !{}
|
49
external/llvm/test/Analysis/ValueTracking/monotonic-phi.ll
vendored
Normal file
49
external/llvm/test/Analysis/ValueTracking/monotonic-phi.ll
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
; RUN: opt -instsimplify -S < %s | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @test1
|
||||
define i1 @test1(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 1, %entry ], [ %next, %loop ]
|
||||
%next = add nsw i8 %A, 1
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%add = or i8 %A, %r
|
||||
%cmp = icmp eq i8 %add, 0
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test2
|
||||
define i1 @test2(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 1, %entry ], [ %next, %loop ]
|
||||
%next = add i8 %A, 1
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%add = or i8 %A, %r
|
||||
%cmp = icmp eq i8 %add, 0
|
||||
; CHECK-NOT: ret i1 false
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test3
|
||||
define i1 @test3(i8 %p, i8* %pq, i8 %n, i8 %r) {
|
||||
entry:
|
||||
br label %loop
|
||||
loop:
|
||||
%A = phi i8 [ 1, %entry ], [ %next, %loop ]
|
||||
%next = add nuw i8 %A, 1
|
||||
%cmp1 = icmp eq i8 %A, %n
|
||||
br i1 %cmp1, label %exit, label %loop
|
||||
exit:
|
||||
%add = or i8 %A, %r
|
||||
%cmp = icmp eq i8 %add, 0
|
||||
; CHECK: ret i1 false
|
||||
ret i1 %cmp
|
||||
}
|
15
external/llvm/test/Analysis/ValueTracking/pr23011.ll
vendored
Normal file
15
external/llvm/test/Analysis/ValueTracking/pr23011.ll
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
; RUN: opt -indvars -S < %s | FileCheck %s
|
||||
|
||||
declare { i8, i1 } @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone
|
||||
|
||||
define i1 @test1(i8 %x) {
|
||||
entry:
|
||||
; CHECK-LABEL: @test1
|
||||
%rem = srem i8 %x, 15
|
||||
%t = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %rem, i8 %rem)
|
||||
; CHECK: %t = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %rem, i8 %rem)
|
||||
; CHECK: %obit = extractvalue { i8, i1 } %t, 1
|
||||
; CHECK: ret i1 %obit
|
||||
%obit = extractvalue { i8, i1 } %t, 1
|
||||
ret i1 %obit
|
||||
}
|
46
external/llvm/test/Analysis/ValueTracking/select-pattern.ll
vendored
Normal file
46
external/llvm/test/Analysis/ValueTracking/select-pattern.ll
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
; RUN: opt -simplifycfg < %s -S | FileCheck %s
|
||||
|
||||
; The dead code would cause a select that had itself
|
||||
; as an operand to be analyzed. This would then cause
|
||||
; infinite recursion and eventual crash.
|
||||
|
||||
define void @PR36045(i1 %t, i32* %b) {
|
||||
; CHECK-LABEL: @PR36045(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
br i1 %t, label %if, label %end
|
||||
|
||||
if:
|
||||
br i1 %t, label %unreach, label %pre
|
||||
|
||||
unreach:
|
||||
unreachable
|
||||
|
||||
pre:
|
||||
%p = phi i32 [ 70, %if ], [ %sel, %for ]
|
||||
br label %for
|
||||
|
||||
for:
|
||||
%cmp = icmp sgt i32 %p, 8
|
||||
%add = add i32 %p, 2
|
||||
%sel = select i1 %cmp, i32 %p, i32 %add
|
||||
%cmp21 = icmp ult i32 %sel, 21
|
||||
br i1 %cmp21, label %pre, label %for.end
|
||||
|
||||
for.end:
|
||||
br i1 %t, label %unreach2, label %then12
|
||||
|
||||
then12:
|
||||
store i32 0, i32* %b
|
||||
br label %unreach2
|
||||
|
||||
unreach2:
|
||||
%spec = phi i32 [ %sel, %for.end ], [ 42, %then12 ]
|
||||
unreachable
|
||||
|
||||
end:
|
||||
ret void
|
||||
}
|
||||
|
28
external/llvm/test/Analysis/ValueTracking/signbits-extract-elt.ll
vendored
Normal file
28
external/llvm/test/Analysis/ValueTracking/signbits-extract-elt.ll
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -instsimplify -S | FileCheck %s
|
||||
|
||||
; If computeKnownBits can do a simple look-through for extractelement
|
||||
; then instsimplify will know that %elt1 is non-negative at icmp.
|
||||
define i1 @computeKnownBits_look_through_extractelt(<2 x i8> %vecin) {
|
||||
; CHECK-LABEL: @computeKnownBits_look_through_extractelt(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
%vec = zext <2 x i8> %vecin to <2 x i32>
|
||||
%elt1 = extractelement <2 x i32> %vec, i32 1
|
||||
%bool = icmp slt i32 %elt1, 0
|
||||
ret i1 %bool
|
||||
}
|
||||
|
||||
; If computeNumSignBits can do a simple look-through for extractelement
|
||||
; then instsimplify will remove the ashr.
|
||||
define i32 @computeNumSignBits_look_through_extractelt(<2 x i1> %vecin) {
|
||||
; CHECK-LABEL: @computeNumSignBits_look_through_extractelt(
|
||||
; CHECK-NEXT: [[VEC:%.*]] = sext <2 x i1> [[VEC:%.*]]in to <2 x i32>
|
||||
; CHECK-NEXT: [[ELT0:%.*]] = extractelement <2 x i32> [[VEC]], i32 0
|
||||
; CHECK-NEXT: ret i32 [[ELT0]]
|
||||
;
|
||||
%vec = sext <2 x i1> %vecin to <2 x i32>
|
||||
%elt0 = extractelement <2 x i32> %vec, i32 0
|
||||
%ashr = ashr i32 %elt0, 5
|
||||
ret i32 %ashr
|
||||
}
|
Reference in New Issue
Block a user