diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-11-25 19:05:59 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-11-25 19:05:59 +0000 |
| commit | 6449741f4c1842221757c062f4abbae7bb524ba9 (patch) | |
| tree | 5a2ca31d10f5ca2e8fb9c1ade59c306526de8329 /test | |
| parent | 60a9e02f5509f102642299ee408fab21b2ee30e4 (diff) | |
Notes
Diffstat (limited to 'test')
22 files changed, 1090 insertions, 25 deletions
diff --git a/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll b/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll new file mode 100644 index 000000000000..01813c8a8104 --- /dev/null +++ b/test/Analysis/LoopAccessAnalysis/memcheck-off-by-one-error.ll @@ -0,0 +1,51 @@ +; RUN: opt -analyze --loop-accesses %s | FileCheck %s + +; This test verifies run-time boundary check of memory accesses. +; The original loop: +; void fastCopy(const char* src, char* op) { +; int len = 32; +; while (len > 0) { +; *(reinterpret_cast<long long*>(op)) = *(reinterpret_cast<const long long*>(src)); +; src += 8; +; op += 8; +; len -= 8; +; } +; } +; Boundaries calculations before this patch: +; (Low: %src High: (24 + %src)) +; and the actual distance between two pointers was 31, (%op - %src = 31) +; IsConflict = (24 > 31) = false -> execution is directed to the vectorized loop. +; The loop was vectorized to 4, 32 byte memory access ( <4 x i64> ), +; store a value at *%op touched memory under *%src. + +;CHECK: Printing analysis 'Loop Access Analysis' for function 'fastCopy' +;CHECK: (Low: %op High: (32 + %op)) +;CHECK: (Low: %src High: (32 + %src)) + +define void @fastCopy(i8* nocapture readonly %src, i8* nocapture %op) { +entry: + br label %while.body.preheader + +while.body.preheader: ; preds = %entry + br label %while.body + +while.body: ; preds = %while.body.preheader, %while.body + %len.addr.07 = phi i32 [ %sub, %while.body ], [ 32, %while.body.preheader ] + %op.addr.06 = phi i8* [ %add.ptr1, %while.body ], [ %op, %while.body.preheader ] + %src.addr.05 = phi i8* [ %add.ptr, %while.body ], [ %src, %while.body.preheader ] + %0 = bitcast i8* %src.addr.05 to i64* + %1 = load i64, i64* %0, align 8 + %2 = bitcast i8* %op.addr.06 to i64* + store i64 %1, i64* %2, align 8 + %add.ptr = getelementptr inbounds i8, i8* %src.addr.05, i64 8 + %add.ptr1 = getelementptr inbounds i8, i8* %op.addr.06, i64 8 + %sub = add nsw i32 %len.addr.07, -8 + %cmp = icmp sgt i32 %len.addr.07, 8 + br i1 %cmp, label %while.body, label %while.end.loopexit + +while.end.loopexit: ; preds = %while.body + br label %while.end + +while.end: ; preds = %while.end.loopexit, %entry + ret void +} diff --git a/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll b/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll index a9626f4dc710..2bae4867870a 100644 --- a/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll +++ b/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll @@ -96,15 +96,15 @@ for.end: ; preds = %for.body ; CHECK-NEXT: %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind ; CHECK-NEXT: Grouped accesses: ; CHECK-NEXT: Group {{.*}}[[ZERO]]: -; CHECK-NEXT: (Low: %c High: (78 + %c)) +; CHECK-NEXT: (Low: %c High: (80 + %c)) ; CHECK-NEXT: Member: {(2 + %c)<nsw>,+,4} ; CHECK-NEXT: Member: {%c,+,4} ; CHECK-NEXT: Group {{.*}}[[ONE]]: -; CHECK-NEXT: (Low: %a High: (40 + %a)) +; CHECK-NEXT: (Low: %a High: (42 + %a)) ; CHECK-NEXT: Member: {(2 + %a)<nsw>,+,2} ; CHECK-NEXT: Member: {%a,+,2} ; CHECK-NEXT: Group {{.*}}[[TWO]]: -; CHECK-NEXT: (Low: %b High: (38 + %b)) +; CHECK-NEXT: (Low: %b High: (40 + %b)) ; CHECK-NEXT: Member: {%b,+,2} define void @testg(i16* %a, @@ -168,15 +168,15 @@ for.end: ; preds = %for.body ; CHECK-NEXT: %arrayidxB = getelementptr i16, i16* %b, i64 %ind ; CHECK-NEXT: Grouped accesses: ; CHECK-NEXT: Group {{.*}}[[ZERO]]: -; CHECK-NEXT: (Low: %c High: (78 + %c)) +; CHECK-NEXT: (Low: %c High: (80 + %c)) ; CHECK-NEXT: Member: {(2 + %c)<nsw>,+,4} ; CHECK-NEXT: Member: {%c,+,4} ; CHECK-NEXT: Group {{.*}}[[ONE]]: -; CHECK-NEXT: (Low: %a High: (40 + %a)) +; CHECK-NEXT: (Low: %a High: (42 + %a)) ; CHECK-NEXT: Member: {(2 + %a),+,2} ; CHECK-NEXT: Member: {%a,+,2} ; CHECK-NEXT: Group {{.*}}[[TWO]]: -; CHECK-NEXT: (Low: %b High: (38 + %b)) +; CHECK-NEXT: (Low: %b High: (40 + %b)) ; CHECK-NEXT: Member: {%b,+,2} define void @testh(i16* %a, @@ -247,13 +247,13 @@ for.end: ; preds = %for.body ; CHECK-NEXT: %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2 ; CHECK-NEXT: Grouped accesses: ; CHECK-NEXT: Group {{.*}}[[ZERO]]: -; CHECK-NEXT: (Low: ((2 * %offset) + %a)<nsw> High: (9998 + (2 * %offset) + %a)) +; CHECK-NEXT: (Low: ((2 * %offset) + %a)<nsw> High: (10000 + (2 * %offset) + %a)) ; CHECK-NEXT: Member: {((2 * %offset) + %a)<nsw>,+,2}<nsw><%for.body> ; CHECK-NEXT: Group {{.*}}[[ONE]]: -; CHECK-NEXT: (Low: %a High: (9998 + %a)) +; CHECK-NEXT: (Low: %a High: (10000 + %a)) ; CHECK-NEXT: Member: {%a,+,2}<%for.body> ; CHECK-NEXT: Group {{.*}}[[TWO]]: -; CHECK-NEXT: (Low: (20000 + %a) High: (29998 + %a)) +; CHECK-NEXT: (Low: (20000 + %a) High: (30000 + %a)) ; CHECK-NEXT: Member: {(20000 + %a),+,2}<%for.body> define void @testi(i16* %a, diff --git a/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll b/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll index 607e007f7a2d..405a47554e4e 100644 --- a/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll +++ b/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll @@ -16,7 +16,7 @@ target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" target triple = "aarch64--linux-gnueabi" ; CHECK: function 'f': -; CHECK: (Low: (20000 + %a) High: (60000 + %a)<nsw>) +; CHECK: (Low: (20000 + %a) High: (60004 + %a)) @B = common global i32* null, align 8 @A = common global i32* null, align 8 @@ -59,7 +59,7 @@ for.end: ; preds = %for.body ; Here it is not obvious what the limits are, since 'step' could be negative. ; CHECK: Low: (-1 + (-1 * ((-60001 + (-1 * %a)) umax (-60001 + (40000 * %step) + (-1 * %a))))) -; CHECK: High: ((60000 + %a)<nsw> umax (60000 + (-40000 * %step) + %a)) +; CHECK: High: (4 + ((60000 + %a)<nsw> umax (60000 + (-40000 * %step) + %a))) define void @g(i64 %step) { entry: diff --git a/test/CodeGen/PowerPC/atomic-minmax.ll b/test/CodeGen/PowerPC/atomic-minmax.ll new file mode 100644 index 000000000000..5b9a15331897 --- /dev/null +++ b/test/CodeGen/PowerPC/atomic-minmax.ll @@ -0,0 +1,435 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +define void @a32min(i32* nocapture dereferenceable(4) %minimum, i32 %val) #0 { +entry: + %0 = atomicrmw min i32* %minimum, i32 %val monotonic + ret void + +; CHECK-LABEL: @a32min +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpw 4, [[OLDV]] +; CHECK: bgelr 0 +; CHECK: stwcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a32max(i32* nocapture dereferenceable(4) %minimum, i32 %val) #0 { +entry: + %0 = atomicrmw max i32* %minimum, i32 %val monotonic + ret void + +; CHECK-LABEL: @a32max +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpw 4, [[OLDV]] +; CHECK: blelr 0 +; CHECK: stwcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a32umin(i32* nocapture dereferenceable(4) %minimum, i32 %val) #0 { +entry: + %0 = atomicrmw umin i32* %minimum, i32 %val monotonic + ret void + +; CHECK-LABEL: @a32umin +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmplw 4, [[OLDV]] +; CHECK: bgelr 0 +; CHECK: stwcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a32umax(i32* nocapture dereferenceable(4) %minimum, i32 %val) #0 { +entry: + %0 = atomicrmw umax i32* %minimum, i32 %val monotonic + ret void + +; CHECK-LABEL: @a32umax +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmplw 4, [[OLDV]] +; CHECK: blelr 0 +; CHECK: stwcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a16min(i16* nocapture dereferenceable(4) %minimum, i16 %val) #1 { +entry: + %0 = atomicrmw min i16* %minimum, i16 %val monotonic + ret void + +; CHECK-LABEL: @a16min +; CHECK: lharx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpw 4, [[OLDV]] +; CHECK: bgelr 0 +; CHECK: sthcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a16max(i16* nocapture dereferenceable(4) %minimum, i16 %val) #1 { +entry: + %0 = atomicrmw max i16* %minimum, i16 %val monotonic + ret void + +; CHECK-LABEL: @a16max +; CHECK: lharx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpw 4, [[OLDV]] +; CHECK: blelr 0 +; CHECK: sthcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a16umin(i16* nocapture dereferenceable(4) %minimum, i16 %val) #1 { +entry: + %0 = atomicrmw umin i16* %minimum, i16 %val monotonic + ret void + +; CHECK-LABEL: @a16umin +; CHECK: lharx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmplw 4, [[OLDV]] +; CHECK: bgelr 0 +; CHECK: sthcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a16umax(i16* nocapture dereferenceable(4) %minimum, i16 %val) #1 { +entry: + %0 = atomicrmw umax i16* %minimum, i16 %val monotonic + ret void + +; CHECK-LABEL: @a16umax +; CHECK: lharx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmplw 4, [[OLDV]] +; CHECK: blelr 0 +; CHECK: sthcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a8min(i8* nocapture dereferenceable(4) %minimum, i8 %val) #1 { +entry: + %0 = atomicrmw min i8* %minimum, i8 %val monotonic + ret void + +; CHECK-LABEL: @a8min +; CHECK: lbarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpw 4, [[OLDV]] +; CHECK: bgelr 0 +; CHECK: stbcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a8max(i8* nocapture dereferenceable(4) %minimum, i8 %val) #1 { +entry: + %0 = atomicrmw max i8* %minimum, i8 %val monotonic + ret void + +; CHECK-LABEL: @a8max +; CHECK: lbarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpw 4, [[OLDV]] +; CHECK: blelr 0 +; CHECK: stbcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a8umin(i8* nocapture dereferenceable(4) %minimum, i8 %val) #1 { +entry: + %0 = atomicrmw umin i8* %minimum, i8 %val monotonic + ret void + +; CHECK-LABEL: @a8umin +; CHECK: lbarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmplw 4, [[OLDV]] +; CHECK: bgelr 0 +; CHECK: stbcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a8umax(i8* nocapture dereferenceable(4) %minimum, i8 %val) #1 { +entry: + %0 = atomicrmw umax i8* %minimum, i8 %val monotonic + ret void + +; CHECK-LABEL: @a8umax +; CHECK: lbarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmplw 4, [[OLDV]] +; CHECK: blelr 0 +; CHECK: stbcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a64min(i64* nocapture dereferenceable(4) %minimum, i64 %val) #0 { +entry: + %0 = atomicrmw min i64* %minimum, i64 %val monotonic + ret void + +; CHECK-LABEL: @a64min +; CHECK: ldarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpd 4, [[OLDV]] +; CHECK: bgelr 0 +; CHECK: stdcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a64max(i64* nocapture dereferenceable(4) %minimum, i64 %val) #0 { +entry: + %0 = atomicrmw max i64* %minimum, i64 %val monotonic + ret void + +; CHECK-LABEL: @a64max +; CHECK: ldarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpd 4, [[OLDV]] +; CHECK: blelr 0 +; CHECK: stdcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a64umin(i64* nocapture dereferenceable(4) %minimum, i64 %val) #0 { +entry: + %0 = atomicrmw umin i64* %minimum, i64 %val monotonic + ret void + +; CHECK-LABEL: @a64umin +; CHECK: ldarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpld 4, [[OLDV]] +; CHECK: bgelr 0 +; CHECK: stdcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @a64umax(i64* nocapture dereferenceable(4) %minimum, i64 %val) #0 { +entry: + %0 = atomicrmw umax i64* %minimum, i64 %val monotonic + ret void + +; CHECK-LABEL: @a64umax +; CHECK: ldarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: cmpld 4, [[OLDV]] +; CHECK: blelr 0 +; CHECK: stdcx. 4, 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @ae16min(i16* nocapture dereferenceable(4) %minimum, i16 %val) #0 { +entry: + %0 = atomicrmw min i16* %minimum, i16 %val monotonic + ret void + +; CHECK-LABEL: @ae16min +; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 27 +; CHECK-DAG: li [[M1:[0-9]+]], 0 +; CHECK-DAG: rldicr 3, 3, 0, 61 +; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 16 +; CHECK-DAG: ori [[M2:[0-9]+]], [[M1]], 65535 +; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]] +; CHECK-DAG: slw [[M:[0-9]+]], [[M2]], [[SA]] +; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]] +; CHECK: extsh [[SESMOLDV:[0-9]+]], [[SMOLDV]] +; CHECK: cmpw 0, 4, [[SESMOLDV]] +; CHECK: bgelr 0 +; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] +; CHECK: stwcx. [[NEWV]], 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @ae16max(i16* nocapture dereferenceable(4) %minimum, i16 %val) #0 { +entry: + %0 = atomicrmw max i16* %minimum, i16 %val monotonic + ret void + +; CHECK-LABEL: @ae16max +; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 27 +; CHECK-DAG: li [[M1:[0-9]+]], 0 +; CHECK-DAG: rldicr 3, 3, 0, 61 +; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 16 +; CHECK-DAG: ori [[M2:[0-9]+]], [[M1]], 65535 +; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]] +; CHECK-DAG: slw [[M:[0-9]+]], [[M2]], [[SA]] +; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]] +; CHECK: extsh [[SESMOLDV:[0-9]+]], [[SMOLDV]] +; CHECK: cmpw 0, 4, [[SESMOLDV]] +; CHECK: blelr 0 +; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] +; CHECK: stwcx. [[NEWV]], 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @ae16umin(i16* nocapture dereferenceable(4) %minimum, i16 %val) #0 { +entry: + %0 = atomicrmw umin i16* %minimum, i16 %val monotonic + ret void + +; CHECK-LABEL: @ae16umin +; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 27 +; CHECK-DAG: li [[M1:[0-9]+]], 0 +; CHECK-DAG: rldicr 3, 3, 0, 61 +; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 16 +; CHECK-DAG: ori [[M2:[0-9]+]], [[M1]], 65535 +; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]] +; CHECK-DAG: slw [[M:[0-9]+]], [[M2]], [[SA]] +; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: cmplw 0, 4, [[MOLDV]] +; CHECK: bgelr 0 +; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] +; CHECK: stwcx. [[NEWV]], 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @ae16umax(i16* nocapture dereferenceable(4) %minimum, i16 %val) #0 { +entry: + %0 = atomicrmw umax i16* %minimum, i16 %val monotonic + ret void + +; CHECK-LABEL: @ae16umax +; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 27 +; CHECK-DAG: li [[M1:[0-9]+]], 0 +; CHECK-DAG: rldicr 3, 3, 0, 61 +; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 16 +; CHECK-DAG: ori [[M2:[0-9]+]], [[M1]], 65535 +; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]] +; CHECK-DAG: slw [[M:[0-9]+]], [[M2]], [[SA]] +; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: cmplw 0, 4, [[MOLDV]] +; CHECK: blelr 0 +; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] +; CHECK: stwcx. [[NEWV]], 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @ae8min(i8* nocapture dereferenceable(4) %minimum, i8 %val) #0 { +entry: + %0 = atomicrmw min i8* %minimum, i8 %val monotonic + ret void + +; CHECK-LABEL: @ae8min +; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 28 +; CHECK-DAG: li [[M1:[0-9]+]], 255 +; CHECK-DAG: rldicr 3, 3, 0, 61 +; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 24 +; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]] +; CHECK-DAG: slw [[M:[0-9]+]], [[M1]], [[SA]] +; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]] +; CHECK: extsb [[SESMOLDV:[0-9]+]], [[SMOLDV]] +; CHECK: cmpw 0, 4, [[SESMOLDV]] +; CHECK: bgelr 0 +; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] +; CHECK: stwcx. [[NEWV]], 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @ae8max(i8* nocapture dereferenceable(4) %minimum, i8 %val) #0 { +entry: + %0 = atomicrmw max i8* %minimum, i8 %val monotonic + ret void + +; CHECK-LABEL: @ae8max +; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 28 +; CHECK-DAG: li [[M1:[0-9]+]], 255 +; CHECK-DAG: rldicr 3, 3, 0, 61 +; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 24 +; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]] +; CHECK-DAG: slw [[M:[0-9]+]], [[M1]], [[SA]] +; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]] +; CHECK: extsb [[SESMOLDV:[0-9]+]], [[SMOLDV]] +; CHECK: cmpw 0, 4, [[SESMOLDV]] +; CHECK: blelr 0 +; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] +; CHECK: stwcx. [[NEWV]], 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @ae8umin(i8* nocapture dereferenceable(4) %minimum, i8 %val) #0 { +entry: + %0 = atomicrmw umin i8* %minimum, i8 %val monotonic + ret void + +; CHECK-LABEL: @ae8umin +; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 28 +; CHECK-DAG: li [[M1:[0-9]+]], 255 +; CHECK-DAG: rldicr 3, 3, 0, 61 +; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 24 +; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]] +; CHECK-DAG: slw [[M:[0-9]+]], [[M1]], [[SA]] +; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: cmplw 0, 4, [[MOLDV]] +; CHECK: bgelr 0 +; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] +; CHECK: stwcx. [[NEWV]], 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +define void @ae8umax(i8* nocapture dereferenceable(4) %minimum, i8 %val) #0 { +entry: + %0 = atomicrmw umax i8* %minimum, i8 %val monotonic + ret void + +; CHECK-LABEL: @ae8umax +; CHECK-DAG: rlwinm [[SA1:[0-9]+]], 3, 3, 27, 28 +; CHECK-DAG: li [[M1:[0-9]+]], 255 +; CHECK-DAG: rldicr 3, 3, 0, 61 +; CHECK-DAG: xori [[SA:[0-9]+]], [[SA1]], 24 +; CHECK-DAG: slw [[SV:[0-9]+]], 4, [[SA]] +; CHECK-DAG: slw [[M:[0-9]+]], [[M1]], [[SA]] +; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] +; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 +; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: cmplw 0, 4, [[MOLDV]] +; CHECK: blelr 0 +; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] +; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] +; CHECK: stwcx. [[NEWV]], 0, 3 +; CHECK: bne 0, +; CHECK: blr +} + +attributes #0 = { nounwind "target-cpu"="ppc64" } +attributes #1 = { nounwind "target-cpu"="pwr8" } + diff --git a/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll b/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll index ac187e084257..fa2844b8d551 100644 --- a/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll +++ b/test/CodeGen/PowerPC/p9-xxinsertw-xxextractuw.ll @@ -968,3 +968,25 @@ entry: %vecins = shufflevector <4 x float> %a, <4 x float> %a, <4 x i32> <i32 0, i32 1, i32 2, i32 6> ret <4 x float> %vecins } +define <4 x float> @insertVarF(<4 x float> %a, float %f, i32 %el) { +entry: +; CHECK-LABEL: insertVarF +; CHECK: stxsspx 1, +; CHECK: lxvd2x +; CHECK-BE-LABEL: insertVarF +; CHECK-BE: stxsspx 1, +; CHECK-BE: lxvw4x + %vecins = insertelement <4 x float> %a, float %f, i32 %el + ret <4 x float> %vecins +} +define <4 x i32> @insertVarI(<4 x i32> %a, i32 %i, i32 %el) { +entry: +; CHECK-LABEL: insertVarI +; CHECK: stwx +; CHECK: lxvd2x +; CHECK-BE-LABEL: insertVarI +; CHECK-BE: stwx +; CHECK-BE: lxvw4x + %vecins = insertelement <4 x i32> %a, i32 %i, i32 %el + ret <4 x i32> %vecins +} diff --git a/test/CodeGen/PowerPC/pr30451.ll b/test/CodeGen/PowerPC/pr30451.ll new file mode 100644 index 000000000000..930553451cf8 --- /dev/null +++ b/test/CodeGen/PowerPC/pr30451.ll @@ -0,0 +1,69 @@ +; RUN: llc < %s -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown | FileCheck %s +define i8 @atomic_min_i8() { + top: + %0 = alloca i8, align 2 + %1 = bitcast i8* %0 to i8* + call void @llvm.lifetime.start(i64 2, i8* %1) + store i8 -1, i8* %0, align 2 + %2 = atomicrmw min i8* %0, i8 0 acq_rel + %3 = load atomic i8, i8* %0 acquire, align 8 + call void @llvm.lifetime.end(i64 2, i8* %1) + ret i8 %3 +; CHECK-LABEL: atomic_min_i8 +; CHECK: lbarx [[DST:[0-9]+]], +; CHECK-NEXT: extsb [[EXT:[0-9]+]], [[DST]] +; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]] +; CHECK-NEXT: bge 0 +} +define i16 @atomic_min_i16() { + top: + %0 = alloca i16, align 2 + %1 = bitcast i16* %0 to i8* + call void @llvm.lifetime.start(i64 2, i8* %1) + store i16 -1, i16* %0, align 2 + %2 = atomicrmw min i16* %0, i16 0 acq_rel + %3 = load atomic i16, i16* %0 acquire, align 8 + call void @llvm.lifetime.end(i64 2, i8* %1) + ret i16 %3 +; CHECK-LABEL: atomic_min_i16 +; CHECK: lharx [[DST:[0-9]+]], +; CHECK-NEXT: extsh [[EXT:[0-9]+]], [[DST]] +; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]] +; CHECK-NEXT: bge 0 +} + +define i8 @atomic_max_i8() { + top: + %0 = alloca i8, align 2 + %1 = bitcast i8* %0 to i8* + call void @llvm.lifetime.start(i64 2, i8* %1) + store i8 -1, i8* %0, align 2 + %2 = atomicrmw max i8* %0, i8 0 acq_rel + %3 = load atomic i8, i8* %0 acquire, align 8 + call void @llvm.lifetime.end(i64 2, i8* %1) + ret i8 %3 +; CHECK-LABEL: atomic_max_i8 +; CHECK: lbarx [[DST:[0-9]+]], +; CHECK-NEXT: extsb [[EXT:[0-9]+]], [[DST]] +; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]] +; CHECK-NEXT: ble 0 +} +define i16 @atomic_max_i16() { + top: + %0 = alloca i16, align 2 + %1 = bitcast i16* %0 to i8* + call void @llvm.lifetime.start(i64 2, i8* %1) + store i16 -1, i16* %0, align 2 + %2 = atomicrmw max i16* %0, i16 0 acq_rel + %3 = load atomic i16, i16* %0 acquire, align 8 + call void @llvm.lifetime.end(i64 2, i8* %1) + ret i16 %3 +; CHECK-LABEL: atomic_max_i16 +; CHECK: lharx [[DST:[0-9]+]], +; CHECK-NEXT: extsh [[EXT:[0-9]+]], [[DST]] +; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]] +; CHECK-NEXT: ble 0 +} + +declare void @llvm.lifetime.start(i64, i8*) +declare void @llvm.lifetime.end(i64, i8*) diff --git a/test/CodeGen/X86/avx-vbroadcast.ll b/test/CodeGen/X86/avx-vbroadcast.ll index b312be9aa6b2..534670795894 100644 --- a/test/CodeGen/X86/avx-vbroadcast.ll +++ b/test/CodeGen/X86/avx-vbroadcast.ll @@ -546,3 +546,64 @@ define <4 x double> @splat_concat4(double* %p) { %6 = shufflevector <2 x double> %3, <2 x double> %5, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ret <4 x double> %6 } + +; +; When VBROADCAST replaces an existing load, ensure it still respects lifetime dependencies. +; +define float @broadcast_lifetime() nounwind { +; X32-LABEL: broadcast_lifetime: +; X32: ## BB#0: +; X32-NEXT: pushl %esi +; X32-NEXT: subl $56, %esp +; X32-NEXT: leal {{[0-9]+}}(%esp), %esi +; X32-NEXT: movl %esi, (%esp) +; X32-NEXT: calll _gfunc +; X32-NEXT: vbroadcastss {{[0-9]+}}(%esp), %xmm0 +; X32-NEXT: vmovaps %xmm0, {{[0-9]+}}(%esp) ## 16-byte Spill +; X32-NEXT: movl %esi, (%esp) +; X32-NEXT: calll _gfunc +; X32-NEXT: vbroadcastss {{[0-9]+}}(%esp), %xmm0 +; X32-NEXT: vsubss {{[0-9]+}}(%esp), %xmm0, %xmm0 ## 16-byte Folded Reload +; X32-NEXT: vmovss %xmm0, {{[0-9]+}}(%esp) +; X32-NEXT: flds {{[0-9]+}}(%esp) +; X32-NEXT: addl $56, %esp +; X32-NEXT: popl %esi +; X32-NEXT: retl +; +; X64-LABEL: broadcast_lifetime: +; X64: ## BB#0: +; X64-NEXT: subq $40, %rsp +; X64-NEXT: leaq (%rsp), %rdi +; X64-NEXT: callq _gfunc +; X64-NEXT: vbroadcastss {{[0-9]+}}(%rsp), %xmm0 +; X64-NEXT: vmovaps %xmm0, {{[0-9]+}}(%rsp) ## 16-byte Spill +; X64-NEXT: leaq (%rsp), %rdi +; X64-NEXT: callq _gfunc +; X64-NEXT: vbroadcastss {{[0-9]+}}(%rsp), %xmm0 +; X64-NEXT: vsubss {{[0-9]+}}(%rsp), %xmm0, %xmm0 ## 16-byte Folded Reload +; X64-NEXT: addq $40, %rsp +; X64-NEXT: retq + %1 = alloca <4 x float>, align 16 + %2 = alloca <4 x float>, align 16 + %3 = bitcast <4 x float>* %1 to i8* + %4 = bitcast <4 x float>* %2 to i8* + + call void @llvm.lifetime.start(i64 16, i8* %3) + call void @gfunc(<4 x float>* %1) + %5 = load <4 x float>, <4 x float>* %1, align 16 + call void @llvm.lifetime.end(i64 16, i8* %3) + + call void @llvm.lifetime.start(i64 16, i8* %4) + call void @gfunc(<4 x float>* %2) + %6 = load <4 x float>, <4 x float>* %2, align 16 + call void @llvm.lifetime.end(i64 16, i8* %4) + + %7 = extractelement <4 x float> %5, i32 1 + %8 = extractelement <4 x float> %6, i32 1 + %9 = fsub float %8, %7 + ret float %9 +} + +declare void @gfunc(<4 x float>*) +declare void @llvm.lifetime.start(i64, i8*) +declare void @llvm.lifetime.end(i64, i8*) diff --git a/test/CodeGen/X86/branchfolding-undef.mir b/test/CodeGen/X86/branchfolding-undef.mir new file mode 100644 index 000000000000..0da167b33257 --- /dev/null +++ b/test/CodeGen/X86/branchfolding-undef.mir @@ -0,0 +1,29 @@ +# RUN: llc -o - %s -march=x86 -run-pass branch-folder | FileCheck %s +# Test that tail merging drops undef flags that aren't present on all +# instructions to be merged. +--- | + define void @func() { ret void } +... +--- +# CHECK-LABEL: name: func +# CHECK: bb.1: +# CHECK: %eax = MOV32ri 2 +# CHECK-NOT: RET +# CHECK: bb.2: +# CHECK-NOT: RET 0, undef %eax +# CHECK: RET 0, %eax +name: func +tracksRegLiveness: true +body: | + bb.0: + successors: %bb.1, %bb.2 + JE_1 %bb.1, implicit undef %eflags + JMP_1 %bb.2 + + bb.1: + %eax = MOV32ri 2 + RET 0, %eax + + bb.2: + RET 0, undef %eax +... diff --git a/test/CodeGen/X86/no-and8ri8.ll b/test/CodeGen/X86/no-and8ri8.ll new file mode 100644 index 000000000000..57f33226602e --- /dev/null +++ b/test/CodeGen/X86/no-and8ri8.ll @@ -0,0 +1,18 @@ +; RUN: llc -mtriple=x86_64-pc-linux -mattr=+avx512f --show-mc-encoding < %s | FileCheck %s + +declare i1 @bar() + +; CHECK-LABEL: @foo +; CHECK-NOT: andb {{.*}} # encoding: [0x82, +define i1 @foo(i1 %i) nounwind { +entry: + br i1 %i, label %if, label %else + +if: + %r = call i1 @bar() + br label %else + +else: + %ret = phi i1 [%r, %if], [true, %entry] + ret i1 %ret +} diff --git a/test/CodeGen/X86/pr30298.ll b/test/CodeGen/X86/pr30298.ll new file mode 100644 index 000000000000..1e6dad0b20d1 --- /dev/null +++ b/test/CodeGen/X86/pr30298.ll @@ -0,0 +1,43 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=i386-pc-linux-gnu -mattr=+sse < %s | FileCheck %s + +@c = external global i32*, align 8 + +define void @mul_2xi8(i8* nocapture readonly %a, i8* nocapture readonly %b, i64 %index) nounwind { +; CHECK-LABEL: mul_2xi8: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: pushl %ebx +; CHECK-NEXT: pushl %edi +; CHECK-NEXT: pushl %esi +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx +; CHECK-NEXT: movl c, %esi +; CHECK-NEXT: movzbl 1(%edx,%ecx), %edi +; CHECK-NEXT: movzbl (%edx,%ecx), %edx +; CHECK-NEXT: movzbl 1(%eax,%ecx), %ebx +; CHECK-NEXT: movzbl (%eax,%ecx), %eax +; CHECK-NEXT: imull %edx, %eax +; CHECK-NEXT: imull %edi, %ebx +; CHECK-NEXT: movl %ebx, 4(%esi,%ecx,4) +; CHECK-NEXT: movl %eax, (%esi,%ecx,4) +; CHECK-NEXT: popl %esi +; CHECK-NEXT: popl %edi +; CHECK-NEXT: popl %ebx +; CHECK-NEXT: retl +entry: + %pre = load i32*, i32** @c + %tmp6 = getelementptr inbounds i8, i8* %a, i64 %index + %tmp7 = bitcast i8* %tmp6 to <2 x i8>* + %wide.load = load <2 x i8>, <2 x i8>* %tmp7, align 1 + %tmp8 = zext <2 x i8> %wide.load to <2 x i32> + %tmp10 = getelementptr inbounds i8, i8* %b, i64 %index + %tmp11 = bitcast i8* %tmp10 to <2 x i8>* + %wide.load17 = load <2 x i8>, <2 x i8>* %tmp11, align 1 + %tmp12 = zext <2 x i8> %wide.load17 to <2 x i32> + %tmp13 = mul nuw nsw <2 x i32> %tmp12, %tmp8 + %tmp14 = getelementptr inbounds i32, i32* %pre, i64 %index + %tmp15 = bitcast i32* %tmp14 to <2 x i32>* + store <2 x i32> %tmp13, <2 x i32>* %tmp15, align 4 + ret void +} diff --git a/test/LTO/X86/Inputs/type-mapping-src.ll b/test/LTO/X86/Inputs/type-mapping-src.ll new file mode 100644 index 000000000000..3a80560a4486 --- /dev/null +++ b/test/LTO/X86/Inputs/type-mapping-src.ll @@ -0,0 +1,20 @@ +target triple = "x86_64-pc-windows-msvc18.0.0" + +%SrcType = type { i8 } +@x = external global %SrcType + +%CommonStruct = type opaque +@bar = internal global %CommonStruct* null, !dbg !0 + + +!llvm.dbg.cu = !{!1} +!llvm.module.flags = !{!12} +!0 = distinct !DIGlobalVariable(name: "bar", linkageName: "bar", scope: !1, file: !2, line: 2, type: !5, isLocal: false, isDefinition: true) +!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4) +!2 = !DIFile(filename: "b", directory: "/") +!3 = !{} +!4 = !{!0} +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64) +!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !2, line: 1, flags: DIFlagFwdDecl, identifier: ".?AUS@@") +!12 = !{i32 2, !"Debug Info Version", i32 3} + diff --git a/test/LTO/X86/type-mapping-bug.ll b/test/LTO/X86/type-mapping-bug.ll new file mode 100644 index 000000000000..3a1891234c86 --- /dev/null +++ b/test/LTO/X86/type-mapping-bug.ll @@ -0,0 +1,50 @@ +; RUN: llvm-as -o %t.dst.bc %s +; RUN: llvm-as -o %t.src.bc %S/Inputs/type-mapping-src.ll +; RUN: llvm-lto %t.dst.bc %t.src.bc -o=/dev/null + +target triple = "x86_64-pc-windows-msvc18.0.0" + +; @x in Src will be linked with this @x, causing SrcType in Src to be mapped +; to %DstType. +%DstType = type { i8 } +@x = global %DstType zeroinitializer + +; The Src module will re-use our DINode for this type. +%CommonStruct = type { i32 } +@foo = internal global %CommonStruct zeroinitializer, !dbg !5 + +; That DINode will refer to this value, casted to %Tricky.1* (!11), +; which will then show up in Src's getIdentifiedStructTypes(). +@templateValueParam = global i8 zeroinitializer + +; Because of the names, we would try to map %Tricky.1 to %Tricky -- +; mapping a Dst type to another Dst type! This would assert when +; getting a mapping from %DstType, which has previously used as +; a destination type. Since these types are not in the source module, +; there should be no attempt to create a mapping involving them; +; both types should be left as they are. +%Tricky = type opaque +%Tricky.1 = type { %DstType* } + + +; Mark %Tricky used. +@use = global %Tricky* zeroinitializer + +!llvm.dbg.cu = !{!1} +!llvm.module.flags = !{!19} +!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4) +!2 = !DIFile(filename: "a", directory: "/") +!3 = !{} +!4 = !{!5} +!5 = distinct !DIGlobalVariable(name: "foo", linkageName: "foo", scope: !1, file: !2, line: 5, type: !6, isLocal: false, isDefinition: true) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !2, line: 5, size: 8, elements: !7, identifier: ".?AUS@@") +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !6, baseType: !9) +!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Template<&x>", file: !2, line: 3, size: 8, elements: !3, templateParams: !10, identifier: ".?AU?$Template@$1?x@@3UX@@A@@") +!10 = !{!11} + +!11 = !DITemplateValueParameter(type: !12, value: %Tricky.1* bitcast (i8* @templateValueParam to %Tricky.1*)) + +!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "X", file: !2, line: 1, size: 8, elements: !3, identifier: ".?AUX@@") +!19 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/test/MC/ARM/ldr-pseudo-wide.s b/test/MC/ARM/ldr-pseudo-wide.s new file mode 100644 index 000000000000..ae1799f706ac --- /dev/null +++ b/test/MC/ARM/ldr-pseudo-wide.s @@ -0,0 +1,71 @@ +@ Test case for PR30352 +@ Check that ldr.w is: +@ accepted and ignored for ARM +@ accepted and propagated for Thumb2 +@ rejected as needing Thumb2 for Thumb + +@RUN: llvm-mc -triple armv5-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-ARM --check-prefix=CHECK %s +@RUN: llvm-mc -triple armv7-base-apple-darwin %s | FileCheck --check-prefix=CHECK-DARWIN-ARM --check-prefix=CHECK-DARWIN %s +@RUN: llvm-mc -triple thumbv7-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-THUMB2 --check-prefix=CHECK %s +@RUN: llvm-mc -triple thumbv7-base-apple-darwin %s | FileCheck --check-prefix=CHECK-DARWIN-THUMB2 --check-prefix=CHECK-DARWIN %s +@RUN: not llvm-mc -triple thumbv6-unknown-linux-gnueabi %s 2>&1 | FileCheck --check-prefix=CHECK-THUMB %s +@RUN: not llvm-mc -triple thumbv6-base-apple-darwin %s 2>&1 | FileCheck --check-prefix=CHECK-THUMB %s +@ CHECK-LABEL: f1: +f1: + ldr r0, =0x10002 +@ CHECK-ARM: ldr r0, .Ltmp[[TMP0:[0-9]+]] +@ CHECK-DARWIN-ARM: ldr r0, Ltmp0 +@ CHECK-THUMB2: ldr r0, .Ltmp[[TMP0:[0-9]+]] +@ CHECK-DARWIN-THUMB2: ldr r0, Ltmp0 + + ldr.w r0, =0x10002 +@ CHECK-ARM: ldr r0, .Ltmp[[TMP1:[0-9]+]] +@ CHECK-DARWIN-ARM: ldr r0, Ltmp1 +@ CHECK-THUMB2: ldr.w r0, .Ltmp[[TMP1:[0-9]+]] +@ CHECK-DARWIN-THUMB2: ldr.w r0, Ltmp1 +@ CHECK-THUMB: error: instruction requires: thumb2 +@ CHECK-THUMB-NEXT: ldr.w r0, =0x10002 + +@ CHECK-LABEL: f2: +f2: + ldr r0, =foo +@ CHECK-ARM: ldr r0, .Ltmp[[TMP2:[0-9]+]] +@ CHECK-DARWIN-ARM: ldr r0, Ltmp2 +@ CHECK-THUMB2: ldr r0, .Ltmp[[TMP2:[0-9]+]] +@ CHECK-DARWIN-THUMB2: ldr r0, Ltmp2 + + ldr.w r0, =foo +@ CHECK-ARM: ldr r0, .Ltmp[[TMP3:[0-9]+]] +@ CHECK-DARWIN-ARM: ldr r0, Ltmp3 +@ CHECK-THUMB2: ldr.w r0, .Ltmp[[TMP3:[0-9]+]] +@ CHECK-DARWIN-THUMB2: ldr.w r0, Ltmp3 +@ CHECK-THUMB: error: instruction requires: thumb2 +@ CHECK-THUMB-NEXT: ldr.w r0, =foo + +@ CHECK-LABEL: f3: +f3: + ldr.w r1, =0x1 +@ CHECK-ARM: mov r1, #1 +@ CHECK-DARWIN-ARM: mov r1, #1 +@ CHECK-THUMB2: mov.w r1, #1 +@ CHECK-DARWIN-THUMB2: mov.w r1, #1 +@ CHECK-THUMB: error: instruction requires: thumb2 +@ CHECK-THUMB-NEXT: ldr.w r1, =0x1 + +@ CHECK: .Ltmp0: +@ CHECK-NEXT: .long 65538 +@ CHECK: .Ltmp1: +@ CHECK-NEXT: .long 65538 +@ CHECK: .Ltmp2: +@ CHECK-NEXT: .long foo +@ CHECK: .Ltmp3: +@ CHECK-NEXT: .long foo + +@ CHECK-DARWIN: Ltmp0: +@ CHECK-DARWIN-NEXT: .long 65538 +@ CHECK-DARWIN: Ltmp1: +@ CHECK-DARWIN-NEXT: .long 65538 +@ CHECK-DARWIN: Ltmp2: +@ CHECK-DARWIN-NEXT: .long foo +@ CHECK-DARWIN: Ltmp3: +@ CHECK-DARWIN-NEXT: .long foo diff --git a/test/ThinLTO/X86/Inputs/crash_debuginfo.ll b/test/ThinLTO/X86/Inputs/crash_debuginfo.ll new file mode 100644 index 000000000000..9bb9a2fb0c5c --- /dev/null +++ b/test/ThinLTO/X86/Inputs/crash_debuginfo.ll @@ -0,0 +1,33 @@ +; ModuleID = 'test/ThinLTO/X86/Inputs/crash_debuginfo.ll' +source_filename = "src.bc" +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7.0" + +%another_type = type { i32 } + +define void @bar(i32 %arg) { + %tmp = add i32 %arg, 0, !dbg !7 + unreachable +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "Apple LLVM version 8.0.0 (clang-800.0.25.1)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !3, imports: !2) +!1 = !DIFile(filename: "2.cpp", directory: "some_dir") +!2 = !{} +!3 = !{!4} +!4 = distinct !DIGlobalVariable(name: "a_global", linkageName: "a_global", scope: null, line: 52, type: !5, isLocal: true, isDefinition: true, variable: %another_type** undef) +!5 = !DISubroutineType(types: !2) +!6 = !{i32 2, !"Debug Info Version", i32 3} +!7 = distinct !DILocation(line: 728, column: 71, scope: !8, inlinedAt: !14) +!8 = distinct !DISubprogram(name: "baz", linkageName: "baz", scope: !9, file: !1, line: 726, type: !5, isLocal: false, isDefinition: true, scopeLine: 727, flags: DIFlagPrototyped, isOptimized: true, unit: !0, declaration: !10, variables: !11) +!9 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "some_other_class", scope: !1, file: !1, line: 197, size: 192, align: 64, elements: !2, templateParams: !2, identifier: "some_other_class") +!10 = !DISubprogram(name: "baz", linkageName: "baz", scope: !9, file: !1, line: 726, type: !5, isLocal: false, isDefinition: false, scopeLine: 726, flags: DIFlagPrototyped, isOptimized: true) +!11 = !{!12} +!12 = !DILocalVariable(name: "caster", scope: !8, file: !1, line: 728, type: !13) +!13 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !8, file: !1, line: 728, size: 64, align: 64, elements: !2, identifier: "someclass") +!14 = distinct !DILocation(line: 795, column: 16, scope: !15) +!15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 794, column: 7) +!16 = distinct !DISubprogram(name: "operator()", linkageName: "some_special_function", scope: null, file: !1, line: 783, type: !5, isLocal: true, isDefinition: true, scopeLine: 784, flags: DIFlagPrototyped, isOptimized: true, unit: !0, declaration: !17, variables: !2) +!17 = !DISubprogram(name: "operator()", linkageName: "some_special_function", scope: null, file: !1, line: 783, type: !5, isLocal: false, isDefinition: false, scopeLine: 783, flags: DIFlagPrototyped, isOptimized: true) diff --git a/test/ThinLTO/X86/Inputs/import_opaque_type.ll b/test/ThinLTO/X86/Inputs/import_opaque_type.ll new file mode 100644 index 000000000000..fe2b2934724b --- /dev/null +++ b/test/ThinLTO/X86/Inputs/import_opaque_type.ll @@ -0,0 +1,15 @@ +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.11.0" + +%0 = type { i8 } + +%a = type { %0 * } + +define void @bar(%a *) { + ret void +} + +define void @baz() { + call void @bar(%a *null) + ret void +} diff --git a/test/ThinLTO/X86/crash_debuginfo.ll b/test/ThinLTO/X86/crash_debuginfo.ll new file mode 100644 index 000000000000..b250afab1ed6 --- /dev/null +++ b/test/ThinLTO/X86/crash_debuginfo.ll @@ -0,0 +1,46 @@ +; RUN: opt -module-summary -o %t-dst.bc %s +; RUN: opt -module-summary -o %t-src.bc %p/Inputs/crash_debuginfo.ll +; RUN: llvm-lto -thinlto -o %t-index %t-dst.bc %t-src.bc +; RUN: opt -function-import -inline -summary-file %t-index.thinlto.bc %t-dst.bc -o %t.out +; RUN: llvm-nm %t.out | FileCheck %s + +; Verify that we import bar and inline it. It use to crash importing due to ODR type uniquing +; CHECK-NOT: bar +; CHECK: foo +; CHECK-NOT: bar + +; ModuleID = 'test/ThinLTO/X86/crash_debuginfo.ll' +source_filename = "test/ThinLTO/X86/crash_debuginfo.ll" +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7.0" + +%some_type = type { i32 } + +define void @foo(i32 %arg) { + call void @bar(i32 %arg), !dbg !7 + unreachable +} + +declare void @bar(i32) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "Apple LLVM version 8.0.0 (clang-800.0.24.1)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2) +!1 = !DIFile(filename: "1.cpp", directory: "/another_dir") +!2 = !{!3} +!3 = distinct !DIGlobalVariable(name: "_", linkageName: "some_global", scope: null, file: !1, line: 20, type: !4, isLocal: true, isDefinition: true, variable: %some_type* undef) +!4 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "slice_nil", file: !1, line: 13, size: 64, align: 64, elements: !5, identifier: "_ZTSN5boost6python3api9slice_nilE") +!5 = !{} +!6 = !{i32 2, !"Debug Info Version", i32 3} +!7 = distinct !DILocation(line: 728, column: 71, scope: !8, inlinedAt: !15) +!8 = distinct !DISubprogram(name: "baz", linkageName: "baz", scope: !9, file: !1, line: 726, type: !10, isLocal: false, isDefinition: true, scopeLine: 727, flags: DIFlagPrototyped, isOptimized: true, unit: !0, declaration: !11, variables: !12) +!9 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "some_other_class", file: !1, line: 197, size: 192, align: 64, elements: !5, templateParams: !5, identifier: "some_other_class") +!10 = !DISubroutineType(types: !5) +!11 = !DISubprogram(name: "baz", linkageName: "baz", scope: !9, file: !1, line: 726, type: !10, isLocal: false, isDefinition: false, scopeLine: 726, flags: DIFlagPrototyped, isOptimized: true) +!12 = !{!13} +!13 = !DILocalVariable(name: "caster", scope: !8, file: !1, line: 728, type: !14) +!14 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !8, file: !1, line: 728, size: 64, align: 64, elements: !5, identifier: "someclass") +!15 = distinct !DILocation(line: 87, column: 9, scope: !16) +!16 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !9, line: 73, type: !10, isLocal: false, isDefinition: true, scopeLine: 74, flags: DIFlagPrototyped, isOptimized: true, unit: !0, declaration: !17, variables: !5) +!17 = !DISubprogram(name: "foo", linkageName: "foo", scope: !9, file: !1, line: 83, type: !10, isLocal: false, isDefinition: false, scopeLine: 83, flags: DIFlagPrototyped, isOptimized: true) diff --git a/test/ThinLTO/X86/import_opaque_type.ll b/test/ThinLTO/X86/import_opaque_type.ll new file mode 100644 index 000000000000..bfa251abacab --- /dev/null +++ b/test/ThinLTO/X86/import_opaque_type.ll @@ -0,0 +1,27 @@ +; Do setup work for all below tests: generate bitcode and combined index +; RUN: opt -module-summary %s -o %t.bc +; RUN: opt -module-summary %p/Inputs/import_opaque_type.ll -o %t2.bc +; RUN: llvm-lto -thinlto-action=thinlink -o %t3.bc %t.bc %t2.bc + +; Check that we import correctly the imported type to replace the opaque one here +; RUN: llvm-lto -thinlto-action=import %t.bc -thinlto-index=%t3.bc -o - | llvm-dis -o - | FileCheck %s + + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.11.0" + +; CHECK: %0 = type { i8 } +%0 = type opaque + +%a = type { %0 * } + +declare void @baz() +define void @foo(%a *) { + call void @baz() + ret void +} + +define i32 @main() { + call void @foo(%a *null) + ret i32 0 +} diff --git a/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll b/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll new file mode 100644 index 000000000000..3f8fdcc8eafb --- /dev/null +++ b/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll @@ -0,0 +1,42 @@ +; RUN: opt < %s -basicaa -gvn -S | FileCheck %s + +declare void @llvm.masked.scatter.v2i32(<2 x i32> , <2 x i32*> , i32 , <2 x i1> ) +declare <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*>, i32, <2 x i1>, <2 x i32>) + +; This test ensures that masked scatter and gather operations, which take vectors of pointers, +; do not have pointer aliasing ignored when being processed. +; No scatter/gather calls should end up eliminated +; CHECK: llvm.masked.gather +; CHECK: llvm.masked.gather +; CHECK: llvm.masked.scatter +; CHECK: llvm.masked.gather +; CHECK: llvm.masked.scatter +; CHECK: llvm.masked.gather +define spir_kernel void @test(<2 x i32*> %in1, <2 x i32*> %in2, i32* %out) { +entry: + ; Just some temporary storage + %tmp.0 = alloca i32 + %tmp.1 = alloca i32 + %tmp.i = insertelement <2 x i32*> undef, i32* %tmp.0, i32 0 + %tmp = insertelement <2 x i32*> %tmp.i, i32* %tmp.1, i32 1 + ; Read from in1 and in2 + %in1.v = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %in1, i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) #1 + %in2.v = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %in2, i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) #1 + ; Store in1 to the allocas + call void @llvm.masked.scatter.v2i32(<2 x i32> %in1.v, <2 x i32*> %tmp, i32 1, <2 x i1> <i1 true, i1 true>); + ; Read in1 from the allocas + ; This gather should alias the scatter we just saw + %tmp.v.0 = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %tmp, i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) #1 + ; Store in2 to the allocas + call void @llvm.masked.scatter.v2i32(<2 x i32> %in2.v, <2 x i32*> %tmp, i32 1, <2 x i1> <i1 true, i1 true>); + ; Read in2 from the allocas + ; This gather should alias the scatter we just saw, and not be eliminated + %tmp.v.1 = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %tmp, i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) #1 + ; Store in2 to out for good measure + %tmp.v.1.0 = extractelement <2 x i32> %tmp.v.1, i32 0 + %tmp.v.1.1 = extractelement <2 x i32> %tmp.v.1, i32 1 + store i32 %tmp.v.1.0, i32* %out + %out.1 = getelementptr i32, i32* %out, i32 1 + store i32 %tmp.v.1.1, i32* %out.1 + ret void +} diff --git a/test/Transforms/JumpThreading/pr27840.ll b/test/Transforms/JumpThreading/pr27840.ll new file mode 100644 index 000000000000..cbee2af67fae --- /dev/null +++ b/test/Transforms/JumpThreading/pr27840.ll @@ -0,0 +1,33 @@ +; RUN: opt -jump-threading -S < %s | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.11.0" + +declare void @helper() +declare i32 @__gxx_personality_v0(...) + + +define void @pr27840(i8* %call, i1 %A) personality i32(...)* @__gxx_personality_v0 { +entry: + invoke void @helper() + to label %invoke.cont unwind label %lpad + +; Don't jump threading; we can't split the critical edge from entry to lpad. +; CHECK-LABEL: @pr27840 +; CHECK: invoke +; CHECK-NEXT: to label %invoke.cont unwind label %lpad + +invoke.cont: + invoke void @helper() + to label %nowhere unwind label %lpad + +lpad: + %b = phi i1 [ true, %invoke.cont ], [ false, %entry ] + landingpad { i8*, i32 } + cleanup + %xor = xor i1 %b, %A + br i1 %xor, label %nowhere, label %invoke.cont + +nowhere: + unreachable +} diff --git a/test/Transforms/LoopVectorize/runtime-check-readonly.ll b/test/Transforms/LoopVectorize/runtime-check-readonly.ll index a3b5a598d220..e91d5b84324d 100644 --- a/test/Transforms/LoopVectorize/runtime-check-readonly.ll +++ b/test/Transforms/LoopVectorize/runtime-check-readonly.ll @@ -8,10 +8,10 @@ target triple = "x86_64-apple-macosx10.8.0" ;CHECK: br ;CHECK: getelementptr ;CHECK-DAG: getelementptr -;CHECK-DAG: icmp uge -;CHECK-DAG: icmp uge -;CHECK-DAG: icmp uge -;CHECK-DAG: icmp uge +;CHECK-DAG: icmp ugt +;CHECK-DAG: icmp ugt +;CHECK-DAG: icmp ugt +;CHECK-DAG: icmp ugt ;CHECK-DAG: and ;CHECK-DAG: and ;CHECK: br diff --git a/test/Transforms/LoopVectorize/tbaa-nodep.ll b/test/Transforms/LoopVectorize/tbaa-nodep.ll index 06d000230027..3e79d47de08c 100644 --- a/test/Transforms/LoopVectorize/tbaa-nodep.ll +++ b/test/Transforms/LoopVectorize/tbaa-nodep.ll @@ -36,7 +36,7 @@ for.end: ; preds = %for.body ; CHECK: ret i32 0 ; CHECK-NOTBAA-LABEL: @test1 -; CHECK-NOTBAA: icmp uge i32* +; CHECK-NOTBAA: icmp ugt i32* ; CHECK-NOTBAA: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa ; CHECK-NOTBAA: store <4 x i32> %{{.*}}, <4 x i32>* %{{.*}}, align 4, !tbaa @@ -70,8 +70,8 @@ for.end: ; preds = %for.body ; required. Without TBAA, however, two checks are required. ; CHECK-LABEL: @test2 -; CHECK: icmp uge float* -; CHECK: icmp uge float* +; CHECK: icmp ugt float* +; CHECK: icmp ugt float* ; CHECK-NOT: icmp uge i32* ; CHECK: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa @@ -80,10 +80,10 @@ for.end: ; preds = %for.body ; CHECK: ret i32 0 ; CHECK-NOTBAA-LABEL: @test2 -; CHECK-NOTBAA: icmp uge float* -; CHECK-NOTBAA: icmp uge float* -; CHECK-NOTBAA-DAG: icmp uge float* -; CHECK-NOTBAA-DAG: icmp uge i32* +; CHECK-NOTBAA: icmp ugt float* +; CHECK-NOTBAA: icmp ugt float* +; CHECK-NOTBAA-DAG: icmp ugt float* +; CHECK-NOTBAA-DAG: icmp ugt i32* ; CHECK-NOTBAA: load <4 x float>, <4 x float>* %{{.*}}, align 4, !tbaa ; CHECK-NOTBAA: store <4 x float> %{{.*}}, <4 x float>* %{{.*}}, align 4, !tbaa diff --git a/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll b/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll index 9eacbde7710a..022ea734cec2 100644 --- a/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll +++ b/test/Transforms/LoopVersioningLICM/loopversioningLICM1.ll @@ -8,15 +8,15 @@ ; CHECK-NEXT: Loop Versioning found to be beneficial ; ; CHECK: for.body3: -; CHECK-NEXT: %add86 = phi i32 [ %arrayidx7.promoted, %for.body3.ph ], [ %add8, %for.body3 ] +; CHECK-NEXT: %[[induction:.*]] = phi i32 [ %arrayidx7.promoted, %for.body3.ph ], [ %add8, %for.body3 ] ; CHECK-NEXT: %j.113 = phi i32 [ %j.016, %for.body3.ph ], [ %inc, %for.body3 ] ; CHECK-NEXT: %idxprom = zext i32 %j.113 to i64 ; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, i32* %var1, i64 %idxprom ; CHECK-NEXT: store i32 %add, i32* %arrayidx, align 4, !alias.scope !6, !noalias !6 -; CHECK-NEXT: %add8 = add nsw i32 %add86, %add +; CHECK-NEXT: %add8 = add nsw i32 %[[induction]], %add ; CHECK-NEXT: %inc = add nuw i32 %j.113, 1 ; CHECK-NEXT: %cmp2 = icmp ult i32 %inc, %itr -; CHECK-NEXT: br i1 %cmp2, label %for.body3, label %for.inc11.loopexit.loopexit5, !llvm.loop !7 +; CHECK-NEXT: br i1 %cmp2, label %for.body3, label %for.inc11.loopexit.loopexit6, !llvm.loop !7 define i32 @foo(i32* nocapture %var1, i32* nocapture readnone %var2, i32* nocapture %var3, i32 %itr) #0 { entry: %cmp14 = icmp eq i32 %itr, 0 |
