diff options
author | dim <dim@FreeBSD.org> | 2012-04-14 13:54:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-04-14 13:54:10 +0000 |
commit | 1fc08f5e9ef733ef1ce6f363fecedc2260e78974 (patch) | |
tree | 19c69a04768629f2d440944b71cbe90adae0b615 /test/CodeGen/X86 | |
parent | 07637c87f826cdf411f0673595e9bc92ebd793f2 (diff) | |
download | FreeBSD-src-1fc08f5e9ef733ef1ce6f363fecedc2260e78974.zip FreeBSD-src-1fc08f5e9ef733ef1ce6f363fecedc2260e78974.tar.gz |
Vendor import of llvm trunk r154661:
http://llvm.org/svn/llvm-project/llvm/trunk@r154661
Diffstat (limited to 'test/CodeGen/X86')
319 files changed, 10771 insertions, 2383 deletions
diff --git a/test/CodeGen/X86/2004-04-09-SameValueCoalescing.ll b/test/CodeGen/X86/2004-04-09-SameValueCoalescing.ll deleted file mode 100644 index c62fee1..0000000 --- a/test/CodeGen/X86/2004-04-09-SameValueCoalescing.ll +++ /dev/null @@ -1,13 +0,0 @@ -; Linear scan does not currently coalesce any two variables that have -; overlapping live intervals. When two overlapping intervals have the same -; value, they can be joined though. -; -; RUN: llc < %s -march=x86 -regalloc=linearscan | \ -; RUN: not grep {mov %\[A-Z\]\\\{2,3\\\}, %\[A-Z\]\\\{2,3\\\}} - -define i64 @test(i64 %x) { -entry: - %tmp.1 = mul i64 %x, 4294967297 ; <i64> [#uses=1] - ret i64 %tmp.1 -} - diff --git a/test/CodeGen/X86/2006-05-11-InstrSched.ll b/test/CodeGen/X86/2006-05-11-InstrSched.ll index a871ea1..38bca28 100644 --- a/test/CodeGen/X86/2006-05-11-InstrSched.ll +++ b/test/CodeGen/X86/2006-05-11-InstrSched.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu -mattr=+sse2 -stats -realign-stack=0 |&\ -; RUN: grep {asm-printer} | grep 34 +; RUN: grep {asm-printer} | grep 35 target datalayout = "e-p:32:32" define void @foo(i32* %mc, i32* %bp, i32* %ms, i32* %xmb, i32* %mpp, i32* %tpmm, i32* %ip, i32* %tpim, i32* %dpp, i32* %tpdm, i32* %bpi, i32 %M) nounwind { @@ -30,7 +30,7 @@ cond_true: ; preds = %cond_true, %entry %tmp87 = bitcast <16 x i8> %tmp66 to <4 x i32> ; <<4 x i32>> [#uses=1] %tmp88 = add <4 x i32> %tmp87, %tmp77 ; <<4 x i32>> [#uses=2] %tmp88.upgrd.4 = bitcast <4 x i32> %tmp88 to <2 x i64> ; <<2 x i64>> [#uses=1] - %tmp99 = tail call <4 x i32> @llvm.x86.sse2.pcmpgt.d( <4 x i32> %tmp88, <4 x i32> %tmp55 ) ; <<4 x i32>> [#uses=1] + %tmp99 = tail call <4 x i32> @llvm.x86.sse2.psra.d( <4 x i32> %tmp88, <4 x i32> %tmp55 ) ; <<4 x i32>> [#uses=1] %tmp99.upgrd.5 = bitcast <4 x i32> %tmp99 to <2 x i64> ; <<2 x i64>> [#uses=2] %tmp110 = xor <2 x i64> %tmp99.upgrd.5, < i64 -1, i64 -1 > ; <<2 x i64>> [#uses=1] %tmp111 = and <2 x i64> %tmp110, %tmp55.upgrd.2 ; <<2 x i64>> [#uses=1] @@ -48,4 +48,4 @@ return: ; preds = %cond_true, %entry ret void } -declare <4 x i32> @llvm.x86.sse2.pcmpgt.d(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.x86.sse2.psra.d(<4 x i32>, <4 x i32>) diff --git a/test/CodeGen/X86/2007-01-08-InstrSched.ll b/test/CodeGen/X86/2007-01-08-InstrSched.ll index 6f8b89c..24aa5b9 100644 --- a/test/CodeGen/X86/2007-01-08-InstrSched.ll +++ b/test/CodeGen/X86/2007-01-08-InstrSched.ll @@ -1,5 +1,5 @@ ; PR1075 -; RUN: llc < %s -mtriple=x86_64-apple-darwin -O3 | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-apple-darwin -O3 | FileCheck %s define float @foo(float %x) nounwind { %tmp1 = fmul float %x, 3.000000e+00 diff --git a/test/CodeGen/X86/2007-05-05-Personality.ll b/test/CodeGen/X86/2007-05-05-Personality.ll index d1fc70d..7d21b71 100644 --- a/test/CodeGen/X86/2007-05-05-Personality.ll +++ b/test/CodeGen/X86/2007-05-05-Personality.ll @@ -10,9 +10,10 @@ entry: invoke void @raise() to label %eh_then unwind label %unwind -unwind: ; preds = %entry - %eh_ptr = tail call i8* @llvm.eh.exception() - %eh_select = tail call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %eh_ptr, i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*), i8* @error) +unwind: ; preds = %entry + %eh_ptr = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gnat_eh_personality to i8*) + catch i8* @error + %eh_select = extractvalue { i8*, i32 } %eh_ptr, 1 %eh_typeid = tail call i32 @llvm.eh.typeid.for(i8* @error) %tmp2 = icmp eq i32 %eh_select, %eh_typeid br i1 %tmp2, label %eh_then, label %Unwind @@ -21,16 +22,11 @@ eh_then: ; preds = %unwind, %entry ret void Unwind: ; preds = %unwind - %0 = tail call i32 (...)* @_Unwind_Resume(i8* %eh_ptr) - unreachable + resume { i8*, i32 } %eh_ptr } declare void @raise() -declare i8* @llvm.eh.exception() nounwind readonly - -declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind - declare i32 @llvm.eh.typeid.for(i8*) nounwind declare i32 @__gnat_eh_personality(...) diff --git a/test/CodeGen/X86/2007-11-06-InstrSched.ll b/test/CodeGen/X86/2007-11-06-InstrSched.ll index f6db0d0..838a0c3 100644 --- a/test/CodeGen/X86/2007-11-06-InstrSched.ll +++ b/test/CodeGen/X86/2007-11-06-InstrSched.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 | not grep lea +; RUN: llc < %s -march=x86 -mcpu=generic -mattr=+sse2 | not grep lea define float @foo(i32* %x, float* %y, i32 %c) nounwind { entry: diff --git a/test/CodeGen/X86/2007-12-18-LoadCSEBug.ll b/test/CodeGen/X86/2007-12-18-LoadCSEBug.ll index 265d968..2e95082 100644 --- a/test/CodeGen/X86/2007-12-18-LoadCSEBug.ll +++ b/test/CodeGen/X86/2007-12-18-LoadCSEBug.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 | grep {(%esp)} | count 2 +; RUN: llc < %s -march=x86 -mcpu=generic | grep {(%esp)} | count 2 ; PR1872 %struct.c34007g__designated___XUB = type { i32, i32, i32, i32 } diff --git a/test/CodeGen/X86/2008-01-16-Trampoline.ll b/test/CodeGen/X86/2008-01-16-Trampoline.ll deleted file mode 100644 index 704b2ba..0000000 --- a/test/CodeGen/X86/2008-01-16-Trampoline.ll +++ /dev/null @@ -1,14 +0,0 @@ -; RUN: llc < %s -march=x86 -; RUN: llc < %s -march=x86-64 - - %struct.FRAME.gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets = type { i32, i32, void (i32, i32)*, i8 (i32, i32)* } - -define fastcc i32 @gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets.5146(i64 %table.0.0, i64 %table.0.1, i32 %last, i32 %pos) { -entry: - %tramp22 = call i8* @llvm.init.trampoline( i8* null, i8* bitcast (void (%struct.FRAME.gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets*, i32, i32)* @gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets__move.5177 to i8*), i8* null ) ; <i8*> [#uses=0] - unreachable -} - -declare void @gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets__move.5177(%struct.FRAME.gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets* nest , i32, i32) nounwind - -declare i8* @llvm.init.trampoline(i8*, i8*, i8*) nounwind diff --git a/test/CodeGen/X86/2008-02-22-ReMatBug.ll b/test/CodeGen/X86/2008-02-22-ReMatBug.ll deleted file mode 100644 index 8f4d353..0000000 --- a/test/CodeGen/X86/2008-02-22-ReMatBug.ll +++ /dev/null @@ -1,49 +0,0 @@ -; RUN: llc < %s -march=x86 -stats -regalloc=linearscan |& grep {Number of re-materialization} | grep 2 -; rdar://5761454 - - %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* } - -define %struct.quad_struct* @MakeTree(i32 %size, i32 %center_x, i32 %center_y, i32 %lo_proc, i32 %hi_proc, %struct.quad_struct* %parent, i32 %ct, i32 %level) nounwind { -entry: - br i1 true, label %bb43.i, label %bb.i - -bb.i: ; preds = %entry - ret %struct.quad_struct* null - -bb43.i: ; preds = %entry - br i1 true, label %CheckOutside.exit40.i, label %bb11.i38.i - -bb11.i38.i: ; preds = %bb43.i - ret %struct.quad_struct* null - -CheckOutside.exit40.i: ; preds = %bb43.i - br i1 true, label %CheckOutside.exit30.i, label %bb11.i28.i - -bb11.i28.i: ; preds = %CheckOutside.exit40.i - ret %struct.quad_struct* null - -CheckOutside.exit30.i: ; preds = %CheckOutside.exit40.i - br i1 true, label %CheckOutside.exit20.i, label %bb11.i18.i - -bb11.i18.i: ; preds = %CheckOutside.exit30.i - ret %struct.quad_struct* null - -CheckOutside.exit20.i: ; preds = %CheckOutside.exit30.i - br i1 true, label %bb34, label %bb11.i8.i - -bb11.i8.i: ; preds = %CheckOutside.exit20.i - ret %struct.quad_struct* null - -bb34: ; preds = %CheckOutside.exit20.i - %tmp15.reg2mem.0 = sdiv i32 %size, 2 ; <i32> [#uses=7] - %tmp85 = sub i32 %center_y, %tmp15.reg2mem.0 ; <i32> [#uses=2] - %tmp88 = sub i32 %center_x, %tmp15.reg2mem.0 ; <i32> [#uses=2] - %tmp92 = tail call %struct.quad_struct* @MakeTree( i32 %tmp15.reg2mem.0, i32 %tmp88, i32 %tmp85, i32 0, i32 %hi_proc, %struct.quad_struct* null, i32 2, i32 0 ) nounwind ; <%struct.quad_struct*> [#uses=0] - %tmp99 = add i32 0, %hi_proc ; <i32> [#uses=1] - %tmp100 = sdiv i32 %tmp99, 2 ; <i32> [#uses=1] - %tmp110 = tail call %struct.quad_struct* @MakeTree( i32 %tmp15.reg2mem.0, i32 0, i32 %tmp85, i32 0, i32 %tmp100, %struct.quad_struct* null, i32 3, i32 0 ) nounwind ; <%struct.quad_struct*> [#uses=0] - %tmp122 = add i32 %tmp15.reg2mem.0, %center_y ; <i32> [#uses=2] - %tmp129 = tail call %struct.quad_struct* @MakeTree( i32 %tmp15.reg2mem.0, i32 0, i32 %tmp122, i32 0, i32 0, %struct.quad_struct* null, i32 1, i32 0 ) nounwind ; <%struct.quad_struct*> [#uses=0] - %tmp147 = tail call %struct.quad_struct* @MakeTree( i32 %tmp15.reg2mem.0, i32 %tmp88, i32 %tmp122, i32 %lo_proc, i32 0, %struct.quad_struct* null, i32 0, i32 0 ) nounwind ; <%struct.quad_struct*> [#uses=0] - unreachable -} diff --git a/test/CodeGen/X86/2008-03-18-CoalescerBug.ll b/test/CodeGen/X86/2008-03-18-CoalescerBug.ll deleted file mode 100644 index 33d658c..0000000 --- a/test/CodeGen/X86/2008-03-18-CoalescerBug.ll +++ /dev/null @@ -1,51 +0,0 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin -mattr=+sse2 -disable-fp-elim -regalloc=linearscan | grep movss | count 1 -; RUN: llc < %s -mtriple=i386-apple-darwin -mattr=+sse2 -disable-fp-elim -regalloc=linearscan -stats |& grep {Number of re-materialization} | grep 1 - - %struct..0objc_object = type opaque - %struct.OhBoy = type { } - %struct.BooHoo = type { i32 } - %struct.objc_selector = type opaque -@llvm.used = appending global [1 x i8*] [ i8* bitcast (void (%struct.OhBoy*, %struct.objc_selector*, i32, %struct.BooHoo*)* @"-[MessageHeaderDisplay adjustFontSizeBy:viewingState:]" to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] - -define void @"-[MessageHeaderDisplay adjustFontSizeBy:viewingState:]"(%struct.OhBoy* %self, %struct.objc_selector* %_cmd, i32 %delta, %struct.BooHoo* %viewingState) nounwind { -entry: - %tmp19 = load i32* null, align 4 ; <i32> [#uses=1] - %tmp24 = tail call float bitcast (void (%struct..0objc_object*, ...)* @objc_msgSend_fpret to float (%struct..0objc_object*, %struct.objc_selector*)*)( %struct..0objc_object* null, %struct.objc_selector* null ) nounwind ; <float> [#uses=2] - %tmp30 = icmp sgt i32 %delta, 0 ; <i1> [#uses=1] - br i1 %tmp30, label %bb33, label %bb87.preheader -bb33: ; preds = %entry - %tmp28 = fadd float 0.000000e+00, %tmp24 ; <float> [#uses=1] - %tmp35 = fcmp ogt float %tmp28, 1.800000e+01 ; <i1> [#uses=1] - br i1 %tmp35, label %bb38, label %bb87.preheader -bb38: ; preds = %bb33 - %tmp53 = add i32 %tmp19, %delta ; <i32> [#uses=2] - br label %bb43 -bb43: ; preds = %bb38 - store i32 %tmp53, i32* null, align 4 - ret void -bb50: ; preds = %bb38 - %tmp56 = fsub float 1.800000e+01, %tmp24 ; <float> [#uses=1] - %tmp57 = fcmp ugt float 0.000000e+00, %tmp56 ; <i1> [#uses=1] - br i1 %tmp57, label %bb64, label %bb87.preheader -bb64: ; preds = %bb50 - ret void -bb87.preheader: ; preds = %bb50, %bb33, %entry - %usableDelta.0 = phi i32 [ %delta, %entry ], [ %delta, %bb33 ], [ %tmp53, %bb50 ] ; <i32> [#uses=1] - %tmp100 = tail call %struct..0objc_object* (%struct..0objc_object*, %struct.objc_selector*, ...)* @objc_msgSend( %struct..0objc_object* null, %struct.objc_selector* null, %struct..0objc_object* null ) nounwind ; <%struct..0objc_object*> [#uses=2] - %tmp106 = tail call %struct..0objc_object* (%struct..0objc_object*, %struct.objc_selector*, ...)* @objc_msgSend( %struct..0objc_object* %tmp100, %struct.objc_selector* null ) nounwind ; <%struct..0objc_object*> [#uses=0] - %umax = select i1 false, i32 1, i32 0 ; <i32> [#uses=1] - br label %bb108 -bb108: ; preds = %bb108, %bb87.preheader - %attachmentIndex.0.reg2mem.0 = phi i32 [ 0, %bb87.preheader ], [ %indvar.next, %bb108 ] ; <i32> [#uses=2] - %tmp114 = tail call %struct..0objc_object* (%struct..0objc_object*, %struct.objc_selector*, ...)* @objc_msgSend( %struct..0objc_object* %tmp100, %struct.objc_selector* null, i32 %attachmentIndex.0.reg2mem.0 ) nounwind ; <%struct..0objc_object*> [#uses=1] - %tmp121 = tail call %struct..0objc_object* (%struct..0objc_object*, %struct.objc_selector*, ...)* @objc_msgSend( %struct..0objc_object* %tmp114, %struct.objc_selector* null, i32 %usableDelta.0 ) nounwind ; <%struct..0objc_object*> [#uses=0] - %indvar.next = add i32 %attachmentIndex.0.reg2mem.0, 1 ; <i32> [#uses=2] - %exitcond = icmp eq i32 %indvar.next, %umax ; <i1> [#uses=1] - br i1 %exitcond, label %bb130, label %bb108 -bb130: ; preds = %bb108 - ret void -} - -declare %struct..0objc_object* @objc_msgSend(%struct..0objc_object*, %struct.objc_selector*, ...) - -declare void @objc_msgSend_fpret(%struct..0objc_object*, ...) diff --git a/test/CodeGen/X86/2008-05-21-CoalescerBug.ll b/test/CodeGen/X86/2008-05-21-CoalescerBug.ll index e5dda4a..ac167b0 100644 --- a/test/CodeGen/X86/2008-05-21-CoalescerBug.ll +++ b/test/CodeGen/X86/2008-05-21-CoalescerBug.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -O0 -fast-isel=false -regalloc=linearscan | grep mov | count 5 +; RUN: llc < %s -march=x86 -O0 -fast-isel=false -optimize-regalloc -regalloc=basic | grep mov | count 5 ; PR2343 %llvm.dbg.anchor.type = type { i32, i32 } diff --git a/test/CodeGen/X86/2008-05-28-LocalRegAllocBug.ll b/test/CodeGen/X86/2008-05-28-LocalRegAllocBug.ll index 0d11546..c068f8a 100644 --- a/test/CodeGen/X86/2008-05-28-LocalRegAllocBug.ll +++ b/test/CodeGen/X86/2008-05-28-LocalRegAllocBug.ll @@ -2,8 +2,6 @@ @_ZTVN10Evaluation10GridOutputILi3EEE = external constant [5 x i32 (...)*] ; <[5 x i32 (...)*]*> [#uses=1] -declare i8* @llvm.eh.exception() nounwind - declare i8* @_Znwm(i32) declare i8* @__cxa_begin_catch(i8*) nounwind diff --git a/test/CodeGen/X86/2008-06-13-NotVolatileLoadStore.ll b/test/CodeGen/X86/2008-06-13-NotVolatileLoadStore.ll index 90af387..a6234d3 100644 --- a/test/CodeGen/X86/2008-06-13-NotVolatileLoadStore.ll +++ b/test/CodeGen/X86/2008-06-13-NotVolatileLoadStore.ll @@ -1,7 +1,7 @@ ; RUN: llc < %s -march=x86 | not grep movsd ; RUN: llc < %s -march=x86 | grep movw ; RUN: llc < %s -march=x86 | grep addw -; These transforms are turned off for volatile loads and stores. +; These transforms are turned off for load volatiles and stores. ; Check that they weren't turned off for all loads and stores! @atomic = global double 0.000000e+00 ; <double*> [#uses=1] diff --git a/test/CodeGen/X86/2008-06-13-VolatileLoadStore.ll b/test/CodeGen/X86/2008-06-13-VolatileLoadStore.ll index 8665282..037559e 100644 --- a/test/CodeGen/X86/2008-06-13-VolatileLoadStore.ll +++ b/test/CodeGen/X86/2008-06-13-VolatileLoadStore.ll @@ -8,13 +8,13 @@ define i16 @f(i64 %x, double %y) { %b = bitcast i64 %x to double ; <double> [#uses=1] - volatile store double %b, double* @atomic ; one processor operation only - volatile store double 0.000000e+00, double* @atomic2 ; one processor operation only + store volatile double %b, double* @atomic ; one processor operation only + store volatile double 0.000000e+00, double* @atomic2 ; one processor operation only %b2 = bitcast double %y to i64 ; <i64> [#uses=1] - volatile store i64 %b2, i64* @anything ; may transform to store of double - %l = volatile load i32* @ioport ; must not narrow + store volatile i64 %b2, i64* @anything ; may transform to store of double + %l = load volatile i32* @ioport ; must not narrow %t = trunc i32 %l to i16 ; <i16> [#uses=1] - %l2 = volatile load i32* @ioport ; must not narrow + %l2 = load volatile i32* @ioport ; must not narrow %tmp = lshr i32 %l2, 16 ; <i32> [#uses=1] %t2 = trunc i32 %tmp to i16 ; <i16> [#uses=1] %f = add i16 %t, %t2 ; <i16> [#uses=1] diff --git a/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll b/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll index 101b3c5..f0d46a0 100644 --- a/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll +++ b/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mcpu=core2 | grep pxor | count 2 -; RUN: llc < %s -mcpu=core2 | not grep movapd +; RUN: llc < %s -mcpu=core2 | grep xorps | count 2 +; RUN: llc < %s -mcpu=core2 | not grep movap ; PR2715 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" diff --git a/test/CodeGen/X86/2008-09-05-sinttofp-2xi32.ll b/test/CodeGen/X86/2008-09-05-sinttofp-2xi32.ll index 2dc1dea..757f1ff 100644 --- a/test/CodeGen/X86/2008-09-05-sinttofp-2xi32.ll +++ b/test/CodeGen/X86/2008-09-05-sinttofp-2xi32.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 -mattr=+mmx | grep unpcklpd -; RUN: llc < %s -march=x86 -mattr=+sse2 -mattr=+mmx | grep unpckhpd +; RUN: llc < %s -march=x86 -mattr=+sse2 -mattr=+mmx | not grep unpcklpd +; RUN: llc < %s -march=x86 -mattr=+sse2 -mattr=+mmx | not grep unpckhpd ; RUN: llc < %s -march=x86 -mattr=+sse2 | grep cvttpd2pi | count 1 ; RUN: llc < %s -march=x86 -mattr=+sse2 | grep cvtpi2pd | count 1 ; originally from PR2687, but things don't work that way any more. diff --git a/test/CodeGen/X86/2008-09-18-inline-asm-2.ll b/test/CodeGen/X86/2008-09-18-inline-asm-2.ll index 511c7b5..6867ae7 100644 --- a/test/CodeGen/X86/2008-09-18-inline-asm-2.ll +++ b/test/CodeGen/X86/2008-09-18-inline-asm-2.ll @@ -1,4 +1,3 @@ -; RUN: llc < %s -march=x86 -regalloc=linearscan | FileCheck %s ; RUN: llc < %s -march=x86 -regalloc=fast | FileCheck %s ; RUN: llc < %s -march=x86 -regalloc=basic | FileCheck %s ; RUN: llc < %s -march=x86 -regalloc=greedy | FileCheck %s diff --git a/test/CodeGen/X86/2008-09-29-VolatileBug.ll b/test/CodeGen/X86/2008-09-29-VolatileBug.ll index 935c4c5..f35245b 100644 --- a/test/CodeGen/X86/2008-09-29-VolatileBug.ll +++ b/test/CodeGen/X86/2008-09-29-VolatileBug.ll @@ -6,7 +6,7 @@ define i32 @main() nounwind { entry: - %0 = volatile load i32* @g_407, align 4 ; <i32> [#uses=1] + %0 = load volatile i32* @g_407, align 4 ; <i32> [#uses=1] %1 = trunc i32 %0 to i8 ; <i8> [#uses=1] %2 = tail call i32 @func_45(i8 zeroext %1) nounwind ; <i32> [#uses=0] ret i32 0 diff --git a/test/CodeGen/X86/2008-12-16-BadShift.ll b/test/CodeGen/X86/2008-12-16-BadShift.ll deleted file mode 100644 index 6c70c5b..0000000 --- a/test/CodeGen/X86/2008-12-16-BadShift.ll +++ /dev/null @@ -1,19 +0,0 @@ -; RUN: llc < %s | not grep shrl -; Note: this test is really trying to make sure that the shift -; returns the right result; shrl is most likely wrong, -; but if CodeGen starts legitimately using an shrl here, -; please adjust the test appropriately. - -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" -target triple = "i386-pc-linux-gnu" -@.str = internal constant [6 x i8] c"%lld\0A\00" ; <[6 x i8]*> [#uses=1] - -define i64 @mebbe_shift(i32 %xx, i32 %test) nounwind { -entry: - %conv = zext i32 %xx to i64 ; <i64> [#uses=1] - %tobool = icmp ne i32 %test, 0 ; <i1> [#uses=1] - %shl = select i1 %tobool, i64 3, i64 0 ; <i64> [#uses=1] - %x.0 = shl i64 %conv, %shl ; <i64> [#uses=1] - ret i64 %x.0 -} - diff --git a/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll b/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll index 75e0b8a..435adbb 100644 --- a/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll +++ b/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin -asm-verbose=0 | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=i386-apple-darwin -asm-verbose=0 | FileCheck %s ; PR3149 ; Make sure the copy after inline asm is not coalesced away. diff --git a/test/CodeGen/X86/2009-01-31-BigShift2.ll b/test/CodeGen/X86/2009-01-31-BigShift2.ll index 9d24084..3e42553 100644 --- a/test/CodeGen/X86/2009-01-31-BigShift2.ll +++ b/test/CodeGen/X86/2009-01-31-BigShift2.ll @@ -6,6 +6,6 @@ define void @test(<8 x double>* %P, i64* %Q) nounwind { %B = bitcast <8 x double> %A to i512 ; <i512> [#uses=1] %C = lshr i512 %B, 448 ; <i512> [#uses=1] %D = trunc i512 %C to i64 ; <i64> [#uses=1] - volatile store i64 %D, i64* %Q + store volatile i64 %D, i64* %Q ret void } diff --git a/test/CodeGen/X86/2009-02-05-CoalescerBug.ll b/test/CodeGen/X86/2009-02-05-CoalescerBug.ll deleted file mode 100644 index a46a20b..0000000 --- a/test/CodeGen/X86/2009-02-05-CoalescerBug.ll +++ /dev/null @@ -1,14 +0,0 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2,-sse41 -o %t -; RUN: grep movss %t | count 2 -; RUN: grep movaps %t | count 2 -; RUN: grep movdqa %t | count 2 - -define i1 @t([2 x float]* %y, [2 x float]* %w, i32, [2 x float]* %x.pn59, i32 %smax190, i32 %j.1180, <4 x float> %wu.2179, <4 x float> %wr.2178, <4 x float>* %tmp89.out, <4 x float>* %tmp107.out, i32* %indvar.next218.out) nounwind { -newFuncRoot: - %tmp82 = insertelement <4 x float> %wr.2178, float 0.000000e+00, i32 0 ; <<4 x float>> [#uses=1] - %tmp85 = insertelement <4 x float> %tmp82, float 0.000000e+00, i32 1 ; <<4 x float>> [#uses=1] - %tmp87 = insertelement <4 x float> %tmp85, float 0.000000e+00, i32 2 ; <<4 x float>> [#uses=1] - %tmp89 = insertelement <4 x float> %tmp87, float 0.000000e+00, i32 3 ; <<4 x float>> [#uses=1] - store <4 x float> %tmp89, <4 x float>* %tmp89.out - ret i1 false -} diff --git a/test/CodeGen/X86/2009-03-16-SpillerBug.ll b/test/CodeGen/X86/2009-03-16-SpillerBug.ll deleted file mode 100644 index 951e191..0000000 --- a/test/CodeGen/X86/2009-03-16-SpillerBug.ll +++ /dev/null @@ -1,167 +0,0 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin -regalloc=linearscan -stats |& grep virtregrewriter | not grep {stores unfolded} -; rdar://6682365 - -; Do not clobber a register if another spill slot is available in it and it's marked "do not clobber". - - %struct.CAST_KEY = type { [32 x i32], i32 } -@CAST_S_table0 = constant [2 x i32] [i32 821772500, i32 -1616838901], align 32 ; <[2 x i32]*> [#uses=0] -@CAST_S_table4 = constant [2 x i32] [i32 2127105028, i32 745436345], align 32 ; <[2 x i32]*> [#uses=6] -@CAST_S_table5 = constant [2 x i32] [i32 -151351395, i32 749497569], align 32 ; <[2 x i32]*> [#uses=5] -@CAST_S_table6 = constant [2 x i32] [i32 -2048901095, i32 858518887], align 32 ; <[2 x i32]*> [#uses=4] -@CAST_S_table7 = constant [2 x i32] [i32 -501862387, i32 -1143078916], align 32 ; <[2 x i32]*> [#uses=5] -@CAST_S_table1 = constant [2 x i32] [i32 522195092, i32 -284448933], align 32 ; <[2 x i32]*> [#uses=0] -@CAST_S_table2 = constant [2 x i32] [i32 -1913667008, i32 637164959], align 32 ; <[2 x i32]*> [#uses=0] -@CAST_S_table3 = constant [2 x i32] [i32 -1649212384, i32 532081118], align 32 ; <[2 x i32]*> [#uses=0] - -define void @CAST_set_key(%struct.CAST_KEY* nocapture %key, i32 %len, i8* nocapture %data) nounwind ssp { -bb1.thread: - %0 = getelementptr [16 x i32]* null, i32 0, i32 5 ; <i32*> [#uses=1] - %1 = getelementptr [16 x i32]* null, i32 0, i32 8 ; <i32*> [#uses=1] - %2 = load i32* null, align 4 ; <i32> [#uses=1] - %3 = shl i32 %2, 24 ; <i32> [#uses=1] - %4 = load i32* null, align 4 ; <i32> [#uses=1] - %5 = shl i32 %4, 16 ; <i32> [#uses=1] - %6 = load i32* null, align 4 ; <i32> [#uses=1] - %7 = or i32 %5, %3 ; <i32> [#uses=1] - %8 = or i32 %7, %6 ; <i32> [#uses=1] - %9 = or i32 %8, 0 ; <i32> [#uses=1] - %10 = load i32* null, align 4 ; <i32> [#uses=1] - %11 = shl i32 %10, 24 ; <i32> [#uses=1] - %12 = load i32* %0, align 4 ; <i32> [#uses=1] - %13 = shl i32 %12, 16 ; <i32> [#uses=1] - %14 = load i32* null, align 4 ; <i32> [#uses=1] - %15 = or i32 %13, %11 ; <i32> [#uses=1] - %16 = or i32 %15, %14 ; <i32> [#uses=1] - %17 = or i32 %16, 0 ; <i32> [#uses=1] - br label %bb11 - -bb11: ; preds = %bb11, %bb1.thread - %18 = phi i32 [ %110, %bb11 ], [ 0, %bb1.thread ] ; <i32> [#uses=1] - %19 = phi i32 [ %112, %bb11 ], [ 0, %bb1.thread ] ; <i32> [#uses=0] - %20 = phi i32 [ 0, %bb11 ], [ 0, %bb1.thread ] ; <i32> [#uses=0] - %21 = phi i32 [ %113, %bb11 ], [ 0, %bb1.thread ] ; <i32> [#uses=1] - %X.0.0 = phi i32 [ %9, %bb1.thread ], [ %92, %bb11 ] ; <i32> [#uses=0] - %X.1.0 = phi i32 [ %17, %bb1.thread ], [ 0, %bb11 ] ; <i32> [#uses=0] - %22 = getelementptr [2 x i32]* @CAST_S_table6, i32 0, i32 %21 ; <i32*> [#uses=0] - %23 = getelementptr [2 x i32]* @CAST_S_table5, i32 0, i32 %18 ; <i32*> [#uses=0] - %24 = load i32* null, align 4 ; <i32> [#uses=1] - %25 = xor i32 0, %24 ; <i32> [#uses=1] - %26 = xor i32 %25, 0 ; <i32> [#uses=1] - %27 = xor i32 %26, 0 ; <i32> [#uses=4] - %28 = and i32 %27, 255 ; <i32> [#uses=2] - %29 = lshr i32 %27, 8 ; <i32> [#uses=1] - %30 = and i32 %29, 255 ; <i32> [#uses=2] - %31 = lshr i32 %27, 16 ; <i32> [#uses=1] - %32 = and i32 %31, 255 ; <i32> [#uses=1] - %33 = getelementptr [2 x i32]* @CAST_S_table4, i32 0, i32 %28 ; <i32*> [#uses=1] - %34 = load i32* %33, align 4 ; <i32> [#uses=2] - %35 = getelementptr [2 x i32]* @CAST_S_table5, i32 0, i32 %30 ; <i32*> [#uses=1] - %36 = load i32* %35, align 4 ; <i32> [#uses=2] - %37 = xor i32 %34, 0 ; <i32> [#uses=1] - %38 = xor i32 %37, %36 ; <i32> [#uses=1] - %39 = xor i32 %38, 0 ; <i32> [#uses=1] - %40 = xor i32 %39, 0 ; <i32> [#uses=1] - %41 = xor i32 %40, 0 ; <i32> [#uses=3] - %42 = lshr i32 %41, 8 ; <i32> [#uses=1] - %43 = and i32 %42, 255 ; <i32> [#uses=2] - %44 = lshr i32 %41, 16 ; <i32> [#uses=1] - %45 = and i32 %44, 255 ; <i32> [#uses=1] - %46 = getelementptr [2 x i32]* @CAST_S_table4, i32 0, i32 %43 ; <i32*> [#uses=1] - %47 = load i32* %46, align 4 ; <i32> [#uses=1] - %48 = load i32* null, align 4 ; <i32> [#uses=1] - %49 = xor i32 %47, 0 ; <i32> [#uses=1] - %50 = xor i32 %49, %48 ; <i32> [#uses=1] - %51 = xor i32 %50, 0 ; <i32> [#uses=1] - %52 = xor i32 %51, 0 ; <i32> [#uses=1] - %53 = xor i32 %52, 0 ; <i32> [#uses=2] - %54 = and i32 %53, 255 ; <i32> [#uses=1] - %55 = lshr i32 %53, 24 ; <i32> [#uses=1] - %56 = getelementptr [2 x i32]* @CAST_S_table6, i32 0, i32 %55 ; <i32*> [#uses=1] - %57 = load i32* %56, align 4 ; <i32> [#uses=1] - %58 = xor i32 0, %57 ; <i32> [#uses=1] - %59 = xor i32 %58, 0 ; <i32> [#uses=1] - %60 = xor i32 %59, 0 ; <i32> [#uses=1] - store i32 %60, i32* null, align 4 - %61 = getelementptr [2 x i32]* @CAST_S_table4, i32 0, i32 0 ; <i32*> [#uses=1] - %62 = load i32* %61, align 4 ; <i32> [#uses=1] - %63 = getelementptr [2 x i32]* @CAST_S_table7, i32 0, i32 %54 ; <i32*> [#uses=1] - %64 = load i32* %63, align 4 ; <i32> [#uses=1] - %65 = xor i32 0, %64 ; <i32> [#uses=1] - %66 = xor i32 %65, 0 ; <i32> [#uses=1] - store i32 %66, i32* null, align 4 - %67 = getelementptr [2 x i32]* @CAST_S_table7, i32 0, i32 %45 ; <i32*> [#uses=1] - %68 = load i32* %67, align 4 ; <i32> [#uses=1] - %69 = xor i32 %36, %34 ; <i32> [#uses=1] - %70 = xor i32 %69, 0 ; <i32> [#uses=1] - %71 = xor i32 %70, %68 ; <i32> [#uses=1] - %72 = xor i32 %71, 0 ; <i32> [#uses=1] - store i32 %72, i32* null, align 4 - %73 = getelementptr [2 x i32]* @CAST_S_table4, i32 0, i32 %32 ; <i32*> [#uses=1] - %74 = load i32* %73, align 4 ; <i32> [#uses=2] - %75 = load i32* null, align 4 ; <i32> [#uses=1] - %76 = getelementptr [2 x i32]* @CAST_S_table6, i32 0, i32 %43 ; <i32*> [#uses=1] - %77 = load i32* %76, align 4 ; <i32> [#uses=1] - %78 = getelementptr [2 x i32]* @CAST_S_table7, i32 0, i32 0 ; <i32*> [#uses=1] - %79 = load i32* %78, align 4 ; <i32> [#uses=1] - %80 = getelementptr [2 x i32]* @CAST_S_table7, i32 0, i32 %30 ; <i32*> [#uses=1] - %81 = load i32* %80, align 4 ; <i32> [#uses=2] - %82 = xor i32 %75, %74 ; <i32> [#uses=1] - %83 = xor i32 %82, %77 ; <i32> [#uses=1] - %84 = xor i32 %83, %79 ; <i32> [#uses=1] - %85 = xor i32 %84, %81 ; <i32> [#uses=1] - store i32 %85, i32* null, align 4 - %86 = getelementptr [2 x i32]* @CAST_S_table5, i32 0, i32 %28 ; <i32*> [#uses=1] - %87 = load i32* %86, align 4 ; <i32> [#uses=1] - %88 = xor i32 %74, %41 ; <i32> [#uses=1] - %89 = xor i32 %88, %87 ; <i32> [#uses=1] - %90 = xor i32 %89, 0 ; <i32> [#uses=1] - %91 = xor i32 %90, %81 ; <i32> [#uses=1] - %92 = xor i32 %91, 0 ; <i32> [#uses=3] - %93 = lshr i32 %92, 16 ; <i32> [#uses=1] - %94 = and i32 %93, 255 ; <i32> [#uses=1] - store i32 %94, i32* null, align 4 - %95 = lshr i32 %92, 24 ; <i32> [#uses=2] - %96 = getelementptr [2 x i32]* @CAST_S_table4, i32 0, i32 %95 ; <i32*> [#uses=1] - %97 = load i32* %96, align 4 ; <i32> [#uses=1] - %98 = getelementptr [2 x i32]* @CAST_S_table5, i32 0, i32 0 ; <i32*> [#uses=1] - %99 = load i32* %98, align 4 ; <i32> [#uses=1] - %100 = load i32* null, align 4 ; <i32> [#uses=0] - %101 = xor i32 %97, 0 ; <i32> [#uses=1] - %102 = xor i32 %101, %99 ; <i32> [#uses=1] - %103 = xor i32 %102, 0 ; <i32> [#uses=1] - %104 = xor i32 %103, 0 ; <i32> [#uses=0] - store i32 0, i32* null, align 4 - %105 = xor i32 0, %27 ; <i32> [#uses=1] - %106 = xor i32 %105, 0 ; <i32> [#uses=1] - %107 = xor i32 %106, 0 ; <i32> [#uses=1] - %108 = xor i32 %107, 0 ; <i32> [#uses=1] - %109 = xor i32 %108, %62 ; <i32> [#uses=3] - %110 = and i32 %109, 255 ; <i32> [#uses=1] - %111 = lshr i32 %109, 16 ; <i32> [#uses=1] - %112 = and i32 %111, 255 ; <i32> [#uses=1] - %113 = lshr i32 %109, 24 ; <i32> [#uses=3] - store i32 %113, i32* %1, align 4 - %114 = load i32* null, align 4 ; <i32> [#uses=1] - %115 = xor i32 0, %114 ; <i32> [#uses=1] - %116 = xor i32 %115, 0 ; <i32> [#uses=1] - %117 = xor i32 %116, 0 ; <i32> [#uses=1] - %K.0.sum42 = or i32 0, 12 ; <i32> [#uses=1] - %118 = getelementptr [32 x i32]* null, i32 0, i32 %K.0.sum42 ; <i32*> [#uses=1] - store i32 %117, i32* %118, align 4 - %119 = getelementptr [2 x i32]* @CAST_S_table5, i32 0, i32 0 ; <i32*> [#uses=0] - store i32 0, i32* null, align 4 - %120 = getelementptr [2 x i32]* @CAST_S_table6, i32 0, i32 %113 ; <i32*> [#uses=1] - %121 = load i32* %120, align 4 ; <i32> [#uses=1] - %122 = xor i32 0, %121 ; <i32> [#uses=1] - store i32 %122, i32* null, align 4 - %123 = getelementptr [2 x i32]* @CAST_S_table4, i32 0, i32 0 ; <i32*> [#uses=1] - %124 = load i32* %123, align 4 ; <i32> [#uses=1] - %125 = getelementptr [2 x i32]* @CAST_S_table7, i32 0, i32 %95 ; <i32*> [#uses=1] - %126 = load i32* %125, align 4 ; <i32> [#uses=1] - %127 = xor i32 0, %124 ; <i32> [#uses=1] - %128 = xor i32 %127, 0 ; <i32> [#uses=1] - %129 = xor i32 %128, %126 ; <i32> [#uses=1] - %130 = xor i32 %129, 0 ; <i32> [#uses=1] - store i32 %130, i32* null, align 4 - br label %bb11 -} diff --git a/test/CodeGen/X86/2009-03-23-MultiUseSched.ll b/test/CodeGen/X86/2009-03-23-MultiUseSched.ll index 90dabb8..8bbdb0e 100644 --- a/test/CodeGen/X86/2009-03-23-MultiUseSched.ll +++ b/test/CodeGen/X86/2009-03-23-MultiUseSched.ll @@ -9,30 +9,30 @@ @X = external global i64 ; <i64*> [#uses=25] define fastcc i64 @foo() nounwind { - %tmp = volatile load i64* @X ; <i64> [#uses=7] - %tmp1 = volatile load i64* @X ; <i64> [#uses=5] - %tmp2 = volatile load i64* @X ; <i64> [#uses=3] - %tmp3 = volatile load i64* @X ; <i64> [#uses=1] - %tmp4 = volatile load i64* @X ; <i64> [#uses=5] - %tmp5 = volatile load i64* @X ; <i64> [#uses=3] - %tmp6 = volatile load i64* @X ; <i64> [#uses=2] - %tmp7 = volatile load i64* @X ; <i64> [#uses=1] - %tmp8 = volatile load i64* @X ; <i64> [#uses=1] - %tmp9 = volatile load i64* @X ; <i64> [#uses=1] - %tmp10 = volatile load i64* @X ; <i64> [#uses=1] - %tmp11 = volatile load i64* @X ; <i64> [#uses=1] - %tmp12 = volatile load i64* @X ; <i64> [#uses=1] - %tmp13 = volatile load i64* @X ; <i64> [#uses=1] - %tmp14 = volatile load i64* @X ; <i64> [#uses=1] - %tmp15 = volatile load i64* @X ; <i64> [#uses=1] - %tmp16 = volatile load i64* @X ; <i64> [#uses=1] - %tmp17 = volatile load i64* @X ; <i64> [#uses=1] - %tmp18 = volatile load i64* @X ; <i64> [#uses=1] - %tmp19 = volatile load i64* @X ; <i64> [#uses=1] - %tmp20 = volatile load i64* @X ; <i64> [#uses=1] - %tmp21 = volatile load i64* @X ; <i64> [#uses=1] - %tmp22 = volatile load i64* @X ; <i64> [#uses=1] - %tmp23 = volatile load i64* @X ; <i64> [#uses=1] + %tmp = load volatile i64* @X ; <i64> [#uses=7] + %tmp1 = load volatile i64* @X ; <i64> [#uses=5] + %tmp2 = load volatile i64* @X ; <i64> [#uses=3] + %tmp3 = load volatile i64* @X ; <i64> [#uses=1] + %tmp4 = load volatile i64* @X ; <i64> [#uses=5] + %tmp5 = load volatile i64* @X ; <i64> [#uses=3] + %tmp6 = load volatile i64* @X ; <i64> [#uses=2] + %tmp7 = load volatile i64* @X ; <i64> [#uses=1] + %tmp8 = load volatile i64* @X ; <i64> [#uses=1] + %tmp9 = load volatile i64* @X ; <i64> [#uses=1] + %tmp10 = load volatile i64* @X ; <i64> [#uses=1] + %tmp11 = load volatile i64* @X ; <i64> [#uses=1] + %tmp12 = load volatile i64* @X ; <i64> [#uses=1] + %tmp13 = load volatile i64* @X ; <i64> [#uses=1] + %tmp14 = load volatile i64* @X ; <i64> [#uses=1] + %tmp15 = load volatile i64* @X ; <i64> [#uses=1] + %tmp16 = load volatile i64* @X ; <i64> [#uses=1] + %tmp17 = load volatile i64* @X ; <i64> [#uses=1] + %tmp18 = load volatile i64* @X ; <i64> [#uses=1] + %tmp19 = load volatile i64* @X ; <i64> [#uses=1] + %tmp20 = load volatile i64* @X ; <i64> [#uses=1] + %tmp21 = load volatile i64* @X ; <i64> [#uses=1] + %tmp22 = load volatile i64* @X ; <i64> [#uses=1] + %tmp23 = load volatile i64* @X ; <i64> [#uses=1] %tmp24 = call i64 @llvm.bswap.i64(i64 %tmp8) ; <i64> [#uses=1] %tmp25 = add i64 %tmp6, %tmp5 ; <i64> [#uses=1] %tmp26 = add i64 %tmp25, %tmp4 ; <i64> [#uses=1] @@ -229,7 +229,7 @@ define fastcc i64 @foo() nounwind { %tmp217 = add i64 %tmp205, %tmp215 ; <i64> [#uses=1] %tmp218 = add i64 %tmp217, %tmp211 ; <i64> [#uses=1] %tmp219 = call i64 @llvm.bswap.i64(i64 %tmp23) ; <i64> [#uses=2] - volatile store i64 %tmp219, i64* @X, align 8 + store volatile i64 %tmp219, i64* @X, align 8 %tmp220 = add i64 %tmp203, %tmp190 ; <i64> [#uses=1] %tmp221 = add i64 %tmp220, %tmp216 ; <i64> [#uses=1] %tmp222 = add i64 %tmp219, %tmp177 ; <i64> [#uses=1] diff --git a/test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll b/test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll index 620e0f3..9f5a8c5 100644 --- a/test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll +++ b/test/CodeGen/X86/2009-04-21-NoReloadImpDef.ll @@ -1,11 +1,10 @@ ; RUN: llc -mtriple=i386-apple-darwin10.0 -relocation-model=pic -asm-verbose=false \ -; RUN: -disable-fp-elim -mattr=-sse41,-sse3,+sse2 -post-RA-scheduler=false -regalloc=linearscan < %s | \ +; RUN: -disable-fp-elim -mattr=-sse41,-sse3,+sse2 -post-RA-scheduler=false -regalloc=basic < %s | \ ; RUN: FileCheck %s ; rdar://6808032 ; CHECK: pextrw $14 ; CHECK-NEXT: shrl $8 -; CHECK-NEXT: (%ebp) ; CHECK-NEXT: pinsrw define void @update(i8** %args_list) nounwind { diff --git a/test/CodeGen/X86/2009-05-11-tailmerge-crash.ll b/test/CodeGen/X86/2009-05-11-tailmerge-crash.ll index a5e28c0..c2cd89c 100644 --- a/test/CodeGen/X86/2009-05-11-tailmerge-crash.ll +++ b/test/CodeGen/X86/2009-05-11-tailmerge-crash.ll @@ -12,7 +12,7 @@ entry: br label %bb bb: ; preds = %bb.i, %bb, %entry - %2 = volatile load i32* @g_9, align 4 ; <i32> [#uses=2] + %2 = load volatile i32* @g_9, align 4 ; <i32> [#uses=2] %3 = icmp sgt i32 %2, 1 ; <i1> [#uses=1] %4 = and i1 %3, %1 ; <i1> [#uses=1] br i1 %4, label %bb.i, label %bb diff --git a/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll b/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll index 12bd285..1259cf4 100644 --- a/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll +++ b/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=x86_64-mingw32 < %s | FileCheck %s +; RUN: llc -mcpu=generic -mtriple=x86_64-mingw32 < %s | FileCheck %s ; CHECK: subq $40, %rsp ; CHECK: movaps %xmm8, (%rsp) ; CHECK: movaps %xmm7, 16(%rsp) diff --git a/test/CodeGen/X86/2009-06-05-VZextByteShort.ll b/test/CodeGen/X86/2009-06-05-VZextByteShort.ll index 5c51480..5f5d5cc 100644 --- a/test/CodeGen/X86/2009-06-05-VZextByteShort.ll +++ b/test/CodeGen/X86/2009-06-05-VZextByteShort.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s -march=x86 -mattr=+mmx,+sse2 > %t1 ; RUN: grep movzwl %t1 | count 2 -; RUN: grep movzbl %t1 | count 2 +; RUN: grep movzbl %t1 | count 1 ; RUN: grep movd %t1 | count 4 define <4 x i16> @a(i32* %x1) nounwind { diff --git a/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll b/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll index 07ef53e..66caedf 100644 --- a/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll +++ b/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mattr=+mmx | grep movl | count 2 +; RUN: llc < %s -mtriple=x86_64-linux -mcpu=corei7 -mattr=+mmx | grep movd | count 2 define i64 @a(i32 %a, i32 %b) nounwind readnone { entry: diff --git a/test/CodeGen/X86/2009-07-17-StackColoringBug.ll b/test/CodeGen/X86/2009-07-17-StackColoringBug.ll deleted file mode 100644 index 3e5bd34..0000000 --- a/test/CodeGen/X86/2009-07-17-StackColoringBug.ll +++ /dev/null @@ -1,55 +0,0 @@ -; RUN: llc < %s -mtriple=i386-pc-linux-gnu -disable-fp-elim -color-ss-with-regs | not grep dil -; PR4552 - -target triple = "i386-pc-linux-gnu" -@g_8 = internal global i32 0 ; <i32*> [#uses=1] -@g_72 = internal global i32 0 ; <i32*> [#uses=1] -@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 (i32, i8, i8)* @uint84 to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] - -define i32 @uint84(i32 %p_15, i8 signext %p_17, i8 signext %p_19) nounwind { -entry: - %g_72.promoted = load i32* @g_72 ; <i32> [#uses=1] - %g_8.promoted = load i32* @g_8 ; <i32> [#uses=1] - br label %bb - -bb: ; preds = %func_40.exit, %entry - %g_8.tmp.1 = phi i32 [ %g_8.promoted, %entry ], [ %g_8.tmp.0, %func_40.exit ] ; <i32> [#uses=3] - %g_72.tmp.1 = phi i32 [ %g_72.promoted, %entry ], [ %g_72.tmp.0, %func_40.exit ] ; <i32> [#uses=3] - %retval12.i4.i.i = trunc i32 %g_8.tmp.1 to i8 ; <i8> [#uses=2] - %0 = trunc i32 %g_72.tmp.1 to i8 ; <i8> [#uses=2] - %1 = mul i8 %retval12.i4.i.i, %0 ; <i8> [#uses=1] - %2 = icmp eq i8 %1, 0 ; <i1> [#uses=1] - br i1 %2, label %bb2.i.i, label %bb.i.i - -bb.i.i: ; preds = %bb - %3 = sext i8 %0 to i32 ; <i32> [#uses=1] - %4 = and i32 %3, 50295 ; <i32> [#uses=1] - %5 = icmp eq i32 %4, 0 ; <i1> [#uses=1] - br i1 %5, label %bb2.i.i, label %func_55.exit.i - -bb2.i.i: ; preds = %bb.i.i, %bb - br label %func_55.exit.i - -func_55.exit.i: ; preds = %bb2.i.i, %bb.i.i - %g_72.tmp.2 = phi i32 [ 1, %bb2.i.i ], [ %g_72.tmp.1, %bb.i.i ] ; <i32> [#uses=1] - %6 = phi i32 [ 1, %bb2.i.i ], [ %g_72.tmp.1, %bb.i.i ] ; <i32> [#uses=1] - %7 = trunc i32 %6 to i8 ; <i8> [#uses=2] - %8 = mul i8 %7, %retval12.i4.i.i ; <i8> [#uses=1] - %9 = icmp eq i8 %8, 0 ; <i1> [#uses=1] - br i1 %9, label %bb2.i4.i, label %bb.i3.i - -bb.i3.i: ; preds = %func_55.exit.i - %10 = sext i8 %7 to i32 ; <i32> [#uses=1] - %11 = and i32 %10, 50295 ; <i32> [#uses=1] - %12 = icmp eq i32 %11, 0 ; <i1> [#uses=1] - br i1 %12, label %bb2.i4.i, label %func_40.exit - -bb2.i4.i: ; preds = %bb.i3.i, %func_55.exit.i - br label %func_40.exit - -func_40.exit: ; preds = %bb2.i4.i, %bb.i3.i - %g_72.tmp.0 = phi i32 [ 1, %bb2.i4.i ], [ %g_72.tmp.2, %bb.i3.i ] ; <i32> [#uses=1] - %phitmp = icmp sgt i32 %g_8.tmp.1, 0 ; <i1> [#uses=1] - %g_8.tmp.0 = select i1 %phitmp, i32 %g_8.tmp.1, i32 1 ; <i32> [#uses=1] - br label %bb -} diff --git a/test/CodeGen/X86/2009-08-23-SubRegReuseUndo.ll b/test/CodeGen/X86/2009-08-23-SubRegReuseUndo.ll index 790fd88..410a42a 100644 --- a/test/CodeGen/X86/2009-08-23-SubRegReuseUndo.ll +++ b/test/CodeGen/X86/2009-08-23-SubRegReuseUndo.ll @@ -41,18 +41,18 @@ bb3: ; preds = %bb2, %bb br i1 undef, label %bb5, label %bb4 bb4: ; preds = %bb3 - %17 = volatile load i32* @uint8, align 4 ; <i32> [#uses=0] + %17 = load volatile i32* @uint8, align 4 ; <i32> [#uses=0] br label %bb5 bb5: ; preds = %bb4, %bb3 - %18 = volatile load i32* @uint8, align 4 ; <i32> [#uses=0] + %18 = load volatile i32* @uint8, align 4 ; <i32> [#uses=0] %19 = sext i8 undef to i16 ; <i16> [#uses=1] %20 = tail call i32 @func_24(i16 zeroext %19, i8 signext 1) nounwind; <i32> [#uses=0] br i1 undef, label %return, label %bb6.preheader bb6.preheader: ; preds = %bb5 %21 = sext i8 %p_52 to i32 ; <i32> [#uses=1] - %22 = volatile load i32* @uint8, align 4 ; <i32> [#uses=0] + %22 = load volatile i32* @uint8, align 4 ; <i32> [#uses=0] %23 = tail call i32 (...)* @safefuncts(i32 %21, i32 1) nounwind; <i32> [#uses=0] unreachable diff --git a/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll b/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll index f6ac2ba..d4a74c9 100644 --- a/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll +++ b/test/CodeGen/X86/2010-02-19-TailCallRetAddrBug.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=i386-apple-darwin -tailcallopt < %s | FileCheck %s +; RUN: llc -mcpu=generic -mtriple=i386-apple-darwin -tailcallopt < %s | FileCheck %s ; Check that lowered argumens do not overwrite the return address before it is moved. ; Bug 6225 ; diff --git a/test/CodeGen/X86/2010-04-23-mmx-movdq2q.ll b/test/CodeGen/X86/2010-04-23-mmx-movdq2q.ll index 69787c7..5372bc5 100644 --- a/test/CodeGen/X86/2010-04-23-mmx-movdq2q.ll +++ b/test/CodeGen/X86/2010-04-23-mmx-movdq2q.ll @@ -1,32 +1,35 @@ ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=+mmx,+sse2 | FileCheck %s ; There are no MMX operations here, so we use XMM or i64. +; CHECK: ti8 define void @ti8(double %a, double %b) nounwind { entry: %tmp1 = bitcast double %a to <8 x i8> %tmp2 = bitcast double %b to <8 x i8> %tmp3 = add <8 x i8> %tmp1, %tmp2 -; CHECK: paddb %xmm1, %xmm0 +; CHECK: paddw store <8 x i8> %tmp3, <8 x i8>* null ret void } +; CHECK: ti16 define void @ti16(double %a, double %b) nounwind { entry: %tmp1 = bitcast double %a to <4 x i16> %tmp2 = bitcast double %b to <4 x i16> %tmp3 = add <4 x i16> %tmp1, %tmp2 -; CHECK: paddw %xmm1, %xmm0 +; CHECK: paddd store <4 x i16> %tmp3, <4 x i16>* null ret void } +; CHECK: ti32 define void @ti32(double %a, double %b) nounwind { entry: %tmp1 = bitcast double %a to <2 x i32> %tmp2 = bitcast double %b to <2 x i32> %tmp3 = add <2 x i32> %tmp1, %tmp2 -; CHECK: paddd %xmm1, %xmm0 +; CHECK: paddq store <2 x i32> %tmp3, <2 x i32>* null ret void } @@ -55,6 +58,7 @@ entry: ret void } +; CHECK: ti16a define void @ti16a(double %a, double %b) nounwind { entry: %tmp1 = bitcast double %a to x86_mmx @@ -66,6 +70,7 @@ entry: ret void } +; CHECK: ti32a define void @ti32a(double %a, double %b) nounwind { entry: %tmp1 = bitcast double %a to x86_mmx @@ -77,6 +82,7 @@ entry: ret void } +; CHECK: ti64a define void @ti64a(double %a, double %b) nounwind { entry: %tmp1 = bitcast double %a to x86_mmx diff --git a/test/CodeGen/X86/2010-04-30-LocalAlloc-LandingPad.ll b/test/CodeGen/X86/2010-04-30-LocalAlloc-LandingPad.ll index 7af58dc..cbf5502 100644 --- a/test/CodeGen/X86/2010-04-30-LocalAlloc-LandingPad.ll +++ b/test/CodeGen/X86/2010-04-30-LocalAlloc-LandingPad.ll @@ -30,14 +30,16 @@ invoke.cont: ; preds = %entry br label %finally terminate.handler: ; preds = %match.end - %exc = call i8* @llvm.eh.exception() ; <i8*> [#uses=1] - %1 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0] + %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup call void @_ZSt9terminatev() noreturn nounwind unreachable try.handler: ; preds = %entry - %exc1 = call i8* @llvm.eh.exception() ; <i8*> [#uses=3] - %selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc1, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null) ; <i32> [#uses=1] + %exc1.ptr = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + %exc1 = extractvalue { i8*, i32 } %exc1.ptr, 0 + %selector = extractvalue { i8*, i32 } %exc1.ptr, 1 %2 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) ; <i32> [#uses=1] %3 = icmp eq i32 %selector, %2 ; <i1> [#uses=1] br i1 %3, label %match, label %catch.next @@ -55,9 +57,10 @@ invoke.cont2: ; preds = %match br label %match.end match.handler: ; preds = %match - %exc3 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2] - %7 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc3, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0) ; <i32> [#uses=0] - store i8* %exc3, i8** %_rethrow + %exc3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + %7 = extractvalue { i8*, i32 } %exc3, 0 + store i8* %7, i8** %_rethrow store i32 2, i32* %cleanup.dst br label %match.end @@ -124,10 +127,6 @@ declare void @_Z6throwsv() ssp declare i32 @__gxx_personality_v0(...) -declare i8* @llvm.eh.exception() nounwind readonly - -declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind - declare void @_ZSt9terminatev() declare void @_Unwind_Resume_or_Rethrow(i8*) diff --git a/test/CodeGen/X86/2010-05-03-CoalescerSubRegClobber.ll b/test/CodeGen/X86/2010-05-03-CoalescerSubRegClobber.ll index 5accfd7..e0c2c6c 100644 --- a/test/CodeGen/X86/2010-05-03-CoalescerSubRegClobber.ll +++ b/test/CodeGen/X86/2010-05-03-CoalescerSubRegClobber.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s | FileCheck %s +; RUN: llc < %s -mcpu=generic | FileCheck %s ; PR6941 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.0.0" diff --git a/test/CodeGen/X86/2010-06-28-DbgEntryPC.ll b/test/CodeGen/X86/2010-06-28-DbgEntryPC.ll deleted file mode 100644 index 2ba12df..0000000 --- a/test/CodeGen/X86/2010-06-28-DbgEntryPC.ll +++ /dev/null @@ -1,108 +0,0 @@ -; RUN: llc -O2 -mtriple=i386-apple-darwin <%s | FileCheck %s -; Use DW_FORM_addr for DW_AT_entry_pc. -; Radar 8094785 - -; CHECK: .byte 17 ## DW_TAG_compile_unit -; CHECK-NEXT: .byte 1 ## DW_CHILDREN_yes -; CHECK-NEXT: .byte 37 ## DW_AT_producer -; CHECK-NEXT: .byte 8 ## DW_FORM_string -; CHECK-NEXT: .byte 19 ## DW_AT_language -; CHECK-NEXT: .byte 5 ## DW_FORM_data2 -; CHECK-NEXT: .byte 3 ## DW_AT_name -; CHECK-NEXT: .byte 8 ## DW_FORM_string -; CHECK-NEXT: .byte 82 ## DW_AT_entry_pc -; CHECK-NEXT: .byte 1 ## DW_FORM_addr -; CHECK-NEXT: .byte 16 ## DW_AT_stmt_list -; CHECK-NEXT: .byte 6 ## DW_FORM_data4 -; CHECK-NEXT: .byte 27 ## DW_AT_comp_dir -; CHECK-NEXT: .byte 8 ## DW_FORM_string -; CHECK-NEXT: .byte 225 ## DW_AT_APPLE_optimized - -%struct.a = type { i32, %struct.a* } - -@ret = common global i32 0 ; <i32*> [#uses=2] - -define void @foo(i32 %x) nounwind noinline ssp { -entry: - tail call void @llvm.dbg.value(metadata !{i32 %x}, i64 0, metadata !21), !dbg !28 - store i32 %x, i32* @ret, align 4, !dbg !29 - ret void, !dbg !31 -} - -declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -define i8* @bar(%struct.a* %b) nounwind noinline ssp { -entry: - tail call void @llvm.dbg.value(metadata !{%struct.a* %b}, i64 0, metadata !22), !dbg !32 - %0 = getelementptr inbounds %struct.a* %b, i64 0, i32 0, !dbg !33 ; <i32*> [#uses=1] - %1 = load i32* %0, align 8, !dbg !33 ; <i32> [#uses=1] - tail call void @foo(i32 %1) nounwind noinline ssp, !dbg !33 - %2 = bitcast %struct.a* %b to i8*, !dbg !35 ; <i8*> [#uses=1] - ret i8* %2, !dbg !35 -} - -define i32 @main(i32 %argc, i8** nocapture %argv) nounwind ssp { -entry: - %e = alloca %struct.a, align 8 ; <%struct.a*> [#uses=4] - call void @llvm.dbg.value(metadata !{i32 %argc}, i64 0, metadata !23), !dbg !36 - call void @llvm.dbg.value(metadata !{i8** %argv}, i64 0, metadata !24), !dbg !36 - call void @llvm.dbg.declare(metadata !{%struct.a* %e}, metadata !25), !dbg !37 - %0 = getelementptr inbounds %struct.a* %e, i64 0, i32 0, !dbg !38 ; <i32*> [#uses=1] - store i32 4, i32* %0, align 8, !dbg !38 - %1 = getelementptr inbounds %struct.a* %e, i64 0, i32 1, !dbg !39 ; <%struct.a**> [#uses=1] - store %struct.a* %e, %struct.a** %1, align 8, !dbg !39 - %2 = call i8* @bar(%struct.a* %e) nounwind noinline ssp, !dbg !40 ; <i8*> [#uses=0] - %3 = load i32* @ret, align 4, !dbg !41 ; <i32> [#uses=1] - ret i32 %3, !dbg !41 -} - -!llvm.dbg.sp = !{!0, !6, !15} -!llvm.dbg.lv.foo = !{!21} -!llvm.dbg.lv.bar = !{!22} -!llvm.dbg.lv.main = !{!23, !24, !25} -!llvm.dbg.gv = !{!27} - -!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 34, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, void (i32)* @foo} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 524329, metadata !"2010-06-28-DbgEntryPC.c", metadata !"/Users/yash/clean/llvm/test/FrontendC", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 524305, i32 0, i32 1, metadata !"2010-06-28-DbgEntryPC.c", metadata !"/Users/yash/clean/llvm/test/FrontendC", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{null, metadata !5} -!5 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!6 = metadata !{i32 524334, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"bar", metadata !1, i32 38, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i8* (%struct.a*)* @bar} ; [ DW_TAG_subprogram ] -!7 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, null} ; [ DW_TAG_subroutine_type ] -!8 = metadata !{metadata !9, metadata !10} -!9 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] -!10 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !11} ; [ DW_TAG_pointer_type ] -!11 = metadata !{i32 524307, metadata !1, metadata !"a", metadata !1, i32 23, i64 128, i64 64, i64 0, i32 0, null, metadata !12, i32 0, null} ; [ DW_TAG_structure_type ] -!12 = metadata !{metadata !13, metadata !14} -!13 = metadata !{i32 524301, metadata !11, metadata !"c", metadata !1, i32 24, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ] -!14 = metadata !{i32 524301, metadata !11, metadata !"d", metadata !1, i32 25, i64 64, i64 64, i64 64, i32 0, metadata !10} ; [ DW_TAG_member ] -!15 = metadata !{i32 524334, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 43, metadata !16, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 (i32, i8**)* @main} ; [ DW_TAG_subprogram ] -!16 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !17, i32 0, null} ; [ DW_TAG_subroutine_type ] -!17 = metadata !{metadata !5, metadata !5, metadata !18} -!18 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !19} ; [ DW_TAG_pointer_type ] -!19 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !20} ; [ DW_TAG_pointer_type ] -!20 = metadata !{i32 524324, metadata !1, metadata !"char", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] -!21 = metadata !{i32 524545, metadata !0, metadata !"x", metadata !1, i32 33, metadata !5} ; [ DW_TAG_arg_variable ] -!22 = metadata !{i32 524545, metadata !6, metadata !"b", metadata !1, i32 38, metadata !10} ; [ DW_TAG_arg_variable ] -!23 = metadata !{i32 524545, metadata !15, metadata !"argc", metadata !1, i32 43, metadata !5} ; [ DW_TAG_arg_variable ] -!24 = metadata !{i32 524545, metadata !15, metadata !"argv", metadata !1, i32 43, metadata !18} ; [ DW_TAG_arg_variable ] -!25 = metadata !{i32 524544, metadata !26, metadata !"e", metadata !1, i32 44, metadata !11} ; [ DW_TAG_auto_variable ] -!26 = metadata !{i32 524299, metadata !15, i32 43, i32 0} ; [ DW_TAG_lexical_block ] -!27 = metadata !{i32 524340, i32 0, metadata !1, metadata !"ret", metadata !"ret", metadata !"", metadata !1, i32 28, metadata !5, i1 false, i1 true, i32* @ret} ; [ DW_TAG_variable ] -!28 = metadata !{i32 33, i32 0, metadata !0, null} -!29 = metadata !{i32 35, i32 0, metadata !30, null} -!30 = metadata !{i32 524299, metadata !0, i32 34, i32 0} ; [ DW_TAG_lexical_block ] -!31 = metadata !{i32 36, i32 0, metadata !30, null} -!32 = metadata !{i32 38, i32 0, metadata !6, null} -!33 = metadata !{i32 39, i32 0, metadata !34, null} -!34 = metadata !{i32 524299, metadata !6, i32 38, i32 0} ; [ DW_TAG_lexical_block ] -!35 = metadata !{i32 40, i32 0, metadata !34, null} -!36 = metadata !{i32 43, i32 0, metadata !15, null} -!37 = metadata !{i32 44, i32 0, metadata !26, null} -!38 = metadata !{i32 45, i32 0, metadata !26, null} -!39 = metadata !{i32 46, i32 0, metadata !26, null} -!40 = metadata !{i32 48, i32 0, metadata !26, null} -!41 = metadata !{i32 49, i32 0, metadata !26, null} diff --git a/test/CodeGen/X86/2010-08-04-MingWCrash.ll b/test/CodeGen/X86/2010-08-04-MingWCrash.ll index 98a0887..61f527b 100644 --- a/test/CodeGen/X86/2010-08-04-MingWCrash.ll +++ b/test/CodeGen/X86/2010-08-04-MingWCrash.ll @@ -10,14 +10,15 @@ bb1: ret void lpad: - %exn = tail call i8* @llvm.eh.exception() nounwind - %eh.selector = tail call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1, i8* null) nounwind + %exn.ptr = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + %exn = extractvalue { i8*, i32 } %exn.ptr, 0 + %eh.selector = extractvalue { i8*, i32 } %exn.ptr, 1 %ehspec.fails = icmp slt i32 %eh.selector, 0 br i1 %ehspec.fails, label %ehspec.unexpected, label %cleanup cleanup: - tail call void @_Unwind_Resume_or_Rethrow(i8* %exn) noreturn nounwind - unreachable + resume { i8*, i32 } %exn.ptr ehspec.unexpected: tail call void @__cxa_call_unexpected(i8* %exn) noreturn nounwind @@ -26,12 +27,8 @@ ehspec.unexpected: declare noalias i8* @malloc() -declare i8* @llvm.eh.exception() nounwind readonly - declare i32 @__gxx_personality_v0(...) -declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind - declare void @_Unwind_Resume_or_Rethrow(i8*) declare void @__cxa_call_unexpected(i8*) diff --git a/test/CodeGen/X86/2010-08-10-DbgConstant.ll b/test/CodeGen/X86/2010-08-10-DbgConstant.ll index d98ef14..b3cc35d 100644 --- a/test/CodeGen/X86/2010-08-10-DbgConstant.ll +++ b/test/CodeGen/X86/2010-08-10-DbgConstant.ll @@ -1,6 +1,6 @@ -; RUN: llc -march=x86 -O0 < %s | FileCheck %s +; RUN: llc -mtriple=i686-linux -O0 < %s | FileCheck %s ; CHECK: DW_TAG_constant -; CHECK-NEXT: ascii "ro" #{{#?}} DW_AT_name +; CHECK-NEXT: .long .Lstring3 #{{#?}} DW_AT_name define void @foo() nounwind ssp { entry: diff --git a/test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll b/test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll index 7f13411..166dcf2 100644 --- a/test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll +++ b/test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll @@ -4,8 +4,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 target triple = "x86_64-apple-darwin10.0.0" ; Check debug info for variable z_s -;CHECK: .ascii "z_s" ## DW_AT_name -;CHECK-NEXT: .byte 0 +;CHECK: .long Lset13 ;CHECK-NEXT: ## DW_AT_decl_file ;CHECK-NEXT: ## DW_AT_decl_line ;CHECK-NEXT: ## DW_AT_type diff --git a/test/CodeGen/X86/2011-08-29-InitOrder.ll b/test/CodeGen/X86/2011-08-29-InitOrder.ll index 72c79d2..4d5f8d7 100644 --- a/test/CodeGen/X86/2011-08-29-InitOrder.ll +++ b/test/CodeGen/X86/2011-08-29-InitOrder.ll @@ -3,22 +3,28 @@ ; PR5329 @llvm.global_ctors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 2000, void ()* @construct_2 }, { i32, void ()* } { i32 3000, void ()* @construct_3 }, { i32, void ()* } { i32 1000, void ()* @construct_1 }] -; CHECK-DEFAULT: construct_3 -; CHECK-DEFAULT: construct_2 -; CHECK-DEFAULT: construct_1 +; CHECK-DEFAULT .section .ctors.64535,"aw",@progbits +; CHECK-DEFAULT: .long construct_1 +; CHECK-DEFAULT: .section .ctors.63535,"aw",@progbits +; CHECK-DEFAULT: .long construct_2 +; CHECK-DEFAULT: .section .ctors.62535,"aw",@progbits +; CHECK-DEFAULT: .long construct_3 -; CHECK-DARWIN: construct_1 -; CHECK-DARWIN: construct_2 -; CHECK-DARWIN: construct_3 +; CHECK-DARWIN: .long _construct_1 +; CHECK-DARWIN-NEXT: .long _construct_2 +; CHECK-DARWIN-NEXT: .long _construct_3 @llvm.global_dtors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 2000, void ()* @destruct_2 }, { i32, void ()* } { i32 1000, void ()* @destruct_1 }, { i32, void ()* } { i32 3000, void ()* @destruct_3 }] -; CHECK-DEFAULT: destruct_3 -; CHECK-DEFAULT: destruct_2 -; CHECK-DEFAULT: destruct_1 +; CHECK-DEFAULT: .section .dtors.64535,"aw",@progbits +; CHECK-DEFAULT: .long destruct_1 +; CHECK-DEFAULT: .section .dtors.63535,"aw",@progbits +; CHECK-DEFAULT: .long destruct_2 +; CHECK-DEFAULT: .section .dtors.62535,"aw",@progbits +; CHECK-DEFAULT: .long destruct_3 -; CHECK-DARWIN: destruct_1 -; CHECK-DARWIN: destruct_2 -; CHECK-DARWIN: destruct_3 +; CHECK-DARWIN: .long _destruct_1 +; CHECK-DARWIN-NEXT: .long _destruct_2 +; CHECK-DARWIN-NEXT: .long _destruct_3 declare void @construct_1() declare void @construct_2() diff --git a/test/CodeGen/X86/2011-10-18-FastISel-VectorParams.ll b/test/CodeGen/X86/2011-10-18-FastISel-VectorParams.ll new file mode 100644 index 0000000..8c09d97 --- /dev/null +++ b/test/CodeGen/X86/2011-10-18-FastISel-VectorParams.ll @@ -0,0 +1,29 @@ +; RUN: llc -march=x86 -fast-isel -mattr=+sse < %s | FileCheck %s +; <rdar://problem/10215997> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128" +target triple = "i386-apple-macosx10.7" + +define void @vectortest() nounwind ssp { +entry: + %p1 = alloca <4 x float>, align 16 + %p2 = alloca <4 x float>, align 16 + %p3 = alloca <4 x float>, align 16 + %p4 = alloca <4 x float>, align 16 + %p5 = alloca <4 x float>, align 16 + store <4 x float> <float 0x3FF19999A0000000, float 0x3FF3333340000000, float 0x3FF4CCCCC0000000, float 0x3FF6666660000000>, <4 x float>* %p1, align 16 + store <4 x float> <float 0x4000CCCCC0000000, float 0x40019999A0000000, float 0x4002666660000000, float 0x4003333340000000>, <4 x float>* %p2, align 16 + store <4 x float> <float 0x4008CCCCC0000000, float 0x40099999A0000000, float 0x400A666660000000, float 0x400B333340000000>, <4 x float>* %p3, align 16 + store <4 x float> <float 0x4010666660000000, float 0x4010CCCCC0000000, float 0x4011333340000000, float 0x40119999A0000000>, <4 x float>* %p4, align 16 + store <4 x float> <float 0x4014666660000000, float 0x4014CCCCC0000000, float 0x4015333340000000, float 0x40159999A0000000>, <4 x float>* %p5, align 16 + %0 = load <4 x float>* %p1, align 16 + %1 = load <4 x float>* %p2, align 16 + %2 = load <4 x float>* %p3, align 16 + %3 = load <4 x float>* %p4, align 16 + %4 = load <4 x float>* %p5, align 16 +; CHECK: movaps {{%xmm[0-7]}}, (%esp) +; CHECK-NEXT: calll _dovectortest + call void @dovectortest(<4 x float> %0, <4 x float> %1, <4 x float> %2, <4 x float> %3, <4 x float> %4) + ret void +} + +declare void @dovectortest(<4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>) diff --git a/test/CodeGen/X86/2011-10-19-LegelizeLoad.ll b/test/CodeGen/X86/2011-10-19-LegelizeLoad.ll new file mode 100644 index 0000000..a720753 --- /dev/null +++ b/test/CodeGen/X86/2011-10-19-LegelizeLoad.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i8:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%union.anon = type { <2 x i8> } + +@i = global <2 x i8> <i8 150, i8 100>, align 8 +@j = global <2 x i8> <i8 10, i8 13>, align 8 +@res = common global %union.anon zeroinitializer, align 8 + +; Make sure we load the constants i and j starting offset zero. +; Also make sure that we sign-extend it. +; Based on /gcc-4_2-testsuite/src/gcc.c-torture/execute/pr23135.c + +; CHECK: main +define i32 @main() nounwind uwtable { +entry: +; CHECK: movsbq j(%rip), % +; CHECK: movsbq i(%rip), % + %0 = load <2 x i8>* @i, align 8 + %1 = load <2 x i8>* @j, align 8 + %div = sdiv <2 x i8> %1, %0 + store <2 x i8> %div, <2 x i8>* getelementptr inbounds (%union.anon* @res, i32 0, i32 0), align 8 + ret i32 0 +; CHECK: ret +} + diff --git a/test/CodeGen/X86/2011-10-19-widen_vselect.ll b/test/CodeGen/X86/2011-10-19-widen_vselect.ll new file mode 100644 index 0000000..e08c5b2 --- /dev/null +++ b/test/CodeGen/X86/2011-10-19-widen_vselect.ll @@ -0,0 +1,68 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" + +; Make sure that we don't crash when legalizng vselect and vsetcc and that +; we are able to generate vector blend instructions. + +; CHECK: simple_widen +; CHECK: blend +; CHECK: ret +define void @simple_widen() { +entry: + %0 = select <2 x i1> undef, <2 x float> undef, <2 x float> undef + store <2 x float> %0, <2 x float>* undef + ret void +} + +; CHECK: complex_inreg_work +; CHECK: blend +; CHECK: ret + +define void @complex_inreg_work() { +entry: + %0 = fcmp oeq <2 x float> undef, undef + %1 = select <2 x i1> %0, <2 x float> undef, <2 x float> undef + store <2 x float> %1, <2 x float>* undef + ret void +} + +; CHECK: zero_test +; CHECK: blend +; CHECK: ret + +define void @zero_test() { +entry: + %0 = select <2 x i1> undef, <2 x float> undef, <2 x float> zeroinitializer + store <2 x float> %0, <2 x float>* undef + ret void +} + +; CHECK: full_test +; CHECK: blend +; CHECK: ret + +define void @full_test() { + entry: + %Cy300 = alloca <4 x float> + %Cy11a = alloca <2 x float> + %Cy118 = alloca <2 x float> + %Cy119 = alloca <2 x float> + br label %B1 + + B1: ; preds = %entry + %0 = load <2 x float>* %Cy119 + %1 = fptosi <2 x float> %0 to <2 x i32> + %2 = sitofp <2 x i32> %1 to <2 x float> + %3 = fcmp ogt <2 x float> %0, zeroinitializer + %4 = fadd <2 x float> %2, <float 1.000000e+00, float 1.000000e+00> + %5 = select <2 x i1> %3, <2 x float> %4, <2 x float> %2 + %6 = fcmp oeq <2 x float> %2, %0 + %7 = select <2 x i1> %6, <2 x float> %0, <2 x float> %5 + store <2 x float> %7, <2 x float>* %Cy118 + %8 = load <2 x float>* %Cy118 + store <2 x float> %8, <2 x float>* %Cy11a + ret void +} + + diff --git a/test/CodeGen/X86/2011-10-21-widen-cmp.ll b/test/CodeGen/X86/2011-10-21-widen-cmp.ll new file mode 100644 index 0000000..2fe645b --- /dev/null +++ b/test/CodeGen/X86/2011-10-21-widen-cmp.ll @@ -0,0 +1,45 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" + +; Check that a <4 x float> compare is generated and that we are +; not stuck in an endless loop. + +; CHECK: cmp_2_floats +; CHECK: cmpordps +; CHECK: ret + +define void @cmp_2_floats() { +entry: + %0 = fcmp oeq <2 x float> undef, undef + %1 = select <2 x i1> %0, <2 x float> undef, <2 x float> undef + store <2 x float> %1, <2 x float>* undef + ret void +} + +; CHECK: cmp_2_doubles +; CHECK: cmpordpd +; CHECK: blendvpd +; CHECK: ret +define void @cmp_2_doubles() { +entry: + %0 = fcmp oeq <2 x double> undef, undef + %1 = select <2 x i1> %0, <2 x double> undef, <2 x double> undef + store <2 x double> %1, <2 x double>* undef + ret void +} + +; CHECK: mp_11193 +; CHECK: psraw $15 +; CHECK: ret +define void @mp_11193(<8 x float> * nocapture %aFOO, <8 x float>* nocapture %RET) +nounwind { +allocas: + %bincmp = fcmp olt <8 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 9.000000e+00, float 1.000000e+00, float 9.000000e+00, float 1.000000e+00> , <float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00> + %t = extractelement <8 x i1> %bincmp, i32 0 + %ft = sitofp i1 %t to float + %pp = bitcast <8 x float>* %RET to float* + store float %ft, float* %pp + ret void +} + diff --git a/test/CodeGen/X86/2011-10-27-tstore.ll b/test/CodeGen/X86/2011-10-27-tstore.ll new file mode 100644 index 0000000..6e83f67 --- /dev/null +++ b/test/CodeGen/X86/2011-10-27-tstore.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" + +;CHECK: ltstore +;CHECK: movq +;CHECK: movq +;CHECK: ret +define void @ltstore(<4 x i32>* %pA, <2 x i32>* %pB) { +entry: + %in = load <4 x i32>* %pA + %j = shufflevector <4 x i32> %in, <4 x i32> undef, <2 x i32> <i32 0, i32 1> + store <2 x i32> %j, <2 x i32>* %pB + ret void +} + diff --git a/test/CodeGen/X86/2011-10-30-padd.ll b/test/CodeGen/X86/2011-10-30-padd.ll new file mode 100644 index 0000000..180ca15 --- /dev/null +++ b/test/CodeGen/X86/2011-10-30-padd.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s -march=x86 -mcpu=corei7 | FileCheck %s + +;CHECK: addXX_test +;CHECK: padd +;CHECK: ret + + +define <16 x i8> @addXX_test(<16 x i8> %a) { + %b = add <16 x i8> %a, %a + ret <16 x i8> %b +} + +;CHECK: instcombine_test +;CHECK: padd +;CHECK: ret +define <16 x i8> @instcombine_test(<16 x i8> %a) { + %b = shl <16 x i8> %a, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + ret <16 x i8> %b +} + diff --git a/test/CodeGen/X86/2011-11-07-LegalizeBuildVector.ll b/test/CodeGen/X86/2011-11-07-LegalizeBuildVector.ll new file mode 100644 index 0000000..d316470 --- /dev/null +++ b/test/CodeGen/X86/2011-11-07-LegalizeBuildVector.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -march=x86 -mattr=+avx | FileCheck %s + +; We don't really care what this outputs; just make sure it's somewhat sane. +; CHECK: legalize_test +; CHECK: vmovups +define void @legalize_test(i32 %x, <8 x i32>* %p) nounwind { +entry: + %t1 = insertelement <8 x i32> <i32 undef, i32 undef, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15>, i32 %x, i32 0 + %t2 = shufflevector <8 x i32> %t1, <8 x i32> zeroinitializer, <8 x i32> <i32 0, i32 9, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> + %int2float = sitofp <8 x i32> %t2 to <8 x float> + %blendAsInt.i821 = bitcast <8 x float> %int2float to <8 x i32> + store <8 x i32> %blendAsInt.i821, <8 x i32>* %p, align 4 + ret void +} diff --git a/test/CodeGen/X86/2011-11-22-AVX2-Domains.ll b/test/CodeGen/X86/2011-11-22-AVX2-Domains.ll new file mode 100644 index 0000000..8174109 --- /dev/null +++ b/test/CodeGen/X86/2011-11-22-AVX2-Domains.ll @@ -0,0 +1,99 @@ +; RUN: llc < %s -mcpu=corei7-avx -mattr=+avx | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-darwin11" + +; This test would create a vpand %ymm instruction that is only legal in AVX2. +; CHECK-NOT: vpand %ymm + +declare i32 @llvm.x86.avx.movmsk.ps.256(<8 x float>) nounwind readnone + +define void @ShadeTile() nounwind { +allocas: + br i1 undef, label %if_then, label %if_else + +if_then: ; preds = %allocas + unreachable + +if_else: ; preds = %allocas + br i1 undef, label %for_loop156.lr.ph, label %if_exit + +for_loop156.lr.ph: ; preds = %if_else + %val_6.i21244 = load i16* undef, align 2 + %0 = insertelement <8 x i16> undef, i16 %val_6.i21244, i32 6 + %val_7.i21248 = load i16* undef, align 2 + %1 = insertelement <8 x i16> %0, i16 %val_7.i21248, i32 7 + %uint2uint32.i20206 = zext <8 x i16> %1 to <8 x i32> + %bitop5.i20208 = and <8 x i32> %uint2uint32.i20206, <i32 31744, i32 31744, i32 31744, i32 31744, i32 31744, i32 31744, i32 31744, i32 31744> + %bitop8.i20209 = and <8 x i32> %uint2uint32.i20206, <i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023> + %bitop12.i20211 = lshr <8 x i32> %bitop5.i20208, <i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10> + %binop13.i20212 = add <8 x i32> %bitop12.i20211, <i32 112, i32 112, i32 112, i32 112, i32 112, i32 112, i32 112, i32 112> + %bitop15.i20213 = shl <8 x i32> %binop13.i20212, <i32 23, i32 23, i32 23, i32 23, i32 23, i32 23, i32 23, i32 23> + %bitop17.i20214 = shl <8 x i32> %bitop8.i20209, <i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13, i32 13> + %bitop20.i20215 = or <8 x i32> undef, %bitop15.i20213 + %bitop22.i20216 = or <8 x i32> %bitop20.i20215, %bitop17.i20214 + %int_to_float_bitcast.i.i.i20217 = bitcast <8 x i32> %bitop22.i20216 to <8 x float> + %binop401 = fmul <8 x float> undef, <float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00> + %binop402 = fadd <8 x float> %binop401, <float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00> + %binop403 = fmul <8 x float> zeroinitializer, %binop402 + %binop406 = fmul <8 x float> %int_to_float_bitcast.i.i.i20217, <float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00, float 4.000000e+00> + %binop407 = fadd <8 x float> %binop406, <float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00, float -2.000000e+00> + %binop408 = fmul <8 x float> zeroinitializer, %binop407 + %binop411 = fsub <8 x float> <float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00>, undef + %val_4.i21290 = load i16* undef, align 2 + %2 = insertelement <8 x i16> undef, i16 %val_4.i21290, i32 4 + %val_5.i21294 = load i16* undef, align 2 + %3 = insertelement <8 x i16> %2, i16 %val_5.i21294, i32 5 + %val_6.i21298 = load i16* undef, align 2 + %4 = insertelement <8 x i16> %3, i16 %val_6.i21298, i32 6 + %ptr_7.i21301 = inttoptr i64 undef to i16* + %val_7.i21302 = load i16* %ptr_7.i21301, align 2 + %5 = insertelement <8 x i16> %4, i16 %val_7.i21302, i32 7 + %uint2uint32.i20218 = zext <8 x i16> %5 to <8 x i32> + %structelement561 = load i8** undef, align 8 + %ptr2int563 = ptrtoint i8* %structelement561 to i64 + %smear.ptr_smear7571 = insertelement <8 x i64> undef, i64 %ptr2int563, i32 7 + %new_ptr582 = add <8 x i64> %smear.ptr_smear7571, zeroinitializer + %val_5.i21509 = load i8* null, align 1 + %6 = insertelement <8 x i8> undef, i8 %val_5.i21509, i32 5 + %7 = insertelement <8 x i8> %6, i8 undef, i32 6 + %iptr_7.i21515 = extractelement <8 x i64> %new_ptr582, i32 7 + %ptr_7.i21516 = inttoptr i64 %iptr_7.i21515 to i8* + %val_7.i21517 = load i8* %ptr_7.i21516, align 1 + %8 = insertelement <8 x i8> %7, i8 %val_7.i21517, i32 7 + %uint2float.i20245 = uitofp <8 x i8> %8 to <8 x float> + %binop.i20246 = fmul <8 x float> %uint2float.i20245, <float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000> + br i1 undef, label %for_loop594.lr.ph, label %for_exit595 + +if_exit: ; preds = %if_else + ret void + +for_loop594.lr.ph: ; preds = %for_loop156.lr.ph + %bitop8.i20221 = and <8 x i32> %uint2uint32.i20218, <i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023> + br i1 undef, label %cif_test_all730, label %cif_mask_mixed1552 + +for_exit595: ; preds = %for_loop156.lr.ph + unreachable + +cif_test_all730: ; preds = %for_loop594.lr.ph + %binop11.i20545 = fmul <8 x float> %binop408, zeroinitializer + %binop12.i20546 = fadd <8 x float> undef, %binop11.i20545 + %binop15.i20547 = fmul <8 x float> %binop411, undef + %binop16.i20548 = fadd <8 x float> %binop12.i20546, %binop15.i20547 + %bincmp774 = fcmp ogt <8 x float> %binop16.i20548, zeroinitializer + %val_to_boolvec32775 = sext <8 x i1> %bincmp774 to <8 x i32> + %floatmask.i20549 = bitcast <8 x i32> %val_to_boolvec32775 to <8 x float> + %v.i20550 = tail call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %floatmask.i20549) nounwind readnone + %cond = icmp eq i32 %v.i20550, 255 + br i1 %cond, label %cif_test_all794, label %cif_test_mixed + +cif_test_all794: ; preds = %cif_test_all730 + %binop.i20572 = fmul <8 x float> %binop403, undef + unreachable + +cif_test_mixed: ; preds = %cif_test_all730 + %binop1207 = fmul <8 x float> %binop.i20246, undef + unreachable + +cif_mask_mixed1552: ; preds = %for_loop594.lr.ph + unreachable +} diff --git a/test/CodeGen/X86/2011-11-30-or.ll b/test/CodeGen/X86/2011-11-30-or.ll new file mode 100644 index 0000000..0a949eb --- /dev/null +++ b/test/CodeGen/X86/2011-11-30-or.ll @@ -0,0 +1,25 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target triple = "x86_64-apple-macosx10.6.6" + +; Test that the order of operands is correct +; CHECK: select_func +; CHECK: pblendvb %xmm1, %xmm2 +; CHECK: ret + +define void @select_func() { +entry: + %c.lobit.i.i.i = ashr <8 x i16> <i16 17, i16 5, i16 1, i16 15, i16 19, i16 15, i16 4, i16 1> , <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> + %a35 = bitcast <8 x i16> %c.lobit.i.i.i to <2 x i64> + %and.i56.i.i.i = and <8 x i16> %c.lobit.i.i.i, <i16 25, i16 8, i16 65, i16 25, i16 8, i16 95, i16 15, i16 45> + %and.i5.i.i.i = bitcast <8 x i16> %and.i56.i.i.i to <2 x i64> + %neg.i.i.i.i = xor <2 x i64> %a35, <i64 -1, i64 -1> + %and.i.i.i.i = and <2 x i64> zeroinitializer, %neg.i.i.i.i + %or.i.i.i.i = or <2 x i64> %and.i.i.i.i, %and.i5.i.i.i + %a37 = bitcast <2 x i64> %or.i.i.i.i to <8 x i16> + store <8 x i16> %a37, <8 x i16> addrspace(1)* undef, align 4 + ret void +} + + diff --git a/test/CodeGen/X86/2011-12-06-AVXVectorExtractCombine.ll b/test/CodeGen/X86/2011-12-06-AVXVectorExtractCombine.ll new file mode 100644 index 0000000..fcaabdd --- /dev/null +++ b/test/CodeGen/X86/2011-12-06-AVXVectorExtractCombine.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s +; PR11494 + +define void @test(<4 x i32>* nocapture %p) nounwind { + ; CHECK: test: + ; CHECK: vpxor %xmm0, %xmm0, %xmm0 + ; CHECK-NEXT: vpmaxsd {{.*}}, %xmm0, %xmm0 + ; CHECK-NEXT: vmovdqu %xmm0, (%rdi) + ; CHECK-NEXT: ret + %a = call <4 x i32> @llvm.x86.sse41.pmaxsd(<4 x i32> <i32 -8, i32 -9, i32 -10, i32 -11>, <4 x i32> zeroinitializer) nounwind + %b = shufflevector <4 x i32> %a, <4 x i32> undef, <8 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 0, i32 1, i32 2, i32 3> + %c = shufflevector <8 x i32> %b, <8 x i32> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> + store <4 x i32> %c, <4 x i32>* %p, align 1 + ret void +} + +declare <4 x i32> @llvm.x86.sse41.pminsd(<4 x i32>, <4 x i32>) nounwind readnone +declare <4 x i32> @llvm.x86.sse41.pmaxsd(<4 x i32>, <4 x i32>) nounwind readnone diff --git a/test/CodeGen/X86/2011-12-06-BitcastVectorGlobal.ll b/test/CodeGen/X86/2011-12-06-BitcastVectorGlobal.ll new file mode 100644 index 0000000..7a4126f --- /dev/null +++ b/test/CodeGen/X86/2011-12-06-BitcastVectorGlobal.ll @@ -0,0 +1,5 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s +; PR11495 + +; CHECK: 1311768467463790320 +@v = global <2 x float> bitcast (<1 x i64> <i64 1311768467463790320> to <2 x float>), align 8 diff --git a/test/CodeGen/X86/2011-12-08-AVXISelBugs.ll b/test/CodeGen/X86/2011-12-08-AVXISelBugs.ll new file mode 100644 index 0000000..1561784 --- /dev/null +++ b/test/CodeGen/X86/2011-12-08-AVXISelBugs.ll @@ -0,0 +1,80 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7-avx -mattr=+avx +; Various missing patterns causing crashes. +; rdar://10538793 + +define void @t1() nounwind { +entry: + br label %loop.cond + +loop.cond: ; preds = %t1.exit, %entry + br i1 false, label %return, label %loop + +loop: ; preds = %loop.cond + br i1 undef, label %0, label %t1.exit + +; <label>:0 ; preds = %loop + %1 = load <16 x i32> addrspace(1)* undef, align 64 + %2 = shufflevector <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>, <16 x i32> %1, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 16, i32 0, i32 0> + store <16 x i32> %2, <16 x i32> addrspace(1)* undef, align 64 + br label %t1.exit + +t1.exit: ; preds = %0, %loop + br label %loop.cond + +return: ; preds = %loop.cond + ret void +} + +define void @t2() nounwind { + br i1 undef, label %1, label %4 + +; <label>:1 ; preds = %0 + %2 = load <16 x i32> addrspace(1)* undef, align 64 + %3 = shufflevector <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>, <16 x i32> %2, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 0, i32 0, i32 0, i32 0> + store <16 x i32> %3, <16 x i32> addrspace(1)* undef, align 64 + br label %4 + +; <label>:4 ; preds = %1, %0 + ret void +} + +define void @t3() nounwind { +entry: + br label %loop.cond + +loop.cond: ; preds = %t2.exit, %entry + br i1 false, label %return, label %loop + +loop: ; preds = %loop.cond + br i1 undef, label %0, label %t2.exit + +; <label>:0 ; preds = %loop + %1 = shufflevector <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>, <16 x i32> undef, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 25, i32 0> + %2 = load <16 x i32> addrspace(1)* undef, align 64 + %3 = shufflevector <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>, <16 x i32> %2, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 28, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> + store <16 x i32> %3, <16 x i32> addrspace(1)* undef, align 64 + br label %t2.exit + +t2.exit: ; preds = %0, %loop + br label %loop.cond + +return: ; preds = %loop.cond + ret void +} + +define <3 x i64> @t4() nounwind { +entry: + %0 = load <2 x i64> addrspace(1)* undef, align 16 + %1 = extractelement <2 x i64> %0, i32 0 + %2 = insertelement <3 x i64> <i64 undef, i64 0, i64 0>, i64 %1, i32 0 + ret <3 x i64> %2 +} + +define void @t5() nounwind { +entry: + %0 = shufflevector <2 x i64> zeroinitializer, <2 x i64> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> + %1 = shufflevector <8 x i64> <i64 0, i64 0, i64 0, i64 undef, i64 undef, i64 0, i64 0, i64 0>, <8 x i64> %0, <8 x i32> <i32 0, i32 1, i32 2, i32 9, i32 8, i32 5, i32 6, i32 7> + store <8 x i64> %1, <8 x i64> addrspace(1)* undef, align 64 + + ret void +} diff --git a/test/CodeGen/X86/2011-12-15-vec_shift.ll b/test/CodeGen/X86/2011-12-15-vec_shift.ll new file mode 100644 index 0000000..6f9188c --- /dev/null +++ b/test/CodeGen/X86/2011-12-15-vec_shift.ll @@ -0,0 +1,19 @@ +; RUN: llc -march=x86-64 -mattr=+sse41 < %s | FileCheck %s -check-prefix=CHECK-W-SSE4 +; RUN: llc -march=x86-64 -mattr=-sse41 < %s | FileCheck %s -check-prefix=CHECK-WO-SSE4 +; Test case for r146671 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7" + +define <16 x i8> @shift(<16 x i8> %a, <16 x i8> %b) nounwind { + ; Make sure operands to pblend are in the right order. + ; CHECK-W-SSE4: psllw $4, [[REG1:%xmm.]] + ; CHECK-W-SSE4: pblendvb [[REG1]],{{ %xmm.}} + ; CHECK-W-SSE4: psllw $2 + + ; Make sure we're masking and pcmp'ing the VSELECT conditon vector. + ; CHECK-WO-SSE4: psllw $5, [[REG1:%xmm.]] + ; CHECK-WO-SSE4: pand [[REG1]], [[REG2:%xmm.]] + ; CHECK-WO-SSE4: pcmpeqb {{%xmm., }}[[REG2]] + %1 = shl <16 x i8> %a, %b + ret <16 x i8> %1 +} diff --git a/test/CodeGen/X86/2011-12-26-extractelement-duplicate-load.ll b/test/CodeGen/X86/2011-12-26-extractelement-duplicate-load.ll new file mode 100644 index 0000000..39c213f --- /dev/null +++ b/test/CodeGen/X86/2011-12-26-extractelement-duplicate-load.ll @@ -0,0 +1,16 @@ +; RUN: llc -march=x86-64 -mattr=-sse42,+sse41 < %s | FileCheck %s +; Make sure we don't load from the location pointed to by %p +; twice: it has non-obvious performance implications, and +; the relevant transformation doesn't know how to update +; the chains correctly. +; PR10747 + +; CHECK: test: +; CHECK: pextrd $2, %xmm +define <4 x i32> @test(<4 x i32>* %p) { + %v = load <4 x i32>* %p + %e = extractelement <4 x i32> %v, i32 2 + %cmp = icmp eq i32 %e, 3 + %sel = select i1 %cmp, <4 x i32> %v, <4 x i32> zeroinitializer + ret <4 x i32> %sel +} diff --git a/test/CodeGen/X86/2011-12-28-vselecti8.ll b/test/CodeGen/X86/2011-12-28-vselecti8.ll new file mode 100644 index 0000000..dbc122a --- /dev/null +++ b/test/CodeGen/X86/2011-12-28-vselecti8.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s +; ModuleID = '<stdin>' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-darwin11.2.0" + +; CHECK: @foo8 +; CHECK: psll +; CHECK: psraw +; CHECK: pblendvb +; CHECK: ret +define void @foo8(float* nocapture %RET) nounwind { +allocas: + %resultvec.i = select <8 x i1> <i1 false, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true>, <8 x i8> <i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8>, <8 x i8> <i8 100, i8 100, i8 100, i8 100, i8 100, i8 100, i8 100, i8 100> + %uint2float = uitofp <8 x i8> %resultvec.i to <8 x float> + %ptr = bitcast float * %RET to <8 x float> * + store <8 x float> %uint2float, <8 x float>* %ptr, align 4 + ret void +} + + diff --git a/test/CodeGen/X86/2011-12-8-bitcastintprom.ll b/test/CodeGen/X86/2011-12-8-bitcastintprom.ll new file mode 100644 index 0000000..e2b3ebc --- /dev/null +++ b/test/CodeGen/X86/2011-12-8-bitcastintprom.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s + +; Make sure that the conversion between v4i8 to v2i16 is not a simple bitcast. +; CHECK: prom_bug +; CHECK: shufb +; CHECK: movd +; CHECK: movw +; CHECK: ret +define void @prom_bug(<4 x i8> %t, i16* %p) { + %r = bitcast <4 x i8> %t to <2 x i16> + %o = extractelement <2 x i16> %r, i32 0 + store i16 %o, i16* %p + ret void +} + diff --git a/test/CodeGen/X86/2011-20-21-zext-ui2fp.ll b/test/CodeGen/X86/2011-20-21-zext-ui2fp.ll new file mode 100644 index 0000000..75efcf5 --- /dev/null +++ b/test/CodeGen/X86/2011-20-21-zext-ui2fp.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 | FileCheck %s +target triple = "x86_64-unknown-linux-gnu" + +; Check that the booleans are converted using zext and not via sext. +; 0x1 means that we only look at the first bit. + +;CHECK: 0x1 +;CHECK: ui_to_fp_conv +;CHECK: ret +define void @ui_to_fp_conv(<8 x float> * nocapture %aFOO, <8 x float>* nocapture %RET) nounwind { +allocas: + %bincmp = fcmp olt <8 x float> <float 1.000000e+00, float 1.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00> , <float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00, float 3.000000e+00> + %bool2float = uitofp <8 x i1> %bincmp to <8 x float> + store <8 x float> %bool2float, <8 x float>* %RET, align 4 + ret void +} + + + diff --git a/test/CodeGen/X86/2012-01-10-UndefExceptionEdge.ll b/test/CodeGen/X86/2012-01-10-UndefExceptionEdge.ll new file mode 100644 index 0000000..832a8eb --- /dev/null +++ b/test/CodeGen/X86/2012-01-10-UndefExceptionEdge.ll @@ -0,0 +1,155 @@ +; RUN: llc < %s -disable-fp-elim +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128" +target triple = "i386-apple-macosx10.7" + +; This test case has a landing pad with two predecessors, and a variable that +; is undef on the first edge while carrying the first function return value on +; the second edge. +; +; Live range splitting tries to isolate the block containing the first function +; call, and it is important that the last split point is after the function call +; so the return value can spill. +; +; <rdar://problem/10664933> + +@Exception = external unnamed_addr constant { i8*, i8* } + +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind + +define void @f(i32* nocapture %arg, i32* nocapture %arg1, i32* nocapture %arg2, i32* nocapture %arg3, i32 %arg4, i32 %arg5) optsize ssp { +bb: + br i1 undef, label %bb6, label %bb7 + +bb6: ; preds = %bb + %tmp = select i1 false, i32 0, i32 undef + br label %bb7 + +bb7: ; preds = %bb6, %bb + %tmp8 = phi i32 [ %tmp, %bb6 ], [ 0, %bb ] + %tmp9 = shl i32 %tmp8, 2 + %tmp10 = invoke noalias i8* @_Znam(i32 undef) optsize + to label %bb11 unwind label %bb20 + +bb11: ; preds = %bb7 + %tmp12 = ptrtoint i8* %tmp10 to i32 + %tmp13 = bitcast i8* %tmp10 to i32* + %tmp14 = shl i32 %tmp8, 2 + %tmp15 = getelementptr i32* %tmp13, i32 undef + %tmp16 = getelementptr i32* %tmp13, i32 undef + %tmp17 = zext i32 %tmp9 to i64 + %tmp18 = add i64 %tmp17, -1 + %tmp19 = icmp ugt i64 %tmp18, 4294967295 + br i1 %tmp19, label %bb29, label %bb31 + +bb20: ; preds = %bb43, %bb41, %bb29, %bb7 + %tmp21 = phi i32 [ undef, %bb7 ], [ %tmp12, %bb43 ], [ %tmp12, %bb29 ], [ %tmp12, %bb41 ] + %tmp22 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast ({ i8*, i8* }* @Exception to i8*) + br i1 undef, label %bb23, label %bb69 + +bb23: ; preds = %bb38, %bb20 + %tmp24 = phi i32 [ %tmp12, %bb38 ], [ %tmp21, %bb20 ] + %tmp25 = icmp eq i32 %tmp24, 0 + br i1 %tmp25, label %bb28, label %bb26 + +bb26: ; preds = %bb23 + %tmp27 = inttoptr i32 %tmp24 to i8* + br label %bb28 + +bb28: ; preds = %bb26, %bb23 + ret void + +bb29: ; preds = %bb11 + invoke void @OnOverFlow() optsize + to label %bb30 unwind label %bb20 + +bb30: ; preds = %bb29 + unreachable + +bb31: ; preds = %bb11 + %tmp32 = bitcast i32* %tmp15 to i8* + %tmp33 = zext i32 %tmp8 to i64 + %tmp34 = add i64 %tmp33, -1 + %tmp35 = icmp ugt i64 %tmp34, 4294967295 + %tmp36 = icmp sgt i32 %tmp8, 0 + %tmp37 = add i32 %tmp9, -4 + br label %bb38 + +bb38: ; preds = %bb67, %bb31 + %tmp39 = phi i32 [ %tmp68, %bb67 ], [ undef, %bb31 ] + %tmp40 = icmp sgt i32 %tmp39, undef + br i1 %tmp40, label %bb41, label %bb23 + +bb41: ; preds = %bb38 + invoke void @Pjii(i32* %tmp16, i32 0, i32 %tmp8) optsize + to label %bb42 unwind label %bb20 + +bb42: ; preds = %bb41 + tail call void @llvm.memset.p0i8.i32(i8* %tmp32, i8 0, i32 %tmp9, i32 1, i1 false) nounwind + br i1 %tmp35, label %bb43, label %bb45 + +bb43: ; preds = %bb42 + invoke void @OnOverFlow() optsize + to label %bb44 unwind label %bb20 + +bb44: ; preds = %bb43 + unreachable + +bb45: ; preds = %bb57, %bb42 + %tmp46 = phi i32 [ %tmp58, %bb57 ], [ 255, %bb42 ] + %tmp47 = icmp slt i32 undef, 0 + br i1 %tmp47, label %bb48, label %bb59 + +bb48: ; preds = %bb45 + tail call void @llvm.memset.p0i8.i32(i8* %tmp32, i8 0, i32 %tmp9, i32 1, i1 false) nounwind + br i1 %tmp36, label %bb49, label %bb57 + +bb49: ; preds = %bb49, %bb48 + %tmp50 = phi i32 [ %tmp55, %bb49 ], [ 0, %bb48 ] + %tmp51 = add i32 %tmp50, undef + %tmp52 = add i32 %tmp50, undef + %tmp53 = getelementptr i32* %tmp13, i32 %tmp52 + %tmp54 = load i32* %tmp53, align 4, !tbaa !0 + %tmp55 = add i32 %tmp50, 1 + %tmp56 = icmp eq i32 %tmp55, %tmp8 + br i1 %tmp56, label %bb57, label %bb49 + +bb57: ; preds = %bb49, %bb48 + %tmp58 = add i32 %tmp46, -1 + br label %bb45 + +bb59: ; preds = %bb45 + %tmp60 = ashr i32 %tmp46, 31 + tail call void @llvm.memset.p0i8.i32(i8* null, i8 0, i32 %tmp37, i32 1, i1 false) nounwind + br i1 %tmp36, label %bb61, label %bb67 + +bb61: ; preds = %bb61, %bb59 + %tmp62 = phi i32 [ %tmp65, %bb61 ], [ 0, %bb59 ] + %tmp63 = add i32 %tmp62, %tmp14 + %tmp64 = getelementptr i32* %tmp13, i32 %tmp63 + store i32 0, i32* %tmp64, align 4, !tbaa !0 + %tmp65 = add i32 %tmp62, 1 + %tmp66 = icmp eq i32 %tmp65, %tmp8 + br i1 %tmp66, label %bb67, label %bb61 + +bb67: ; preds = %bb61, %bb59 + %tmp68 = add i32 %tmp39, -1 + br label %bb38 + +bb69: ; preds = %bb20 + resume { i8*, i32 } %tmp22 +} + +declare i32 @__gxx_personality_v0(...) + +declare noalias i8* @_Znam(i32) optsize + +declare void @Pjii(i32*, i32, i32) optsize + +declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone + +declare void @OnOverFlow() noreturn optsize ssp align 2 + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} diff --git a/test/CodeGen/X86/2012-01-11-split-cv.ll b/test/CodeGen/X86/2012-01-11-split-cv.ll new file mode 100644 index 0000000..6b90072 --- /dev/null +++ b/test/CodeGen/X86/2012-01-11-split-cv.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s -march=x86 -mcpu=corei7-avx -mattr=+avx -mtriple=i686-pc-win32 | FileCheck %s + +;CHECK: add18i16 +define void @add18i16(<18 x i16>* nocapture sret %ret, <18 x i16>* %bp) nounwind { +;CHECK: vmovups + %b = load <18 x i16>* %bp, align 16 + %x = add <18 x i16> zeroinitializer, %b + store <18 x i16> %x, <18 x i16>* %ret, align 16 +;CHECK: ret + ret void +} + diff --git a/test/CodeGen/X86/2012-01-12-extract-sv.ll b/test/CodeGen/X86/2012-01-12-extract-sv.ll new file mode 100644 index 0000000..fa8e80f --- /dev/null +++ b/test/CodeGen/X86/2012-01-12-extract-sv.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s -march=x86 -mcpu=corei7-avx -mattr=+avx -mtriple=i686-pc-win32 | FileCheck %s + +; CHECK: endless_loop +define void @endless_loop() { +entry: + %0 = load <8 x i32> addrspace(1)* undef, align 32 + %1 = shufflevector <8 x i32> %0, <8 x i32> undef, <16 x i32> <i32 4, i32 4, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> + %2 = shufflevector <16 x i32> <i32 undef, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 undef>, <16 x i32> %1, <16 x i32> <i32 16, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 17> + store <16 x i32> %2, <16 x i32> addrspace(1)* undef, align 64 + ret void +; CHECK: ret +} diff --git a/test/CodeGen/X86/2012-01-16-mfence-nosse-flags.ll b/test/CodeGen/X86/2012-01-16-mfence-nosse-flags.ll new file mode 100644 index 0000000..a883d79 --- /dev/null +++ b/test/CodeGen/X86/2012-01-16-mfence-nosse-flags.ll @@ -0,0 +1,34 @@ +; RUN: llc < %s -mtriple=i686-linux -mattr=-sse | FileCheck %s +; PR11768 + +@ptr = external global i8* + +define void @baz() nounwind ssp { +entry: + %0 = load i8** @ptr, align 4 + %cmp = icmp eq i8* %0, null + fence seq_cst + br i1 %cmp, label %if.then, label %if.else + +; Make sure the fence comes before the comparison, since it +; clobbers EFLAGS. + +; CHECK: lock +; CHECK-NEXT: orl {{.*}}, (%esp) +; CHECK-NEXT: cmpl $0 + +if.then: ; preds = %entry + tail call void bitcast (void (...)* @foo to void ()*)() nounwind + br label %if.end + +if.else: ; preds = %entry + tail call void bitcast (void (...)* @bar to void ()*)() nounwind + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +declare void @foo(...) + +declare void @bar(...) diff --git a/test/CodeGen/X86/2012-01-18-vbitcast.ll b/test/CodeGen/X86/2012-01-18-vbitcast.ll new file mode 100644 index 0000000..8a3ccc8 --- /dev/null +++ b/test/CodeGen/X86/2012-01-18-vbitcast.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 -mtriple=x86_64-pc-win32 | FileCheck %s + +;CHECK: vcast +define <2 x i32> @vcast(<2 x float> %a, <2 x float> %b) { +;CHECK: pshufd +;CHECK: pshufd + %af = bitcast <2 x float> %a to <2 x i32> + %bf = bitcast <2 x float> %b to <2 x i32> + %x = sub <2 x i32> %af, %bf +;CHECK: psubq + ret <2 x i32> %x +;CHECK: ret +} + diff --git a/test/CodeGen/X86/2012-02-12-dagco.ll b/test/CodeGen/X86/2012-02-12-dagco.ll new file mode 100644 index 0000000..13723a2 --- /dev/null +++ b/test/CodeGen/X86/2012-02-12-dagco.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx +target triple = "x86_64-unknown-linux-gnu" +; Make sure we are not crashing on this one +define void @dagco_crash() { +entry: + %srcval.i411.i = load <4 x i64>* undef, align 1 + %0 = extractelement <4 x i64> %srcval.i411.i, i32 3 + %srcval.i409.i = load <2 x i64>* undef, align 1 + %1 = extractelement <2 x i64> %srcval.i409.i, i32 0 + %2 = insertelement <8 x i64> undef, i64 %0, i32 5 + %3 = insertelement <8 x i64> %2, i64 %1, i32 6 + %4 = insertelement <8 x i64> %3, i64 undef, i32 7 + store <8 x i64> %4, <8 x i64> addrspace(1)* undef, align 64 + unreachable +} + diff --git a/test/CodeGen/X86/2012-02-14-scalar.ll b/test/CodeGen/X86/2012-02-14-scalar.ll new file mode 100644 index 0000000..1dc076b --- /dev/null +++ b/test/CodeGen/X86/2012-02-14-scalar.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx +target triple = "x86_64-unknown-linux-gnu" +; Make sure we are not crashing on this one +define void @autogen_28112_5000() { +BB: + %S17 = icmp sgt <1 x i64> undef, undef + %E19 = extractelement <1 x i1> %S17, i32 0 + br label %CF + +CF: ; preds = %CF, %BB + %S23 = select i1 %E19, i8 undef, i8 undef + br label %CF +} diff --git a/test/CodeGen/X86/2012-02-20-MachineCPBug.ll b/test/CodeGen/X86/2012-02-20-MachineCPBug.ll new file mode 100644 index 0000000..557d49d --- /dev/null +++ b/test/CodeGen/X86/2012-02-20-MachineCPBug.ll @@ -0,0 +1,78 @@ +; RUN: llc < %s -mtriple=i386-apple-macosx -mattr=+sse | FileCheck %s +; PR11940: Do not optimize away movb %al, %ch + +%struct.APInt = type { i64* } + +declare noalias i8* @calloc(i32, i32) nounwind + +define void @bug(%struct.APInt* noalias nocapture sret %agg.result, %struct.APInt* nocapture %this, i32 %rotateAmt) nounwind align 2 { +entry: +; CHECK: bug: + %call = tail call i8* @calloc(i32 1, i32 32) + %call.i = tail call i8* @calloc(i32 1, i32 32) nounwind + %0 = bitcast i8* %call.i to i64* + %rem.i = and i32 %rotateAmt, 63 + %div.i = lshr i32 %rotateAmt, 6 + %cmp.i = icmp eq i32 %rem.i, 0 + br i1 %cmp.i, label %for.cond.preheader.i, label %if.end.i + +for.cond.preheader.i: ; preds = %entry + %sub.i = sub i32 4, %div.i + %cmp23.i = icmp eq i32 %div.i, 4 + br i1 %cmp23.i, label %for.body9.lr.ph.i, label %for.body.lr.ph.i + +for.body.lr.ph.i: ; preds = %for.cond.preheader.i + %pVal.i = getelementptr inbounds %struct.APInt* %this, i32 0, i32 0 + %.pre5.i = load i64** %pVal.i, align 4 + br label %for.body.i + +for.body.i: ; preds = %for.body.i, %for.body.lr.ph.i + %i.04.i = phi i32 [ 0, %for.body.lr.ph.i ], [ %inc.i, %for.body.i ] + %add.i = add i32 %i.04.i, %div.i + %arrayidx.i = getelementptr inbounds i64* %.pre5.i, i32 %add.i + %1 = load i64* %arrayidx.i, align 4 + %arrayidx3.i = getelementptr inbounds i64* %0, i32 %i.04.i + store i64 %1, i64* %arrayidx3.i, align 4 + %inc.i = add i32 %i.04.i, 1 + %cmp2.i = icmp ult i32 %inc.i, %sub.i + br i1 %cmp2.i, label %for.body.i, label %if.end.i + +if.end.i: ; preds = %for.body.i, %entry + %cmp81.i = icmp eq i32 %div.i, 3 + br i1 %cmp81.i, label %_ZNK5APInt4lshrEj.exit, label %for.body9.lr.ph.i + +for.body9.lr.ph.i: ; preds = %if.end.i, %for.cond.preheader.i + %sub58.i = sub i32 3, %div.i + %pVal11.i = getelementptr inbounds %struct.APInt* %this, i32 0, i32 0 + %sh_prom.i = zext i32 %rem.i to i64 + %sub17.i = sub i32 64, %rem.i + %sh_prom18.i = zext i32 %sub17.i to i64 + %.pre.i = load i64** %pVal11.i, align 4 + br label %for.body9.i + +for.body9.i: ; preds = %for.body9.i, %for.body9.lr.ph.i +; CHECK: %for.body9.i +; CHECK: movb +; CHECK: shrdl + %i6.02.i = phi i32 [ 0, %for.body9.lr.ph.i ], [ %inc21.i, %for.body9.i ] + %add10.i = add i32 %i6.02.i, %div.i + %arrayidx12.i = getelementptr inbounds i64* %.pre.i, i32 %add10.i + %2 = load i64* %arrayidx12.i, align 4 + %shr.i = lshr i64 %2, %sh_prom.i + %add14.i = add i32 %add10.i, 1 + %arrayidx16.i = getelementptr inbounds i64* %.pre.i, i32 %add14.i + %3 = load i64* %arrayidx16.i, align 4 + %shl.i = shl i64 %3, %sh_prom18.i + %or.i = or i64 %shl.i, %shr.i + %arrayidx19.i = getelementptr inbounds i64* %0, i32 %i6.02.i + store i64 %or.i, i64* %arrayidx19.i, align 4 + %inc21.i = add i32 %i6.02.i, 1 + %cmp8.i = icmp ult i32 %inc21.i, %sub58.i + br i1 %cmp8.i, label %for.body9.i, label %_ZNK5APInt4lshrEj.exit + +_ZNK5APInt4lshrEj.exit: ; preds = %for.body9.i, %if.end.i + %call.i1 = tail call i8* @calloc(i32 1, i32 32) nounwind + %4 = getelementptr inbounds %struct.APInt* %agg.result, i32 0, i32 0 + store i64* %0, i64** %4, align 4 + ret void +} diff --git a/test/CodeGen/X86/2012-02-23-mmx-inlineasm.ll b/test/CodeGen/X86/2012-02-23-mmx-inlineasm.ll new file mode 100644 index 0000000..a55c77b --- /dev/null +++ b/test/CodeGen/X86/2012-02-23-mmx-inlineasm.ll @@ -0,0 +1,12 @@ +; RUN: llc -march=x86 -mcpu=i686 -mattr=+mmx < %s | FileCheck %s +; <rdar://problem/10106006> + +define void @func() nounwind ssp { +; CHECK: psrlw %mm0, %mm1 +entry: + call void asm sideeffect "psrlw $0, %mm1", "y,~{dirflag},~{fpsr},~{flags}"(i32 8) nounwind + unreachable + +bb367: ; preds = %entry + ret void +} diff --git a/test/CodeGen/X86/2012-02-29-CoalescerBug.ll b/test/CodeGen/X86/2012-02-29-CoalescerBug.ll new file mode 100644 index 0000000..bdce853 --- /dev/null +++ b/test/CodeGen/X86/2012-02-29-CoalescerBug.ll @@ -0,0 +1,58 @@ +; RUN: llc -O1 <%s +; PR12138 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128" +target triple = "i386-apple-macosx10.7.0" + +%struct.S0 = type { i8, i32 } + +@d = external global [2 x [2 x %struct.S0]], align 4 +@c = external global i32, align 4 +@e = external global i32, align 4 +@b = external global i32, align 4 +@a = external global i32, align 4 + +define void @fn2() nounwind optsize ssp { +entry: + store i64 0, i64* bitcast ([2 x [2 x %struct.S0]]* @d to i64*), align 4 + %0 = load i32* @c, align 4 + %tobool2 = icmp eq i32 %0, 0 + %1 = load i32* @a, align 4 + %tobool4 = icmp eq i32 %1, 0 + br label %for.cond + +for.cond: ; preds = %if.end, %entry + %f.1.0 = phi i32 [ undef, %entry ], [ %sub, %if.end ] + %g.0 = phi i64 [ 0, %entry ], [ %ins, %if.end ] + %tobool = icmp eq i32 %f.1.0, 0 + br i1 %tobool, label %for.end, label %for.body + +for.body: ; preds = %for.cond + %2 = lshr i64 %g.0, 32 + %conv = trunc i64 %2 to i16 + br i1 %tobool2, label %lor.rhs, label %lor.end + +lor.rhs: ; preds = %for.body + store i32 1, i32* @e, align 4 + br label %lor.end + +lor.end: ; preds = %lor.rhs, %for.body + %xor.i = xor i16 %conv, 1 + %p1.lobit.i8 = lshr i64 %g.0, 47 + %p1.lobit.i8.tr = trunc i64 %p1.lobit.i8 to i16 + %p1.lobit.i = and i16 %p1.lobit.i8.tr, 1 + %and.i = and i16 %p1.lobit.i, %xor.i + %3 = xor i16 %and.i, 1 + %sub.conv.i = sub i16 %conv, %3 + %conv3 = sext i16 %sub.conv.i to i32 + store i32 %conv3, i32* @b, align 4 + br i1 %tobool4, label %if.end, label %for.end + +if.end: ; preds = %lor.end + %mask = and i64 %g.0, -256 + %ins = or i64 %mask, 1 + %sub = add nsw i32 %f.1.0, -1 + br label %for.cond + +for.end: ; preds = %lor.end, %for.cond + ret void +} diff --git a/test/CodeGen/X86/2012-03-15-build_vector_wl.ll b/test/CodeGen/X86/2012-03-15-build_vector_wl.ll new file mode 100644 index 0000000..fec17e9 --- /dev/null +++ b/test/CodeGen/X86/2012-03-15-build_vector_wl.ll @@ -0,0 +1,10 @@ + +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s +; CHECK: build_vector_again +define <4 x i8> @build_vector_again(<16 x i8> %in) nounwind readnone { +entry: + %out = shufflevector <16 x i8> %in, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> +; CHECK: shufb + ret <4 x i8> %out +; CHECK: ret +} diff --git a/test/CodeGen/X86/2012-03-20-LargeConstantExpr.ll b/test/CodeGen/X86/2012-03-20-LargeConstantExpr.ll new file mode 100644 index 0000000..d24647e --- /dev/null +++ b/test/CodeGen/X86/2012-03-20-LargeConstantExpr.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s +; <rdar://problem/11070338> +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.8.0" + +; CHECK: _.memset_pattern: +; CHECK-NEXT: .quad 4575657222473777152 +; CHECK-NEXT: .quad 4575657222473777152 + +@.memset_pattern = internal unnamed_addr constant i128 or (i128 zext (i64 bitcast (<2 x float> <float 1.000000e+00, float 1.000000e+00> to i64) to i128), i128 shl (i128 zext (i64 bitcast (<2 x float> <float 1.000000e+00, float 1.000000e+00> to i64) to i128), i128 64)), align 16 + +define void @foo(i8* %a, i64 %b) { + call void @memset_pattern16(i8* %a, i8* bitcast (i128* @.memset_pattern to i8*), i64 %b) + ret void +} + +declare void @memset_pattern16(i8*, i8*, i64) diff --git a/test/CodeGen/X86/2012-03-26-PostRALICMBug.ll b/test/CodeGen/X86/2012-03-26-PostRALICMBug.ll new file mode 100644 index 0000000..101ecca --- /dev/null +++ b/test/CodeGen/X86/2012-03-26-PostRALICMBug.ll @@ -0,0 +1,59 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -stats |& \ +; RUN: not grep {Number of machine instructions hoisted out of loops post regalloc} + +; rdar://11095580 + +%struct.ref_s = type { %union.color_sample, i16, i16 } +%union.color_sample = type { i64 } + +@table = external global [3891 x i64] + +declare i32 @foo() + +define i32 @zarray(%struct.ref_s* nocapture %op) nounwind ssp { +entry: + %call = tail call i32 @foo() + %tmp = ashr i32 %call, 31 + %0 = and i32 %tmp, 1396 + %index9 = add i32 %0, 2397 + indirectbr i8* undef, [label %return, label %if.end] + +if.end: ; preds = %entry + %size5 = getelementptr inbounds %struct.ref_s* %op, i64 0, i32 2 + %tmp6 = load i16* %size5, align 2 + %tobool1 = icmp eq i16 %tmp6, 0 + %1 = select i1 %tobool1, i32 1396, i32 -1910 + %index10 = add i32 %index9, %1 + indirectbr i8* undef, [label %return, label %while.body.lr.ph] + +while.body.lr.ph: ; preds = %if.end + %refs = bitcast %struct.ref_s* %op to %struct.ref_s** + %tmp9 = load %struct.ref_s** %refs, align 8 + %tmp4 = zext i16 %tmp6 to i64 + %index13 = add i32 %index10, 1658 + %2 = sext i32 %index13 to i64 + %3 = getelementptr [3891 x i64]* @table, i64 0, i64 %2 + %blockaddress14 = load i64* %3, align 8 + %4 = inttoptr i64 %blockaddress14 to i8* + indirectbr i8* %4, [label %while.body] + +while.body: ; preds = %while.body, %while.body.lr.ph + %index7 = phi i32 [ %index15, %while.body ], [ %index13, %while.body.lr.ph ] + %indvar = phi i64 [ %indvar.next, %while.body ], [ 0, %while.body.lr.ph ] + %type_attrs = getelementptr %struct.ref_s* %tmp9, i64 %indvar, i32 1 + store i16 32, i16* %type_attrs, align 2 + %indvar.next = add i64 %indvar, 1 + %exitcond5 = icmp eq i64 %indvar.next, %tmp4 + %tmp7 = select i1 %exitcond5, i32 1648, i32 0 + %index15 = add i32 %index7, %tmp7 + %tmp8 = select i1 %exitcond5, i64 13, i64 0 + %5 = sext i32 %index15 to i64 + %6 = getelementptr [3891 x i64]* @table, i64 0, i64 %5 + %blockaddress16 = load i64* %6, align 8 + %7 = inttoptr i64 %blockaddress16 to i8* + indirectbr i8* %7, [label %return, label %while.body] + +return: ; preds = %while.body, %if.end, %entry + %retval.0 = phi i32 [ %call, %entry ], [ 0, %if.end ], [ 0, %while.body ] + ret i32 %retval.0 +} diff --git a/test/CodeGen/X86/2012-04-09-TwoAddrPassBug.ll b/test/CodeGen/X86/2012-04-09-TwoAddrPassBug.ll new file mode 100644 index 0000000..2d90165 --- /dev/null +++ b/test/CodeGen/X86/2012-04-09-TwoAddrPassBug.ll @@ -0,0 +1,34 @@ +; RUN: llc -O1 -verify-coalescing < %s +; PR12495 +target datalayout = +"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7.0" + +define void @func(i8* nocapture) nounwind uwtable ssp align 2 { + br i1 undef, label %4, label %2 + +; <label>:2 ; preds = %1 + %3 = tail call double @foo() nounwind + br label %4 + +; <label>:4 ; preds = %2, %1 + %5 = phi double [ %3, %2 ], [ 0.000000e+00, %1 ] + %6 = fsub double %5, undef + %7 = fcmp olt double %6, 0.000000e+00 + %8 = select i1 %7, double 0.000000e+00, double %6 + %9 = fcmp olt double undef, 0.000000e+00 + %10 = fcmp olt double %8, undef + %11 = or i1 %9, %10 + br i1 %11, label %12, label %14 + +; <label>:12 ; preds = %4 + %13 = tail call double @fmod(double %8, double 0.000000e+00) nounwind + unreachable + +; <label>:14 ; preds = %4 + ret void +} + +declare double @foo() + +declare double @fmod(double, double) diff --git a/test/CodeGen/X86/2012-1-10-buildvector.ll b/test/CodeGen/X86/2012-1-10-buildvector.ll new file mode 100644 index 0000000..ff6be36 --- /dev/null +++ b/test/CodeGen/X86/2012-1-10-buildvector.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -march=x86 -mcpu=corei7-avx -mattr=+avx -mtriple=i686-pc-win32 | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32" +target triple = "i686-pc-win32" + +;CHECK: bad_cast +define void @bad_cast() { +entry: + %vext.i = shufflevector <2 x i64> undef, <2 x i64> undef, <3 x i32> <i32 0, i32 1, i32 undef> + %vecinit8.i = shufflevector <3 x i64> zeroinitializer, <3 x i64> %vext.i, <3 x i32> <i32 0, i32 3, i32 4> + store <3 x i64> %vecinit8.i, <3 x i64>* undef, align 32 +;CHECK: ret + ret void +} + + +;CHECK: bad_insert +define void @bad_insert(i32 %t) { +entry: +;CHECK: vpinsrd + %v2 = insertelement <8 x i32> zeroinitializer, i32 %t, i32 0 + store <8 x i32> %v2, <8 x i32> addrspace(1)* undef, align 32 +;CHECK: ret + ret void +} + diff --git a/test/CodeGen/X86/GC/dg.exp b/test/CodeGen/X86/GC/dg.exp deleted file mode 100644 index 629a147..0000000 --- a/test/CodeGen/X86/GC/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if { [llvm_supports_target X86] } { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] -} diff --git a/test/CodeGen/X86/GC/lit.local.cfg b/test/CodeGen/X86/GC/lit.local.cfg new file mode 100644 index 0000000..a8ad0f1 --- /dev/null +++ b/test/CodeGen/X86/GC/lit.local.cfg @@ -0,0 +1,6 @@ +config.suffixes = ['.ll', '.c', '.cpp'] + +targets = set(config.root.targets_to_build.split()) +if not 'X86' in targets: + config.unsupported = True + diff --git a/test/CodeGen/X86/SwizzleShuff.ll b/test/CodeGen/X86/SwizzleShuff.ll new file mode 100644 index 0000000..100817a --- /dev/null +++ b/test/CodeGen/X86/SwizzleShuff.ll @@ -0,0 +1,68 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s + +; Check that we perform a scalar XOR on i32. + +; CHECK: pull_bitcast +; CHECK: xorl +; CHECK: ret +define void @pull_bitcast (<4 x i8>* %pA, <4 x i8>* %pB) { + %A = load <4 x i8>* %pA + %B = load <4 x i8>* %pB + %C = xor <4 x i8> %A, %B + store <4 x i8> %C, <4 x i8>* %pA + ret void +} + +; CHECK: multi_use_swizzle +; CHECK: mov +; CHECK-NEXT: shuf +; CHECK-NEXT: shuf +; CHECK-NEXT: shuf +; CHECK-NEXT: xor +; CHECK-NEXT: ret +define <4 x i32> @multi_use_swizzle (<4 x i32>* %pA, <4 x i32>* %pB) { + %A = load <4 x i32>* %pA + %B = load <4 x i32>* %pB + %S = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 1, i32 5, i32 6> + %S1 = shufflevector <4 x i32> %S, <4 x i32> undef, <4 x i32> <i32 1, i32 3, i32 2, i32 2> + %S2 = shufflevector <4 x i32> %S, <4 x i32> undef, <4 x i32> <i32 2, i32 1, i32 0, i32 2> + %R = xor <4 x i32> %S1, %S2 + ret <4 x i32> %R +} + +; CHECK: pull_bitcast2 +; CHECK: xorl +; CHECK: ret +define <4 x i8> @pull_bitcast2 (<4 x i8>* %pA, <4 x i8>* %pB, <4 x i8>* %pC) { + %A = load <4 x i8>* %pA + store <4 x i8> %A, <4 x i8>* %pC + %B = load <4 x i8>* %pB + %C = xor <4 x i8> %A, %B + store <4 x i8> %C, <4 x i8>* %pA + ret <4 x i8> %C +} + + + +; CHECK: reverse_1 +; CHECK-NOT: shuf +; CHECK: ret +define <4 x i32> @reverse_1 (<4 x i32>* %pA, <4 x i32>* %pB) { + %A = load <4 x i32>* %pA + %B = load <4 x i32>* %pB + %S = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 0, i32 3, i32 2> + %S1 = shufflevector <4 x i32> %S, <4 x i32> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2> + ret <4 x i32> %S1 +} + + +; CHECK: no_reverse_shuff +; CHECK: shuf +; CHECK: ret +define <4 x i32> @no_reverse_shuff (<4 x i32>* %pA, <4 x i32>* %pB) { + %A = load <4 x i32>* %pA + %B = load <4 x i32>* %pB + %S = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 0, i32 3, i32 2> + %S1 = shufflevector <4 x i32> %S, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 3, i32 2> + ret <4 x i32> %S1 +} diff --git a/test/CodeGen/X86/abi-isel.ll b/test/CodeGen/X86/abi-isel.ll index 5068d29..658ccaa 100644 --- a/test/CodeGen/X86/abi-isel.ll +++ b/test/CodeGen/X86/abi-isel.ll @@ -1,16 +1,16 @@ -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-unknown-linux-gnu -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-32-STATIC -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-unknown-linux-gnu -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-32-PIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=i686-unknown-linux-gnu -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-32-STATIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=i686-unknown-linux-gnu -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-32-PIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-unknown-linux-gnu -march=x86-64 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-64-STATIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-unknown-linux-gnu -march=x86-64 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=LINUX-64-PIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=x86_64-unknown-linux-gnu -march=x86-64 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=LINUX-64-STATIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=x86_64-unknown-linux-gnu -march=x86-64 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=LINUX-64-PIC -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=DARWIN-32-STATIC -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=dynamic-no-pic -code-model=small | FileCheck %s -check-prefix=DARWIN-32-DYNAMIC -; RUN: llc < %s -asm-verbose=0 -mtriple=i686-apple-darwin -march=x86 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=DARWIN-32-PIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=i686-apple-darwin -march=x86 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=DARWIN-32-STATIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=i686-apple-darwin -march=x86 -relocation-model=dynamic-no-pic -code-model=small | FileCheck %s -check-prefix=DARWIN-32-DYNAMIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=i686-apple-darwin -march=x86 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=DARWIN-32-PIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=DARWIN-64-STATIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=dynamic-no-pic -code-model=small | FileCheck %s -check-prefix=DARWIN-64-DYNAMIC -; RUN: llc < %s -asm-verbose=0 -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=DARWIN-64-PIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=static -code-model=small | FileCheck %s -check-prefix=DARWIN-64-STATIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=dynamic-no-pic -code-model=small | FileCheck %s -check-prefix=DARWIN-64-DYNAMIC +; RUN: llc < %s -asm-verbose=0 -mcpu=generic -mtriple=x86_64-apple-darwin -march=x86-64 -relocation-model=pic -code-model=small | FileCheck %s -check-prefix=DARWIN-64-PIC @src = external global [131072 x i32] @dst = external global [131072 x i32] diff --git a/test/CodeGen/X86/add.ll b/test/CodeGen/X86/add.ll index 7bf527a..8e871f4 100644 --- a/test/CodeGen/X86/add.ll +++ b/test/CodeGen/X86/add.ll @@ -1,6 +1,6 @@ -; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32 -; RUN: llc < %s -mtriple=x86_64-linux -join-physregs | FileCheck %s -check-prefix=X64 -; RUN: llc < %s -mtriple=x86_64-win32 -join-physregs | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -mcpu=generic -march=x86 | FileCheck %s -check-prefix=X32 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -join-physregs | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-win32 -join-physregs | FileCheck %s -check-prefix=X64 ; Some of these tests depend on -join-physregs to commute instructions. diff --git a/test/CodeGen/X86/apm.ll b/test/CodeGen/X86/apm.ll index b514cf6..aaedf18 100644 --- a/test/CodeGen/X86/apm.ll +++ b/test/CodeGen/X86/apm.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s -check-prefix=WIN64 +; RUN: llc < %s -mtriple=x86_64-linux -mattr=+sse3 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 -mattr=+sse3 | FileCheck %s -check-prefix=WIN64 ; PR8573 ; CHECK: foo: diff --git a/test/CodeGen/X86/atom-lea-sp.ll b/test/CodeGen/X86/atom-lea-sp.ll new file mode 100644 index 0000000..5942788 --- /dev/null +++ b/test/CodeGen/X86/atom-lea-sp.ll @@ -0,0 +1,48 @@ +; RUN: llc < %s -mcpu=atom -mtriple=i686-linux | FileCheck -check-prefix=atom %s +; RUN: llc < %s -mcpu=core2 -mtriple=i686-linux | FileCheck %s + +declare void @use_arr(i8*) +declare void @many_params(i32, i32, i32, i32, i32, i32) + +define void @test1() nounwind { +; atom: test1: +; atom: leal -1052(%esp), %esp +; atom-NOT: sub +; atom: call +; atom: leal 1052(%esp), %esp + +; CHECK: test1: +; CHECK: subl +; CHECK: call +; CHECK-NOT: lea + %arr = alloca [1024 x i8], align 16 + %arr_ptr = getelementptr inbounds [1024 x i8]* %arr, i8 0, i8 0 + call void @use_arr(i8* %arr_ptr) + ret void +} + +define void @test2() nounwind { +; atom: test2: +; atom: leal -28(%esp), %esp +; atom: call +; atom: leal 28(%esp), %esp + +; CHECK: test2: +; CHECK-NOT: lea + call void @many_params(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6) + ret void +} + +define void @test3() nounwind { +; atom: test3: +; atom: leal -8(%esp), %esp +; atom: leal 8(%esp), %esp + +; CHECK: test3: +; CHECK-NOT: lea + %x = alloca i32, align 4 + %y = alloca i32, align 4 + store i32 0, i32* %x, align 4 + ret void +} + diff --git a/test/CodeGen/X86/atom-sched.ll b/test/CodeGen/X86/atom-sched.ll new file mode 100644 index 0000000..2301dfc --- /dev/null +++ b/test/CodeGen/X86/atom-sched.ll @@ -0,0 +1,28 @@ +; RUN: llc <%s -O2 -mcpu=atom -march=x86 -relocation-model=static | FileCheck -check-prefix=atom %s +; RUN: llc <%s -O2 -mcpu=core2 -march=x86 -relocation-model=static | FileCheck %s + +@a = common global i32 0, align 4 +@b = common global i32 0, align 4 +@c = common global i32 0, align 4 +@d = common global i32 0, align 4 +@e = common global i32 0, align 4 +@f = common global i32 0, align 4 + +define void @func() nounwind uwtable { +; atom: imull +; atom-NOT: movl +; atom: imull +; CHECK: imull +; CHECK: movl +; CHECK: imull +entry: + %0 = load i32* @b, align 4 + %1 = load i32* @c, align 4 + %mul = mul nsw i32 %0, %1 + store i32 %mul, i32* @a, align 4 + %2 = load i32* @e, align 4 + %3 = load i32* @f, align 4 + %mul1 = mul nsw i32 %2, %3 + store i32 %mul1, i32* @d, align 4 + ret void +} diff --git a/test/CodeGen/X86/avx-arith.ll b/test/CodeGen/X86/avx-arith.ll index 59988ca..4aa3370 100644 --- a/test/CodeGen/X86/avx-arith.ll +++ b/test/CodeGen/X86/avx-arith.ll @@ -259,3 +259,14 @@ define <4 x i64> @mul-v4i64(<4 x i64> %i, <4 x i64> %j) nounwind readnone { ret <4 x i64> %x } +declare <4 x float> @llvm.x86.sse.sqrt.ss(<4 x float>) nounwind readnone + +define <4 x float> @int_sqrt_ss() { +; CHECK: int_sqrt_ss +; CHECK: vsqrtss + %x0 = load float addrspace(1)* undef, align 8 + %x1 = insertelement <4 x float> undef, float %x0, i32 0 + %x2 = call <4 x float> @llvm.x86.sse.sqrt.ss(<4 x float> %x1) nounwind + ret <4 x float> %x2 +} + diff --git a/test/CodeGen/X86/avx-basic.ll b/test/CodeGen/X86/avx-basic.ll index 0a46b08..8ad0fa8 100644 --- a/test/CodeGen/X86/avx-basic.ll +++ b/test/CodeGen/X86/avx-basic.ll @@ -6,7 +6,7 @@ define void @zero128() nounwind ssp { entry: - ; CHECK: vpxor + ; CHECK: vxorps ; CHECK: vmovaps store <4 x float> zeroinitializer, <4 x float>* @z, align 16 ret void @@ -105,3 +105,19 @@ allocas: ret <8 x i32> %updatedret.i30.i } +;;;; Don't crash on fneg +; rdar://10566486 +; CHECK: fneg +; CHECK: vxorps +define <16 x float> @fneg(<16 x float> addrspace(1)* nocapture %out) nounwind { + %1 = fsub <16 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00> + ret <16 x float> %1 +} + +;;; Don't crash on build vector +; CHECK: @build_vec_16x16 +; CHECK: vmovd +define <16 x i16> @build_vec_16x16(i16 %a) nounwind readonly { + %res = insertelement <16 x i16> <i16 undef, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, i16 %a, i32 0 + ret <16 x i16> %res +} diff --git a/test/CodeGen/X86/avx-cast.ll b/test/CodeGen/X86/avx-cast.ll index d6d2415..32d450c 100644 --- a/test/CodeGen/X86/avx-cast.ll +++ b/test/CodeGen/X86/avx-cast.ll @@ -16,7 +16,7 @@ entry: ret <4 x double> %shuffle.i } -; CHECK: vpxor +; CHECK: vxorps ; CHECK-NEXT: vinsertf128 $0 define <4 x i64> @castC(<2 x i64> %m) nounwind uwtable readnone ssp { entry: diff --git a/test/CodeGen/X86/avx-cvt.ll b/test/CodeGen/X86/avx-cvt.ll index 6c0bd58..d0a7fe0 100644 --- a/test/CodeGen/X86/avx-cvt.ll +++ b/test/CodeGen/X86/avx-cvt.ll @@ -18,7 +18,7 @@ define <4 x double> @sitofp01(<4 x i32> %a) { ret <4 x double> %b } -; CHECK: vcvtpd2dqy %ymm +; CHECK: vcvttpd2dqy %ymm define <4 x i32> @fptosi01(<4 x double> %a) { %b = fptosi <4 x double> %a to <4 x i32> ret <4 x i32> %b diff --git a/test/CodeGen/X86/avx-fp2int.ll b/test/CodeGen/X86/avx-fp2int.ll new file mode 100755 index 0000000..a3aadde --- /dev/null +++ b/test/CodeGen/X86/avx-fp2int.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -mtriple=i386-apple-darwin10 -mcpu=corei7-avx -mattr=+avx | FileCheck %s + +;; Check that FP_TO_SINT and FP_TO_UINT generate convert with truncate + +; CHECK: test1: +; CHECK: vcvttpd2dqy +; CHECK: ret +; CHECK: test2: +; CHECK: vcvttpd2dqy +; CHECK: ret + +define <4 x i8> @test1(<4 x double> %d) { + %c = fptoui <4 x double> %d to <4 x i8> + ret <4 x i8> %c +} +define <4 x i8> @test2(<4 x double> %d) { + %c = fptosi <4 x double> %d to <4 x i8> + ret <4 x i8> %c +} diff --git a/test/CodeGen/X86/avx-intrinsics-x86.ll b/test/CodeGen/X86/avx-intrinsics-x86.ll index 5201688..b334932 100644 --- a/test/CodeGen/X86/avx-intrinsics-x86.ll +++ b/test/CodeGen/X86/avx-intrinsics-x86.ll @@ -245,34 +245,6 @@ define <2 x double> @test_x86_sse2_div_sd(<2 x double> %a0, <2 x double> %a1) { declare <2 x double> @llvm.x86.sse2.div.sd(<2 x double>, <2 x double>) nounwind readnone -define <16 x i8> @test_x86_sse2_loadu_dq(i8* %a0) { - ; CHECK: movl - ; CHECK: vmovups - %res = call <16 x i8> @llvm.x86.sse2.loadu.dq(i8* %a0) ; <<16 x i8>> [#uses=1] - ret <16 x i8> %res -} -declare <16 x i8> @llvm.x86.sse2.loadu.dq(i8*) nounwind readonly - - -define <2 x double> @test_x86_sse2_loadu_pd(i8* %a0) { - ; CHECK: movl - ; CHECK: vmovups - %res = call <2 x double> @llvm.x86.sse2.loadu.pd(i8* %a0) ; <<2 x double>> [#uses=1] - ret <2 x double> %res -} -declare <2 x double> @llvm.x86.sse2.loadu.pd(i8*) nounwind readonly - - -define void @test_x86_sse2_maskmov_dqu(<16 x i8> %a0, <16 x i8> %a1, i8* %a2) { - ; CHECK: pushl - ; CHECK: movl - ; CHECK: vmaskmovdqu - ; CHECK: popl - call void @llvm.x86.sse2.maskmov.dqu(<16 x i8> %a0, <16 x i8> %a1, i8* %a2) - ret void -} -declare void @llvm.x86.sse2.maskmov.dqu(<16 x i8>, <16 x i8>, i8*) nounwind - define <2 x double> @test_x86_sse2_max_pd(<2 x double> %a0, <2 x double> %a1) { ; CHECK: vmaxpd @@ -314,25 +286,10 @@ define i32 @test_x86_sse2_movmsk_pd(<2 x double> %a0) { declare i32 @llvm.x86.sse2.movmsk.pd(<2 x double>) nounwind readnone -define void @test_x86_sse2_movnt_dq(i8* %a0, <2 x i64> %a1) { - ; CHECK: movl - ; CHECK: vmovntdq - call void @llvm.x86.sse2.movnt.dq(i8* %a0, <2 x i64> %a1) - ret void -} -declare void @llvm.x86.sse2.movnt.dq(i8*, <2 x i64>) nounwind - - -define void @test_x86_sse2_movnt_pd(i8* %a0, <2 x double> %a1) { - ; CHECK: movl - ; CHECK: vmovntpd - call void @llvm.x86.sse2.movnt.pd(i8* %a0, <2 x double> %a1) - ret void -} -declare void @llvm.x86.sse2.movnt.pd(i8*, <2 x double>) nounwind define <2 x double> @test_x86_sse2_mul_sd(<2 x double> %a0, <2 x double> %a1) { + ; CHECK: test_x86_sse2_mul_sd ; CHECK: vmulsd %res = call <2 x double> @llvm.x86.sse2.mul.sd(<2 x double> %a0, <2 x double> %a1) ; <<2 x double>> [#uses=1] ret <2 x double> %res @@ -412,54 +369,6 @@ define <8 x i16> @test_x86_sse2_pavg_w(<8 x i16> %a0, <8 x i16> %a1) { declare <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16>, <8 x i16>) nounwind readnone -define <16 x i8> @test_x86_sse2_pcmpeq_b(<16 x i8> %a0, <16 x i8> %a1) { - ; CHECK: vpcmpeqb - %res = call <16 x i8> @llvm.x86.sse2.pcmpeq.b(<16 x i8> %a0, <16 x i8> %a1) ; <<16 x i8>> [#uses=1] - ret <16 x i8> %res -} -declare <16 x i8> @llvm.x86.sse2.pcmpeq.b(<16 x i8>, <16 x i8>) nounwind readnone - - -define <4 x i32> @test_x86_sse2_pcmpeq_d(<4 x i32> %a0, <4 x i32> %a1) { - ; CHECK: vpcmpeqd - %res = call <4 x i32> @llvm.x86.sse2.pcmpeq.d(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1] - ret <4 x i32> %res -} -declare <4 x i32> @llvm.x86.sse2.pcmpeq.d(<4 x i32>, <4 x i32>) nounwind readnone - - -define <8 x i16> @test_x86_sse2_pcmpeq_w(<8 x i16> %a0, <8 x i16> %a1) { - ; CHECK: vpcmpeqw - %res = call <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1] - ret <8 x i16> %res -} -declare <8 x i16> @llvm.x86.sse2.pcmpeq.w(<8 x i16>, <8 x i16>) nounwind readnone - - -define <16 x i8> @test_x86_sse2_pcmpgt_b(<16 x i8> %a0, <16 x i8> %a1) { - ; CHECK: vpcmpgtb - %res = call <16 x i8> @llvm.x86.sse2.pcmpgt.b(<16 x i8> %a0, <16 x i8> %a1) ; <<16 x i8>> [#uses=1] - ret <16 x i8> %res -} -declare <16 x i8> @llvm.x86.sse2.pcmpgt.b(<16 x i8>, <16 x i8>) nounwind readnone - - -define <4 x i32> @test_x86_sse2_pcmpgt_d(<4 x i32> %a0, <4 x i32> %a1) { - ; CHECK: vpcmpgtd - %res = call <4 x i32> @llvm.x86.sse2.pcmpgt.d(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1] - ret <4 x i32> %res -} -declare <4 x i32> @llvm.x86.sse2.pcmpgt.d(<4 x i32>, <4 x i32>) nounwind readnone - - -define <8 x i16> @test_x86_sse2_pcmpgt_w(<8 x i16> %a0, <8 x i16> %a1) { - ; CHECK: vpcmpgtw - %res = call <8 x i16> @llvm.x86.sse2.pcmpgt.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1] - ret <8 x i16> %res -} -declare <8 x i16> @llvm.x86.sse2.pcmpgt.w(<8 x i16>, <8 x i16>) nounwind readnone - - define <4 x i32> @test_x86_sse2_pmadd_wd(<8 x i16> %a0, <8 x i16> %a1) { ; CHECK: vpmaddwd %res = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a0, <8 x i16> %a1) ; <<4 x i32>> [#uses=1] @@ -749,6 +658,7 @@ declare <2 x double> @llvm.x86.sse2.sqrt.sd(<2 x double>) nounwind readnone define void @test_x86_sse2_storel_dq(i8* %a0, <4 x i32> %a1) { + ; CHECK: test_x86_sse2_storel_dq ; CHECK: movl ; CHECK: vmovq call void @llvm.x86.sse2.storel.dq(i8* %a0, <4 x i32> %a1) @@ -758,6 +668,7 @@ declare void @llvm.x86.sse2.storel.dq(i8*, <4 x i32>) nounwind define void @test_x86_sse2_storeu_dq(i8* %a0, <16 x i8> %a1) { + ; CHECK: test_x86_sse2_storeu_dq ; CHECK: movl ; CHECK: vmovdqu call void @llvm.x86.sse2.storeu.dq(i8* %a0, <16 x i8> %a1) @@ -767,15 +678,18 @@ declare void @llvm.x86.sse2.storeu.dq(i8*, <16 x i8>) nounwind define void @test_x86_sse2_storeu_pd(i8* %a0, <2 x double> %a1) { + ; CHECK: test_x86_sse2_storeu_pd ; CHECK: movl ; CHECK: vmovupd - call void @llvm.x86.sse2.storeu.pd(i8* %a0, <2 x double> %a1) + %a2 = fadd <2 x double> %a1, <double 0x0, double 0x4200000000000000> + call void @llvm.x86.sse2.storeu.pd(i8* %a0, <2 x double> %a2) ret void } declare void @llvm.x86.sse2.storeu.pd(i8*, <2 x double>) nounwind define <2 x double> @test_x86_sse2_sub_sd(<2 x double> %a0, <2 x double> %a1) { + ; CHECK: test_x86_sse2_sub_sd ; CHECK: vsubsd %res = call <2 x double> @llvm.x86.sse2.sub.sd(<2 x double> %a0, <2 x double> %a1) ; <<2 x double>> [#uses=1] ret <2 x double> %res @@ -955,21 +869,13 @@ define <4 x float> @test_x86_sse41_insertps(<4 x float> %a0, <4 x float> %a1) { declare <4 x float> @llvm.x86.sse41.insertps(<4 x float>, <4 x float>, i32) nounwind readnone -define <2 x i64> @test_x86_sse41_movntdqa(i8* %a0) { - ; CHECK: movl - ; CHECK: vmovntdqa - %res = call <2 x i64> @llvm.x86.sse41.movntdqa(i8* %a0) ; <<2 x i64>> [#uses=1] - ret <2 x i64> %res -} -declare <2 x i64> @llvm.x86.sse41.movntdqa(i8*) nounwind readonly - -define <16 x i8> @test_x86_sse41_mpsadbw(<16 x i8> %a0, <16 x i8> %a1) { +define <8 x i16> @test_x86_sse41_mpsadbw(<16 x i8> %a0, <16 x i8> %a1) { ; CHECK: vmpsadbw - %res = call <16 x i8> @llvm.x86.sse41.mpsadbw(<16 x i8> %a0, <16 x i8> %a1, i32 7) ; <<16 x i8>> [#uses=1] - ret <16 x i8> %res + %res = call <8 x i16> @llvm.x86.sse41.mpsadbw(<16 x i8> %a0, <16 x i8> %a1, i32 7) ; <<8 x i16>> [#uses=1] + ret <8 x i16> %res } -declare <16 x i8> @llvm.x86.sse41.mpsadbw(<16 x i8>, <16 x i8>, i32) nounwind readnone +declare <8 x i16> @llvm.x86.sse41.mpsadbw(<16 x i8>, <16 x i8>, i32) nounwind readnone define <8 x i16> @test_x86_sse41_packusdw(<4 x i32> %a0, <4 x i32> %a1) { @@ -996,14 +902,6 @@ define <8 x i16> @test_x86_sse41_pblendw(<8 x i16> %a0, <8 x i16> %a1) { declare <8 x i16> @llvm.x86.sse41.pblendw(<8 x i16>, <8 x i16>, i32) nounwind readnone -define <2 x i64> @test_x86_sse41_pcmpeqq(<2 x i64> %a0, <2 x i64> %a1) { - ; CHECK: vpcmpeqq - %res = call <2 x i64> @llvm.x86.sse41.pcmpeqq(<2 x i64> %a0, <2 x i64> %a1) ; <<2 x i64>> [#uses=1] - ret <2 x i64> %res -} -declare <2 x i64> @llvm.x86.sse41.pcmpeqq(<2 x i64>, <2 x i64>) nounwind readnone - - define <8 x i16> @test_x86_sse41_phminposuw(<8 x i16> %a0) { ; CHECK: vphminposuw %res = call <8 x i16> @llvm.x86.sse41.phminposuw(<8 x i16> %a0) ; <<8 x i16>> [#uses=1] @@ -1180,33 +1078,33 @@ define <2 x i64> @test_x86_sse41_pmuldq(<4 x i32> %a0, <4 x i32> %a1) { declare <2 x i64> @llvm.x86.sse41.pmuldq(<4 x i32>, <4 x i32>) nounwind readnone -define i32 @test_x86_sse41_ptestc(<4 x float> %a0, <4 x float> %a1) { +define i32 @test_x86_sse41_ptestc(<2 x i64> %a0, <2 x i64> %a1) { ; CHECK: vptest ; CHECK: sbbl - %res = call i32 @llvm.x86.sse41.ptestc(<4 x float> %a0, <4 x float> %a1) ; <i32> [#uses=1] + %res = call i32 @llvm.x86.sse41.ptestc(<2 x i64> %a0, <2 x i64> %a1) ; <i32> [#uses=1] ret i32 %res } -declare i32 @llvm.x86.sse41.ptestc(<4 x float>, <4 x float>) nounwind readnone +declare i32 @llvm.x86.sse41.ptestc(<2 x i64>, <2 x i64>) nounwind readnone -define i32 @test_x86_sse41_ptestnzc(<4 x float> %a0, <4 x float> %a1) { +define i32 @test_x86_sse41_ptestnzc(<2 x i64> %a0, <2 x i64> %a1) { ; CHECK: vptest ; CHECK: seta ; CHECK: movzbl - %res = call i32 @llvm.x86.sse41.ptestnzc(<4 x float> %a0, <4 x float> %a1) ; <i32> [#uses=1] + %res = call i32 @llvm.x86.sse41.ptestnzc(<2 x i64> %a0, <2 x i64> %a1) ; <i32> [#uses=1] ret i32 %res } -declare i32 @llvm.x86.sse41.ptestnzc(<4 x float>, <4 x float>) nounwind readnone +declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) nounwind readnone -define i32 @test_x86_sse41_ptestz(<4 x float> %a0, <4 x float> %a1) { +define i32 @test_x86_sse41_ptestz(<2 x i64> %a0, <2 x i64> %a1) { ; CHECK: vptest ; CHECK: sete ; CHECK: movzbl - %res = call i32 @llvm.x86.sse41.ptestz(<4 x float> %a0, <4 x float> %a1) ; <i32> [#uses=1] + %res = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %a0, <2 x i64> %a1) ; <i32> [#uses=1] ret i32 %res } -declare i32 @llvm.x86.sse41.ptestz(<4 x float>, <4 x float>) nounwind readnone +declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) nounwind readnone define <2 x double> @test_x86_sse41_round_pd(<2 x double> %a0) { @@ -1317,14 +1215,6 @@ define <16 x i8> @test_x86_sse42_pcmpestrm128(<16 x i8> %a0, <16 x i8> %a2) { declare <16 x i8> @llvm.x86.sse42.pcmpestrm128(<16 x i8>, i32, <16 x i8>, i32, i8) nounwind readnone -define <2 x i64> @test_x86_sse42_pcmpgtq(<2 x i64> %a0, <2 x i64> %a1) { - ; CHECK: vpcmpgtq - %res = call <2 x i64> @llvm.x86.sse42.pcmpgtq(<2 x i64> %a0, <2 x i64> %a1) ; <<2 x i64>> [#uses=1] - ret <2 x i64> %res -} -declare <2 x i64> @llvm.x86.sse42.pcmpgtq(<2 x i64>, <2 x i64>) nounwind readnone - - define i32 @test_x86_sse42_pcmpistri128(<16 x i8> %a0, <16 x i8> %a1) { ; CHECK: vpcmpistri ; CHECK: movl @@ -1512,14 +1402,6 @@ define void @test_x86_sse_ldmxcsr(i8* %a0) { declare void @llvm.x86.sse.ldmxcsr(i8*) nounwind -define <4 x float> @test_x86_sse_loadu_ps(i8* %a0) { - ; CHECK: movl - ; CHECK: vmovups - %res = call <4 x float> @llvm.x86.sse.loadu.ps(i8* %a0) ; <<4 x float>> [#uses=1] - ret <4 x float> %res -} -declare <4 x float> @llvm.x86.sse.loadu.ps(i8*) nounwind readonly - define <4 x float> @test_x86_sse_max_ps(<4 x float> %a0, <4 x float> %a1) { ; CHECK: vmaxps @@ -1561,14 +1443,6 @@ define i32 @test_x86_sse_movmsk_ps(<4 x float> %a0) { declare i32 @llvm.x86.sse.movmsk.ps(<4 x float>) nounwind readnone -define void @test_x86_sse_movnt_ps(i8* %a0, <4 x float> %a1) { - ; CHECK: movl - ; CHECK: vmovntps - call void @llvm.x86.sse.movnt.ps(i8* %a0, <4 x float> %a1) - ret void -} -declare void @llvm.x86.sse.movnt.ps(i8*, <4 x float>) nounwind - define <4 x float> @test_x86_sse_mul_ss(<4 x float> %a0, <4 x float> %a1) { ; CHECK: vmulss @@ -1743,12 +1617,12 @@ define <4 x i32> @test_x86_ssse3_phadd_d_128(<4 x i32> %a0, <4 x i32> %a1) { declare <4 x i32> @llvm.x86.ssse3.phadd.d.128(<4 x i32>, <4 x i32>) nounwind readnone -define <4 x i32> @test_x86_ssse3_phadd_sw_128(<4 x i32> %a0, <4 x i32> %a1) { +define <8 x i16> @test_x86_ssse3_phadd_sw_128(<8 x i16> %a0, <8 x i16> %a1) { ; CHECK: vphaddsw - %res = call <4 x i32> @llvm.x86.ssse3.phadd.sw.128(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1] - ret <4 x i32> %res + %res = call <8 x i16> @llvm.x86.ssse3.phadd.sw.128(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1] + ret <8 x i16> %res } -declare <4 x i32> @llvm.x86.ssse3.phadd.sw.128(<4 x i32>, <4 x i32>) nounwind readnone +declare <8 x i16> @llvm.x86.ssse3.phadd.sw.128(<8 x i16>, <8 x i16>) nounwind readnone define <8 x i16> @test_x86_ssse3_phadd_w_128(<8 x i16> %a0, <8 x i16> %a1) { @@ -1783,12 +1657,12 @@ define <8 x i16> @test_x86_ssse3_phsub_w_128(<8 x i16> %a0, <8 x i16> %a1) { declare <8 x i16> @llvm.x86.ssse3.phsub.w.128(<8 x i16>, <8 x i16>) nounwind readnone -define <8 x i16> @test_x86_ssse3_pmadd_ub_sw_128(<8 x i16> %a0, <8 x i16> %a1) { +define <8 x i16> @test_x86_ssse3_pmadd_ub_sw_128(<16 x i8> %a0, <16 x i8> %a1) { ; CHECK: vpmaddubsw - %res = call <8 x i16> @llvm.x86.ssse3.pmadd.ub.sw.128(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1] + %res = call <8 x i16> @llvm.x86.ssse3.pmadd.ub.sw.128(<16 x i8> %a0, <16 x i8> %a1) ; <<8 x i16>> [#uses=1] ret <8 x i16> %res } -declare <8 x i16> @llvm.x86.ssse3.pmadd.ub.sw.128(<8 x i16>, <8 x i16>) nounwind readnone +declare <8 x i16> @llvm.x86.ssse3.pmadd.ub.sw.128(<16 x i8>, <16 x i8>) nounwind readnone define <8 x i16> @test_x86_ssse3_pmul_hr_sw_128(<8 x i16> %a0, <8 x i16> %a1) { @@ -1892,6 +1766,74 @@ define <8 x float> @test_x86_avx_cmp_ps_256(<8 x float> %a0, <8 x float> %a1) { %res = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a1, i8 7) ; <<8 x float>> [#uses=1] ret <8 x float> %res } + +define <8 x float> @test_x86_avx_cmp_ps_256_pseudo_op(<8 x float> %a0, <8 x float> %a1) { + ; CHECK: vcmpeqps + %a2 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a1, i8 0) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpltps + %a3 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a2, i8 1) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpleps + %a4 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a3, i8 2) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpunordps + %a5 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a4, i8 3) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpneqps + %a6 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a5, i8 4) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnltps + %a7 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a6, i8 5) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnleps + %a8 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a7, i8 6) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpordps + %a9 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a8, i8 7) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpeq_uqps + %a10 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a9, i8 8) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpngeps + %a11 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a10, i8 9) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpngtps + %a12 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a11, i8 10) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpfalseps + %a13 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a12, i8 11) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpneq_oqps + %a14 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a13, i8 12) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpgeps + %a15 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a14, i8 13) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpgtps + %a16 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a15, i8 14) ; <<8 x float>> [#uses=1] + ; CHECK: vcmptrueps + %a17 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a16, i8 15) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpeq_osps + %a18 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a17, i8 16) ; <<8 x float>> [#uses=1] + ; CHECK: vcmplt_oqps + %a19 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a18, i8 17) ; <<8 x float>> [#uses=1] + ; CHECK: vcmple_oqps + %a20 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a19, i8 18) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpunord_sps + %a21 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a20, i8 19) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpneq_usps + %a22 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a21, i8 20) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnlt_uqps + %a23 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a22, i8 21) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnle_uqps + %a24 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a23, i8 22) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpord_sps + %a25 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a24, i8 23) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpeq_usps + %a26 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a25, i8 24) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnge_uqps + %a27 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a26, i8 25) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpngt_uqps + %a28 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a27, i8 26) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpfalse_osps + %a29 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a28, i8 27) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpneq_osps + %a30 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a29, i8 28) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpge_oqps + %a31 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a30, i8 29) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpgt_oqps + %a32 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a31, i8 30) ; <<8 x float>> [#uses=1] + ; CHECK: vcmptrue_usps + %res = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a32, i8 31) ; <<8 x float>> [#uses=1] + ret <8 x float> %res +} declare <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float>, <8 x float>, i8) nounwind readnone @@ -2007,30 +1949,6 @@ define <32 x i8> @test_x86_avx_ldu_dq_256(i8* %a0) { declare <32 x i8> @llvm.x86.avx.ldu.dq.256(i8*) nounwind readonly -define <32 x i8> @test_x86_avx_loadu_dq_256(i8* %a0) { - ; CHECK: vmovdqu - %res = call <32 x i8> @llvm.x86.avx.loadu.dq.256(i8* %a0) ; <<32 x i8>> [#uses=1] - ret <32 x i8> %res -} -declare <32 x i8> @llvm.x86.avx.loadu.dq.256(i8*) nounwind readonly - - -define <4 x double> @test_x86_avx_loadu_pd_256(i8* %a0) { - ; CHECK: vmovupd - %res = call <4 x double> @llvm.x86.avx.loadu.pd.256(i8* %a0) ; <<4 x double>> [#uses=1] - ret <4 x double> %res -} -declare <4 x double> @llvm.x86.avx.loadu.pd.256(i8*) nounwind readonly - - -define <8 x float> @test_x86_avx_loadu_ps_256(i8* %a0) { - ; CHECK: vmovups - %res = call <8 x float> @llvm.x86.avx.loadu.ps.256(i8* %a0) ; <<8 x float>> [#uses=1] - ret <8 x float> %res -} -declare <8 x float> @llvm.x86.avx.loadu.ps.256(i8*) nounwind readonly - - define <2 x double> @test_x86_avx_maskload_pd(i8* %a0, <2 x double> %a1) { ; CHECK: vmaskmovpd %res = call <2 x double> @llvm.x86.avx.maskload.pd(i8* %a0, <2 x double> %a1) ; <<2 x double>> [#uses=1] @@ -2143,29 +2061,10 @@ define i32 @test_x86_avx_movmsk_ps_256(<8 x float> %a0) { declare i32 @llvm.x86.avx.movmsk.ps.256(<8 x float>) nounwind readnone -define void @test_x86_avx_movnt_dq_256(i8* %a0, <4 x i64> %a1) { - ; CHECK: vmovntdq - call void @llvm.x86.avx.movnt.dq.256(i8* %a0, <4 x i64> %a1) - ret void -} -declare void @llvm.x86.avx.movnt.dq.256(i8*, <4 x i64>) nounwind -define void @test_x86_avx_movnt_pd_256(i8* %a0, <4 x double> %a1) { - ; CHECK: vmovntpd - call void @llvm.x86.avx.movnt.pd.256(i8* %a0, <4 x double> %a1) - ret void -} -declare void @llvm.x86.avx.movnt.pd.256(i8*, <4 x double>) nounwind -define void @test_x86_avx_movnt_ps_256(i8* %a0, <8 x float> %a1) { - ; CHECK: vmovntps - call void @llvm.x86.avx.movnt.ps.256(i8* %a0, <8 x float> %a1) - ret void -} -declare void @llvm.x86.avx.movnt.ps.256(i8*, <8 x float>) nounwind - define i32 @test_x86_avx_ptestc_256(<4 x i64> %a0, <4 x i64> %a1) { ; CHECK: vptest @@ -2245,8 +2144,11 @@ declare <8 x float> @llvm.x86.avx.sqrt.ps.256(<8 x float>) nounwind readnone define void @test_x86_avx_storeu_dq_256(i8* %a0, <32 x i8> %a1) { - ; CHECK: vmovdqu - call void @llvm.x86.avx.storeu.dq.256(i8* %a0, <32 x i8> %a1) + ; FIXME: unfortunately the execution domain fix pass changes this to vmovups and its hard to force with no 256-bit integer instructions + ; CHECK: vmovups + ; add operation forces the execution domain. + %a2 = add <32 x i8> %a1, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + call void @llvm.x86.avx.storeu.dq.256(i8* %a0, <32 x i8> %a2) ret void } declare void @llvm.x86.avx.storeu.dq.256(i8*, <32 x i8>) nounwind @@ -2254,7 +2156,9 @@ declare void @llvm.x86.avx.storeu.dq.256(i8*, <32 x i8>) nounwind define void @test_x86_avx_storeu_pd_256(i8* %a0, <4 x double> %a1) { ; CHECK: vmovupd - call void @llvm.x86.avx.storeu.pd.256(i8* %a0, <4 x double> %a1) + ; add operation forces the execution domain. + %a2 = fadd <4 x double> %a1, <double 0x0, double 0x0, double 0x0, double 0x0> + call void @llvm.x86.avx.storeu.pd.256(i8* %a0, <4 x double> %a2) ret void } declare void @llvm.x86.avx.storeu.pd.256(i8*, <4 x double>) nounwind @@ -2292,20 +2196,20 @@ define <8 x float> @test_x86_avx_vbroadcastf128_ps_256(i8* %a0) { declare <8 x float> @llvm.x86.avx.vbroadcastf128.ps.256(i8*) nounwind readonly -define <4 x float> @test_x86_avx_vbroadcastss(i8* %a0) { +define <4 x float> @test_x86_avx_vbroadcast_ss(i8* %a0) { ; CHECK: vbroadcastss - %res = call <4 x float> @llvm.x86.avx.vbroadcastss(i8* %a0) ; <<4 x float>> [#uses=1] + %res = call <4 x float> @llvm.x86.avx.vbroadcast.ss(i8* %a0) ; <<4 x float>> [#uses=1] ret <4 x float> %res } -declare <4 x float> @llvm.x86.avx.vbroadcastss(i8*) nounwind readonly +declare <4 x float> @llvm.x86.avx.vbroadcast.ss(i8*) nounwind readonly -define <8 x float> @test_x86_avx_vbroadcastss_256(i8* %a0) { +define <8 x float> @test_x86_avx_vbroadcast_ss_256(i8* %a0) { ; CHECK: vbroadcastss - %res = call <8 x float> @llvm.x86.avx.vbroadcastss.256(i8* %a0) ; <<8 x float>> [#uses=1] + %res = call <8 x float> @llvm.x86.avx.vbroadcast.ss.256(i8* %a0) ; <<8 x float>> [#uses=1] ret <8 x float> %res } -declare <8 x float> @llvm.x86.avx.vbroadcastss.256(i8*) nounwind readonly +declare <8 x float> @llvm.x86.avx.vbroadcast.ss.256(i8*) nounwind readonly define <2 x double> @test_x86_avx_vextractf128_pd_256(<4 x double> %a0) { @@ -2433,6 +2337,12 @@ define <4 x float> @test_x86_avx_vpermilvar_ps(<4 x float> %a0, <4 x i32> %a1) { %res = call <4 x float> @llvm.x86.avx.vpermilvar.ps(<4 x float> %a0, <4 x i32> %a1) ; <<4 x float>> [#uses=1] ret <4 x float> %res } +define <4 x float> @test_x86_avx_vpermilvar_ps_load(<4 x float> %a0, <4 x i32>* %a1) { + ; CHECK: vpermilps + %a2 = load <4 x i32>* %a1 + %res = call <4 x float> @llvm.x86.avx.vpermilvar.ps(<4 x float> %a0, <4 x i32> %a2) ; <<4 x float>> [#uses=1] + ret <4 x float> %res +} declare <4 x float> @llvm.x86.avx.vpermilvar.ps(<4 x float>, <4 x i32>) nounwind readnone @@ -2575,4 +2485,73 @@ define void @test_x86_avx_vzeroupper() { } declare void @llvm.x86.avx.vzeroupper() nounwind +; Make sure instructions with no AVX equivalents, but are associated with SSEX feature flags still work +; CHECK: monitor +define void @monitor(i8* %P, i32 %E, i32 %H) nounwind { +entry: + tail call void @llvm.x86.sse3.monitor(i8* %P, i32 %E, i32 %H) + ret void +} +declare void @llvm.x86.sse3.monitor(i8*, i32, i32) nounwind + +; CHECK: mwait +define void @mwait(i32 %E, i32 %H) nounwind { +entry: + tail call void @llvm.x86.sse3.mwait(i32 %E, i32 %H) + ret void +} +declare void @llvm.x86.sse3.mwait(i32, i32) nounwind + +; CHECK: sfence +define void @sfence() nounwind { +entry: + tail call void @llvm.x86.sse.sfence() + ret void +} +declare void @llvm.x86.sse.sfence() nounwind + +; CHECK: lfence +define void @lfence() nounwind { +entry: + tail call void @llvm.x86.sse2.lfence() + ret void +} +declare void @llvm.x86.sse2.lfence() nounwind + +; CHECK: mfence +define void @mfence() nounwind { +entry: + tail call void @llvm.x86.sse2.mfence() + ret void +} +declare void @llvm.x86.sse2.mfence() nounwind + +; CHECK: clflush +define void @clflush(i8* %p) nounwind { +entry: + tail call void @llvm.x86.sse2.clflush(i8* %p) + ret void +} +declare void @llvm.x86.sse2.clflush(i8*) nounwind + +; CHECK: crc32b +define i32 @crc32_32_8(i32 %a, i8 %b) nounwind { + %tmp = call i32 @llvm.x86.sse42.crc32.32.8(i32 %a, i8 %b) + ret i32 %tmp +} +declare i32 @llvm.x86.sse42.crc32.32.8(i32, i8) nounwind + +; CHECK: crc32w +define i32 @crc32_32_16(i32 %a, i16 %b) nounwind { + %tmp = call i32 @llvm.x86.sse42.crc32.32.16(i32 %a, i16 %b) + ret i32 %tmp +} +declare i32 @llvm.x86.sse42.crc32.32.16(i32, i16) nounwind + +; CHECK: crc32l +define i32 @crc32_32_32(i32 %a, i32 %b) nounwind { + %tmp = call i32 @llvm.x86.sse42.crc32.32.32(i32 %a, i32 %b) + ret i32 %tmp +} +declare i32 @llvm.x86.sse42.crc32.32.32(i32, i32) nounwind diff --git a/test/CodeGen/X86/avx-load-store.ll b/test/CodeGen/X86/avx-load-store.ll index 07a63ef..c9fc66a 100644 --- a/test/CodeGen/X86/avx-load-store.ll +++ b/test/CodeGen/X86/avx-load-store.ll @@ -25,20 +25,26 @@ declare void @dummy(<4 x double>, <8 x float>, <4 x i64>) ;; ;; The two tests below check that we must fold load + scalar_to_vector -;; + ins_subvec+ zext into only a single vmovss or vmovsd +;; + ins_subvec+ zext into only a single vmovss or vmovsd or vinsertps from memory -; CHECK: vmovss (% +; CHECK: mov00 define <8 x float> @mov00(<8 x float> %v, float * %ptr) nounwind { %val = load float* %ptr +; CHECK: vinsertps +; CHECK: vinsertf128 %i0 = insertelement <8 x float> zeroinitializer, float %val, i32 0 ret <8 x float> %i0 +; CHECK: ret } -; CHECK: vmovsd (% +; CHECK: mov01 define <4 x double> @mov01(<4 x double> %v, double * %ptr) nounwind { %val = load double* %ptr +; CHECK: vmovlpd +; CHECK: vinsertf128 %i0 = insertelement <4 x double> zeroinitializer, double %val, i32 0 ret <4 x double> %i0 +; CHECK: ret } ; CHECK: vmovaps %ymm diff --git a/test/CodeGen/X86/avx-logic.ll b/test/CodeGen/X86/avx-logic.ll index 518c09c..115cefb 100644 --- a/test/CodeGen/X86/avx-logic.ll +++ b/test/CodeGen/X86/avx-logic.ll @@ -7,7 +7,9 @@ entry: %1 = bitcast <4 x double> %y to <4 x i64> %and.i = and <4 x i64> %0, %1 %2 = bitcast <4 x i64> %and.i to <4 x double> - ret <4 x double> %2 + ; add forces execution domain + %3 = fadd <4 x double> %2, <double 0x0, double 0x0, double 0x0, double 0x0> + ret <4 x double> %3 } ; CHECK: vandpd LCP{{.*}}(%rip) @@ -16,7 +18,9 @@ entry: %0 = bitcast <4 x double> %y to <4 x i64> %and.i = and <4 x i64> %0, <i64 4616752568008179712, i64 4614838538166547251, i64 4612361558371493478, i64 4608083138725491507> %1 = bitcast <4 x i64> %and.i to <4 x double> - ret <4 x double> %1 + ; add forces execution domain + %2 = fadd <4 x double> %1, <double 0x0, double 0x0, double 0x0, double 0x0> + ret <4 x double> %2 } ; CHECK: vandps @@ -45,7 +49,9 @@ entry: %1 = bitcast <4 x double> %y to <4 x i64> %xor.i = xor <4 x i64> %0, %1 %2 = bitcast <4 x i64> %xor.i to <4 x double> - ret <4 x double> %2 + ; add forces execution domain + %3 = fadd <4 x double> %2, <double 0x0, double 0x0, double 0x0, double 0x0> + ret <4 x double> %3 } ; CHECK: vxorpd LCP{{.*}}(%rip) @@ -54,7 +60,9 @@ entry: %0 = bitcast <4 x double> %y to <4 x i64> %xor.i = xor <4 x i64> %0, <i64 4616752568008179712, i64 4614838538166547251, i64 4612361558371493478, i64 4608083138725491507> %1 = bitcast <4 x i64> %xor.i to <4 x double> - ret <4 x double> %1 + ; add forces execution domain + %2 = fadd <4 x double> %1, <double 0x0, double 0x0, double 0x0, double 0x0> + ret <4 x double> %2 } ; CHECK: vxorps @@ -83,7 +91,9 @@ entry: %1 = bitcast <4 x double> %y to <4 x i64> %or.i = or <4 x i64> %0, %1 %2 = bitcast <4 x i64> %or.i to <4 x double> - ret <4 x double> %2 + ; add forces execution domain + %3 = fadd <4 x double> %2, <double 0x0, double 0x0, double 0x0, double 0x0> + ret <4 x double> %3 } ; CHECK: vorpd LCP{{.*}}(%rip) @@ -92,7 +102,9 @@ entry: %0 = bitcast <4 x double> %y to <4 x i64> %or.i = or <4 x i64> %0, <i64 4616752568008179712, i64 4614838538166547251, i64 4612361558371493478, i64 4608083138725491507> %1 = bitcast <4 x i64> %or.i to <4 x double> - ret <4 x double> %1 + ; add forces execution domain + %2 = fadd <4 x double> %1, <double 0x0, double 0x0, double 0x0, double 0x0> + ret <4 x double> %2 } ; CHECK: vorps @@ -122,7 +134,9 @@ entry: %1 = bitcast <4 x double> %y to <4 x i64> %and.i = and <4 x i64> %1, %neg.i %2 = bitcast <4 x i64> %and.i to <4 x double> - ret <4 x double> %2 + ; add forces execution domain + %3 = fadd <4 x double> %2, <double 0x0, double 0x0, double 0x0, double 0x0> + ret <4 x double> %3 } ; CHECK: vandnpd (% @@ -134,7 +148,9 @@ entry: %1 = bitcast <4 x double> %tmp2 to <4 x i64> %and.i = and <4 x i64> %1, %neg.i %2 = bitcast <4 x i64> %and.i to <4 x double> - ret <4 x double> %2 + ; add forces execution domain + %3 = fadd <4 x double> %2, <double 0x0, double 0x0, double 0x0, double 0x0> + ret <4 x double> %3 } ; CHECK: vandnps @@ -165,7 +181,9 @@ entry: ; CHECK: vpandn %xmm define <2 x i64> @vpandn(<2 x i64> %a, <2 x i64> %b) nounwind uwtable readnone ssp { entry: - %y = xor <2 x i64> %a, <i64 -1, i64 -1> + ; Force the execution domain with an add. + %a2 = add <2 x i64> %a, <i64 1, i64 1> + %y = xor <2 x i64> %a2, <i64 -1, i64 -1> %x = and <2 x i64> %a, %y ret <2 x i64> %x } @@ -173,7 +191,9 @@ entry: ; CHECK: vpand %xmm define <2 x i64> @vpand(<2 x i64> %a, <2 x i64> %b) nounwind uwtable readnone ssp { entry: - %x = and <2 x i64> %a, %b + ; Force the execution domain with an add. + %a2 = add <2 x i64> %a, <i64 1, i64 1> + %x = and <2 x i64> %a2, %b ret <2 x i64> %x } diff --git a/test/CodeGen/X86/avx-minmax.ll b/test/CodeGen/X86/avx-minmax.ll index f36ba7b..7c58820 100644 --- a/test/CodeGen/X86/avx-minmax.ll +++ b/test/CodeGen/X86/avx-minmax.ll @@ -33,7 +33,7 @@ define <4 x float> @minps(<4 x float> %x, <4 x float> %y) { } ; UNSAFE: vmaxpd: -; UNSAFE: vmaxpd %ymm +; UNSAFE: vmaxpd {{.+}}, %ymm define <4 x double> @vmaxpd(<4 x double> %x, <4 x double> %y) { %max_is_x = fcmp oge <4 x double> %x, %y %max = select <4 x i1> %max_is_x, <4 x double> %x, <4 x double> %y @@ -41,7 +41,7 @@ define <4 x double> @vmaxpd(<4 x double> %x, <4 x double> %y) { } ; UNSAFE: vminpd: -; UNSAFE: vminpd %ymm +; UNSAFE: vminpd {{.+}}, %ymm define <4 x double> @vminpd(<4 x double> %x, <4 x double> %y) { %min_is_x = fcmp ole <4 x double> %x, %y %min = select <4 x i1> %min_is_x, <4 x double> %x, <4 x double> %y @@ -49,7 +49,7 @@ define <4 x double> @vminpd(<4 x double> %x, <4 x double> %y) { } ; UNSAFE: vmaxps: -; UNSAFE: vmaxps %ymm +; UNSAFE: vmaxps {{.+}}, %ymm define <8 x float> @vmaxps(<8 x float> %x, <8 x float> %y) { %max_is_x = fcmp oge <8 x float> %x, %y %max = select <8 x i1> %max_is_x, <8 x float> %x, <8 x float> %y @@ -57,7 +57,7 @@ define <8 x float> @vmaxps(<8 x float> %x, <8 x float> %y) { } ; UNSAFE: vminps: -; UNSAFE: vminps %ymm +; UNSAFE: vminps {{.+}}, %ymm define <8 x float> @vminps(<8 x float> %x, <8 x float> %y) { %min_is_x = fcmp ole <8 x float> %x, %y %min = select <8 x i1> %min_is_x, <8 x float> %x, <8 x float> %y diff --git a/test/CodeGen/X86/avx-sext.ll b/test/CodeGen/X86/avx-sext.ll new file mode 100755 index 0000000..3713a8c --- /dev/null +++ b/test/CodeGen/X86/avx-sext.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s + +define <8 x i32> @sext_8i16_to_8i32(<8 x i16> %A) nounwind uwtable readnone ssp { +;CHECK: sext_8i16_to_8i32 +;CHECK: vpmovsxwd + + %B = sext <8 x i16> %A to <8 x i32> + ret <8 x i32>%B +} + +define <4 x i64> @sext_4i32_to_4i64(<4 x i32> %A) nounwind uwtable readnone ssp { +;CHECK: sext_4i32_to_4i64 +;CHECK: vpmovsxdq + + %B = sext <4 x i32> %A to <4 x i64> + ret <4 x i64>%B +} diff --git a/test/CodeGen/X86/avx-shift.ll b/test/CodeGen/X86/avx-shift.ll index 3ea39a2..681747b 100644 --- a/test/CodeGen/X86/avx-shift.ll +++ b/test/CodeGen/X86/avx-shift.ll @@ -62,6 +62,45 @@ define <16 x i16> @vshift07(<16 x i16> %a) nounwind readnone { ret <16 x i16> %s } +; CHECK: vpsrlw +; CHECK: pand +; CHECK: pxor +; CHECK: psubb +; CHECK: vpsrlw +; CHECK: pand +; CHECK: pxor +; CHECK: psubb +define <32 x i8> @vshift09(<32 x i8> %a) nounwind readnone { + %s = ashr <32 x i8> %a, <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2> + ret <32 x i8> %s +} + +; CHECK: pxor +; CHECK: pcmpgtb +; CHECK: pcmpgtb +define <32 x i8> @vshift10(<32 x i8> %a) nounwind readnone { + %s = ashr <32 x i8> %a, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7> + ret <32 x i8> %s +} + +; CHECK: vpsrlw +; CHECK: pand +; CHECK: vpsrlw +; CHECK: pand +define <32 x i8> @vshift11(<32 x i8> %a) nounwind readnone { + %s = lshr <32 x i8> %a, <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2> + ret <32 x i8> %s +} + +; CHECK: vpsllw +; CHECK: pand +; CHECK: vpsllw +; CHECK: pand +define <32 x i8> @vshift12(<32 x i8> %a) nounwind readnone { + %s = shl <32 x i8> %a, <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2> + ret <32 x i8> %s +} + ;;; Support variable shifts ; CHECK: _vshift08 ; CHECK: vextractf128 $1 @@ -73,3 +112,27 @@ define <8 x i32> @vshift08(<8 x i32> %a) nounwind { ret <8 x i32> %bitop } +;;; Uses shifts for sign extension +; CHECK: _sext_v16i16 +; CHECK: vpsllw +; CHECK: vpsraw +; CHECK: vpsllw +; CHECK: vpsraw +; CHECK: vinsertf128 +define <16 x i16> @sext_v16i16(<16 x i16> %a) nounwind { + %b = trunc <16 x i16> %a to <16 x i8> + %c = sext <16 x i8> %b to <16 x i16> + ret <16 x i16> %c +} + +; CHECK: _sext_v8i32 +; CHECK: vpslld +; CHECK: vpsrad +; CHECK: vpslld +; CHECK: vpsrad +; CHECK: vinsertf128 +define <8 x i32> @sext_v8i32(<8 x i32> %a) nounwind { + %b = trunc <8 x i32> %a to <8 x i16> + %c = sext <8 x i16> %b to <8 x i32> + ret <8 x i32> %c +} diff --git a/test/CodeGen/X86/avx-shuffle-x86_32.ll b/test/CodeGen/X86/avx-shuffle-x86_32.ll new file mode 100755 index 0000000..5268ec3a --- /dev/null +++ b/test/CodeGen/X86/avx-shuffle-x86_32.ll @@ -0,0 +1,8 @@ +; RUN: llc < %s -mtriple=i686-pc-win32 -mcpu=corei7-avx -mattr=+avx | FileCheck %s + +define <4 x i64> @test1(<4 x i64> %a) nounwind { + %b = shufflevector <4 x i64> %a, <4 x i64> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7> + ret <4 x i64>%b + ; CHECK: test1: + ; CHECK: vinsertf128 + } diff --git a/test/CodeGen/X86/avx-shuffle.ll b/test/CodeGen/X86/avx-shuffle.ll index 0db334d..16c447b 100644 --- a/test/CodeGen/X86/avx-shuffle.ll +++ b/test/CodeGen/X86/avx-shuffle.ll @@ -6,5 +6,199 @@ define <4 x float> @test1(<4 x float> %a) nounwind { ret <4 x float> %b ; CHECK: test1: ; CHECK: vshufps -; CHECK: vpshufd +; CHECK: vpermilps +} + +; rdar://10538417 +define <3 x i64> @test2(<2 x i64> %v) nounwind readnone { +; CHECK: test2: +; CHECK: vinsertf128 + %1 = shufflevector <2 x i64> %v, <2 x i64> %v, <3 x i32> <i32 0, i32 1, i32 undef> + %2 = shufflevector <3 x i64> zeroinitializer, <3 x i64> %1, <3 x i32> <i32 3, i32 4, i32 2> + ret <3 x i64> %2 +; CHECK: ret +} + +define <4 x i64> @test3(<4 x i64> %a, <4 x i64> %b) nounwind { + %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 4, i32 5, i32 2, i32 undef> + ret <4 x i64> %c +; CHECK: test3: +; CHECK: vperm2f128 +; CHECK: ret +} + +define <8 x float> @test4(float %a) nounwind { + %b = insertelement <8 x float> zeroinitializer, float %a, i32 0 + ret <8 x float> %b +; CHECK: test4: +; CHECK: vinsertf128 +} + +; rdar://10594409 +define <8 x float> @test5(float* nocapture %f) nounwind uwtable readonly ssp { +entry: + %0 = bitcast float* %f to <4 x float>* + %1 = load <4 x float>* %0, align 16 +; CHECK: test5 +; CHECK: vmovaps +; CHECK-NOT: vxorps +; CHECK-NOT: vinsertf128 + %shuffle.i = shufflevector <4 x float> %1, <4 x float> <float 0.000000e+00, float undef, float undef, float undef>, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 4, i32 4, i32 4> + ret <8 x float> %shuffle.i +} + +define <4 x double> @test6(double* nocapture %d) nounwind uwtable readonly ssp { +entry: + %0 = bitcast double* %d to <2 x double>* + %1 = load <2 x double>* %0, align 16 +; CHECK: test6 +; CHECK: vmovaps +; CHECK-NOT: vxorps +; CHECK-NOT: vinsertf128 + %shuffle.i = shufflevector <2 x double> %1, <2 x double> <double 0.000000e+00, double undef>, <4 x i32> <i32 0, i32 1, i32 2, i32 2> + ret <4 x double> %shuffle.i +} + +define <16 x i16> @test7(<4 x i16> %a) nounwind { +; CHECK: test7 + %b = shufflevector <4 x i16> %a, <4 x i16> undef, <16 x i32> <i32 1, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> +; CHECK: ret + ret <16 x i16> %b +} + +; CHECK: test8 +define void @test8() { +entry: + %0 = load <16 x i64> addrspace(1)* null, align 128 + %1 = shufflevector <16 x i64> <i64 undef, i64 undef, i64 0, i64 undef, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 undef, i64 0, i64 undef, i64 undef, i64 undef, i64 undef>, <16 x i64> %0, <16 x i32> <i32 17, i32 18, i32 2, i32 undef, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 undef, i32 11, i32 undef, i32 undef, i32 undef, i32 26> + %2 = shufflevector <16 x i64> %1, <16 x i64> %0, <16 x i32> <i32 0, i32 1, i32 2, i32 30, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 undef, i32 11, i32 undef, i32 22, i32 20, i32 15> + store <16 x i64> %2, <16 x i64> addrspace(1)* undef, align 128 +; CHECK: ret + ret void +} + +; Extract a value from a shufflevector.. +define i32 @test9(<4 x i32> %a) nounwind { +; CHECK: test9 +; CHECK: vpextrd + %b = shufflevector <4 x i32> %a, <4 x i32> undef, <8 x i32> <i32 1, i32 1, i32 2, i32 2, i32 3, i32 3, i32 undef, i32 4> + %r = extractelement <8 x i32> %b, i32 2 +; CHECK: ret + ret i32 %r +} + +; Extract a value which is the result of an undef mask. +define i32 @test10(<4 x i32> %a) nounwind { +; CHECK: @test10 +; CHECK-NEXT: # +; CHECK-NEXT: ret + %b = shufflevector <4 x i32> %a, <4 x i32> undef, <8 x i32> <i32 1, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> + %r = extractelement <8 x i32> %b, i32 2 + ret i32 %r +} + +define <4 x float> @test11(<4 x float> %a) nounwind { +; check: test11 +; check: vpermilps $27 + %tmp1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> + ret <4 x float> %tmp1 +} + +define <4 x float> @test12(<4 x float>* %a) nounwind { +; CHECK: test12 +; CHECK: vpermilps $27, ( + %tmp0 = load <4 x float>* %a + %tmp1 = shufflevector <4 x float> %tmp0, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> + ret <4 x float> %tmp1 +} + +define <4 x i32> @test13(<4 x i32> %a) nounwind { +; check: test13 +; check: vpshufd $27 + %tmp1 = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> + ret <4 x i32> %tmp1 +} + +define <4 x i32> @test14(<4 x i32>* %a) nounwind { +; CHECK: test14 +; CHECK: vpshufd $27, ( + %tmp0 = load <4 x i32>* %a + %tmp1 = shufflevector <4 x i32> %tmp0, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> + ret <4 x i32> %tmp1 +} + +; CHECK: test15 +; CHECK: vpshufd $8 +; CHECK: ret +define <4 x i32> @test15(<2 x i32>%x) nounwind readnone { + %x1 = shufflevector <2 x i32> %x, <2 x i32> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> + ret <4 x i32>%x1 +} + +; rdar://10974078 +define <8 x float> @test16(float* nocapture %f) nounwind uwtable readonly ssp { +entry: + %0 = bitcast float* %f to <4 x float>* + %1 = load <4 x float>* %0, align 8 +; CHECK: test16 +; CHECK: vmovups +; CHECK-NOT: vxorps +; CHECK-NOT: vinsertf128 + %shuffle.i = shufflevector <4 x float> %1, <4 x float> <float 0.000000e+00, float undef, float undef, float undef>, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 4, i32 4, i32 4> + ret <8 x float> %shuffle.i +} + +; PR12413 +; CHECK: vpshufb +; CHECK: vpshufb +; CHECK: vpshufb +; CHECK: vpshufb +define <32 x i8> @shuf(<32 x i8> %inval1, <32 x i8> %inval2) { +entry: + %0 = shufflevector <32 x i8> %inval1, <32 x i8> %inval2, <32 x i32> <i32 0, +i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 +22, i32 24, i32 26, i32 28, i32 30, i32 32, i32 34, i32 36, i32 38, i32 40, i32 +42, i32 44, i32 46, i32 48, i32 50, i32 52, i32 54, i32 56, i32 58, i32 60, i32 +62> + ret <32 x i8> %0 +} + +; CHECK: blend1 +; CHECK: vblendps +; CHECK: ret +define <4 x i32> @blend1(<4 x i32> %a, <4 x i32> %b) nounwind alwaysinline { + %t = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> + ret <4 x i32> %t +} + +; CHECK: blend2 +; CHECK: vblendps +; CHECK: ret +define <4 x i32> @blend2(<4 x i32> %a, <4 x i32> %b) nounwind alwaysinline { + %t = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> + ret <4 x i32> %t +} + +; CHECK: blend2a +; CHECK: vblendps +; CHECK: ret +define <4 x float> @blend2a(<4 x float> %a, <4 x float> %b) nounwind alwaysinline { + %t = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> + ret <4 x float> %t +} + +; CHECK: blend3 +; CHECK-NOT: vblendps +; CHECK: ret +define <4 x i32> @blend3(<4 x i32> %a, <4 x i32> %b) nounwind alwaysinline { + %t = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 1, i32 5, i32 2, i32 7> + ret <4 x i32> %t +} + +; CHECK: blend4 +; CHECK: vblendpd +; CHECK: ret +define <4 x i64> @blend4(<4 x i64> %a, <4 x i64> %b) nounwind alwaysinline { + %t = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 7> + ret <4 x i64> %t } diff --git a/test/CodeGen/X86/avx-splat.ll b/test/CodeGen/X86/avx-splat.ll index af20b90..94bcddd 100644 --- a/test/CodeGen/X86/avx-splat.ll +++ b/test/CodeGen/X86/avx-splat.ll @@ -32,7 +32,7 @@ entry: ret <4 x i64> %vecinit6.i } -; CHECK: vshufpd $0 +; CHECK: vpermilpd $0 ; CHECK-NEXT: vinsertf128 $1 define <4 x double> @funcD(double %q) nounwind uwtable readnone ssp { entry: @@ -47,7 +47,7 @@ entry: ; shuffle (scalar_to_vector (load (ptr + 4))), undef, <0, 0, 0, 0> ; To: ; shuffle (vload ptr)), undef, <1, 1, 1, 1> -; CHECK: vmovdqa +; CHECK: vmovaps ; CHECK-NEXT: vinsertf128 $1 ; CHECK-NEXT: vpermilps $-1 define <8 x float> @funcE() nounwind { diff --git a/test/CodeGen/X86/avx-trunc.ll b/test/CodeGen/X86/avx-trunc.ll new file mode 100755 index 0000000..d007736 --- /dev/null +++ b/test/CodeGen/X86/avx-trunc.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s + +define <4 x i32> @trunc_64_32(<4 x i64> %A) nounwind uwtable readnone ssp{ +; CHECK: trunc_64_32 +; CHECK: pshufd + %B = trunc <4 x i64> %A to <4 x i32> + ret <4 x i32>%B +} +define <8 x i16> @trunc_32_16(<8 x i32> %A) nounwind uwtable readnone ssp{ +; CHECK: trunc_32_16 +; CHECK: pshufb + %B = trunc <8 x i32> %A to <8 x i16> + ret <8 x i16>%B +} + diff --git a/test/CodeGen/X86/avx-unpack.ll b/test/CodeGen/X86/avx-unpack.ll index d420101..20f5345 100644 --- a/test/CodeGen/X86/avx-unpack.ll +++ b/test/CodeGen/X86/avx-unpack.ll @@ -67,6 +67,15 @@ entry: ret <8 x i32> %shuffle.i } +; CHECK: vunpckhps (% +define <8 x i32> @unpackhips2(<8 x i32>* %src1, <8 x i32>* %src2) nounwind uwtable readnone ssp { +entry: + %a = load <8 x i32>* %src1 + %b = load <8 x i32>* %src2 + %shuffle.i = shufflevector <8 x i32> %a, <8 x i32> %b, <8 x i32> <i32 2, i32 10, i32 3, i32 11, i32 6, i32 14, i32 7, i32 15> + ret <8 x i32> %shuffle.i +} + ; CHECK: vunpckhpd define <4 x i64> @unpackhipd1(<4 x i64> %src1, <4 x i64> %src2) nounwind uwtable readnone ssp { entry: @@ -74,6 +83,15 @@ entry: ret <4 x i64> %shuffle.i } +; CHECK: vunpckhpd (% +define <4 x i64> @unpackhipd2(<4 x i64>* %src1, <4 x i64>* %src2) nounwind uwtable readnone ssp { +entry: + %a = load <4 x i64>* %src1 + %b = load <4 x i64>* %src2 + %shuffle.i = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 1, i32 5, i32 3, i32 7> + ret <4 x i64> %shuffle.i +} + ; CHECK: vunpcklps define <8 x i32> @unpacklops1(<8 x i32> %src1, <8 x i32> %src2) nounwind uwtable readnone ssp { entry: @@ -81,9 +99,63 @@ entry: ret <8 x i32> %shuffle.i } +; CHECK: vunpcklps (% +define <8 x i32> @unpacklops2(<8 x i32>* %src1, <8 x i32>* %src2) nounwind uwtable readnone ssp { +entry: + %a = load <8 x i32>* %src1 + %b = load <8 x i32>* %src2 + %shuffle.i = shufflevector <8 x i32> %a, <8 x i32> %b, <8 x i32> <i32 0, i32 8, i32 1, i32 9, i32 4, i32 12, i32 5, i32 13> + ret <8 x i32> %shuffle.i +} + ; CHECK: vunpcklpd define <4 x i64> @unpacklopd1(<4 x i64> %src1, <4 x i64> %src2) nounwind uwtable readnone ssp { entry: %shuffle.i = shufflevector <4 x i64> %src1, <4 x i64> %src2, <4 x i32> <i32 0, i32 4, i32 2, i32 6> ret <4 x i64> %shuffle.i } + +; CHECK: vunpcklpd (% +define <4 x i64> @unpacklopd2(<4 x i64>* %src1, <4 x i64>* %src2) nounwind uwtable readnone ssp { +entry: + %a = load <4 x i64>* %src1 + %b = load <4 x i64>* %src2 + %shuffle.i = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 0, i32 4, i32 2, i32 6> + ret <4 x i64> %shuffle.i +} + +; CHECK: vpunpckhwd +; CHECK: vpunpckhwd +; CHECK: vinsertf128 +define <16 x i16> @unpackhwd_undef(<16 x i16> %src1) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <16 x i16> %src1, <16 x i16> %src1, <16 x i32> <i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23, i32 12, i32 28, i32 13, i32 29, i32 14, i32 30, i32 15, i32 31> + ret <16 x i16> %shuffle.i +} + +; CHECK: vpunpcklwd +; CHECK: vpunpcklwd +; CHECK: vinsertf128 +define <16 x i16> @unpacklwd_undef(<16 x i16> %src1) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <16 x i16> %src1, <16 x i16> %src1, <16 x i32> <i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 8, i32 24, i32 9, i32 25, i32 10, i32 26, i32 11, i32 27> + ret <16 x i16> %shuffle.i +} + +; CHECK: vpunpckhbw +; CHECK: vpunpckhbw +; CHECK: vinsertf128 +define <32 x i8> @unpackhbw_undef(<32 x i8> %src1, <32 x i8> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <32 x i8> %src1, <32 x i8> %src1, <32 x i32> <i32 8, i32 40, i32 9, i32 41, i32 10, i32 42, i32 11, i32 43, i32 12, i32 44, i32 13, i32 45, i32 14, i32 46, i32 15, i32 47, i32 24, i32 56, i32 25, i32 57, i32 26, i32 58, i32 27, i32 59, i32 28, i32 60, i32 29, i32 61, i32 30, i32 62, i32 31, i32 63> + ret <32 x i8> %shuffle.i +} + +; CHECK: vpunpcklbw +; CHECK: vpunpcklbw +; CHECK: vinsertf128 +define <32 x i8> @unpacklbw_undef(<32 x i8> %src1) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <32 x i8> %src1, <32 x i8> %src1, <32 x i32> <i32 0, i32 32, i32 1, i32 33, i32 2, i32 34, i32 3, i32 35, i32 4, i32 36, i32 5, i32 37, i32 6, i32 38, i32 7, i32 39, i32 16, i32 48, i32 17, i32 49, i32 18, i32 50, i32 19, i32 51, i32 20, i32 52, i32 21, i32 53, i32 22, i32 54, i32 23, i32 55> + ret <32 x i8> %shuffle.i +} diff --git a/test/CodeGen/X86/avx-varargs-x86_64.ll b/test/CodeGen/X86/avx-varargs-x86_64.ll new file mode 100644 index 0000000..b0932bd --- /dev/null +++ b/test/CodeGen/X86/avx-varargs-x86_64.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s +; <rdar://problem/10463281> +; Check that the <8 x float> is passed on the stack. + +@x = common global <8 x float> zeroinitializer, align 32 +declare i32 @f(i32, ...) + +; CHECK: test1: +; CHECK: vmovaps %ymm0, (%rsp) +define void @test1() nounwind uwtable ssp { +entry: + %0 = load <8 x float>* @x, align 32 + %call = call i32 (i32, ...)* @f(i32 1, <8 x float> %0) + ret void +} diff --git a/test/CodeGen/X86/avx-vbroadcast.ll b/test/CodeGen/X86/avx-vbroadcast.ll index 89b4188..148ae73 100644 --- a/test/CodeGen/X86/avx-vbroadcast.ll +++ b/test/CodeGen/X86/avx-vbroadcast.ll @@ -1,7 +1,4 @@ ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s -; XFAIL: * - -; xfail this file for now because of PR8156, when it gets solved merge this with avx-splat.ll ; CHECK: vbroadcastsd (% define <4 x i64> @A(i64* %ptr) nounwind uwtable readnone ssp { @@ -50,7 +47,7 @@ entry: ;;;; 128-bit versions ; CHECK: vbroadcastss (% -define <4 x float> @E(float* %ptr) nounwind uwtable readnone ssp { +define <4 x float> @e(float* %ptr) nounwind uwtable readnone ssp { entry: %q = load float* %ptr, align 4 %vecinit.i = insertelement <4 x float> undef, float %q, i32 0 @@ -60,6 +57,19 @@ entry: ret <4 x float> %vecinit6.i } + +; CHECK: _e2 +; CHECK-NOT: vbroadcastss +; CHECK: ret +define <4 x float> @_e2(float* %ptr) nounwind uwtable readnone ssp { + %vecinit.i = insertelement <4 x float> undef, float 0xbf80000000000000, i32 0 + %vecinit2.i = insertelement <4 x float> %vecinit.i, float 0xbf80000000000000, i32 1 + %vecinit4.i = insertelement <4 x float> %vecinit2.i, float 0xbf80000000000000, i32 2 + %vecinit6.i = insertelement <4 x float> %vecinit4.i, float 0xbf80000000000000, i32 3 + ret <4 x float> %vecinit6.i +} + + ; CHECK: vbroadcastss (% define <4 x i32> @F(i32* %ptr) nounwind uwtable readnone ssp { entry: @@ -74,7 +84,7 @@ entry: ; Unsupported vbroadcasts ; CHECK: _G -; CHECK-NOT: vbroadcastsd (% +; CHECK-NOT: broadcast (% ; CHECK: ret define <2 x i64> @G(i64* %ptr) nounwind uwtable readnone ssp { entry: @@ -85,10 +95,20 @@ entry: } ; CHECK: _H -; CHECK-NOT: vbroadcastss +; CHECK-NOT: broadcast ; CHECK: ret define <4 x i32> @H(<4 x i32> %a) { %x = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> ret <4 x i32> %x } +; CHECK: _I +; CHECK-NOT: broadcast (% +; CHECK: ret +define <2 x double> @I(double* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load double* %ptr, align 4 + %vecinit.i = insertelement <2 x double> undef, double %q, i32 0 + %vecinit2.i = insertelement <2 x double> %vecinit.i, double %q, i32 1 + ret <2 x double> %vecinit2.i +} diff --git a/test/CodeGen/X86/avx-vextractf128.ll b/test/CodeGen/X86/avx-vextractf128.ll index dccf901..fe0f6ca 100644 --- a/test/CodeGen/X86/avx-vextractf128.ll +++ b/test/CodeGen/X86/avx-vextractf128.ll @@ -1,5 +1,6 @@ ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s +; CHECK: @A ; CHECK-NOT: vunpck ; CHECK: vextractf128 $1 define <8 x float> @A(<8 x float> %a) nounwind uwtable readnone ssp { @@ -8,6 +9,7 @@ entry: ret <8 x float> %shuffle } +; CHECK: @B ; CHECK-NOT: vunpck ; CHECK: vextractf128 $1 define <4 x double> @B(<4 x double> %a) nounwind uwtable readnone ssp { @@ -16,3 +18,89 @@ entry: ret <4 x double> %shuffle } +; CHECK: @t0 +; CHECK-NOT: vextractf128 $0, %ymm0, %xmm0 +; CHECK-NOT: vmovaps %xmm0, (%rdi) +; CHECK: vextractf128 $0, %ymm0, (%rdi) +define void @t0(float* nocapture %addr, <8 x float> %a) nounwind uwtable ssp { +entry: + %0 = tail call <4 x float> @llvm.x86.avx.vextractf128.ps.256(<8 x float> %a, i8 0) + %1 = bitcast float* %addr to <4 x float>* + store <4 x float> %0, <4 x float>* %1, align 16 + ret void +} + +declare <4 x float> @llvm.x86.avx.vextractf128.ps.256(<8 x float>, i8) nounwind readnone + +; CHECK: @t1 +; CHECK-NOT: vextractf128 $0, %ymm0, %xmm0 +; CHECK-NOT: vmovups %xmm0, (%rdi) +; CHECK: vextractf128 $0, %ymm0, (%rdi) +define void @t1(float* %addr, <8 x float> %a) nounwind uwtable ssp { +entry: + %0 = tail call <4 x float> @llvm.x86.avx.vextractf128.ps.256(<8 x float> %a, i8 0) + %1 = bitcast float* %addr to i8* + tail call void @llvm.x86.sse.storeu.ps(i8* %1, <4 x float> %0) + ret void +} + +declare void @llvm.x86.sse.storeu.ps(i8*, <4 x float>) nounwind + +; CHECK: @t2 +; CHECK-NOT: vextractf128 $0, %ymm0, %xmm0 +; CHECK-NOT: vmovaps %xmm0, (%rdi) +; CHECK: vextractf128 $0, %ymm0, (%rdi) +define void @t2(double* nocapture %addr, <4 x double> %a) nounwind uwtable ssp { +entry: + %0 = tail call <2 x double> @llvm.x86.avx.vextractf128.pd.256(<4 x double> %a, i8 0) + %1 = bitcast double* %addr to <2 x double>* + store <2 x double> %0, <2 x double>* %1, align 16 + ret void +} + +declare <2 x double> @llvm.x86.avx.vextractf128.pd.256(<4 x double>, i8) nounwind readnone + +; CHECK: @t3 +; CHECK-NOT: vextractf128 $0, %ymm0, %xmm0 +; CHECK-NOT: vmovups %xmm0, (%rdi) +; CHECK: vextractf128 $0, %ymm0, (%rdi) +define void @t3(double* %addr, <4 x double> %a) nounwind uwtable ssp { +entry: + %0 = tail call <2 x double> @llvm.x86.avx.vextractf128.pd.256(<4 x double> %a, i8 0) + %1 = bitcast double* %addr to i8* + tail call void @llvm.x86.sse2.storeu.pd(i8* %1, <2 x double> %0) + ret void +} + +declare void @llvm.x86.sse2.storeu.pd(i8*, <2 x double>) nounwind + +; CHECK: @t4 +; CHECK-NOT: vextractf128 $0, %ymm0, %xmm0 +; CHECK-NOT: vmovaps %xmm0, (%rdi) +; CHECK: vextractf128 $0, %ymm0, (%rdi) +define void @t4(<2 x i64>* nocapture %addr, <4 x i64> %a) nounwind uwtable ssp { +entry: + %0 = bitcast <4 x i64> %a to <8 x i32> + %1 = tail call <4 x i32> @llvm.x86.avx.vextractf128.si.256(<8 x i32> %0, i8 0) + %2 = bitcast <4 x i32> %1 to <2 x i64> + store <2 x i64> %2, <2 x i64>* %addr, align 16 + ret void +} + +declare <4 x i32> @llvm.x86.avx.vextractf128.si.256(<8 x i32>, i8) nounwind readnone + +; CHECK: @t5 +; CHECK-NOT: vextractf128 $0, %ymm0, %xmm0 +; CHECK-NOT: vmovdqu %xmm0, (%rdi) +; CHECK: vextractf128 $0, %ymm0, (%rdi) +define void @t5(<2 x i64>* %addr, <4 x i64> %a) nounwind uwtable ssp { +entry: + %0 = bitcast <4 x i64> %a to <8 x i32> + %1 = tail call <4 x i32> @llvm.x86.avx.vextractf128.si.256(<8 x i32> %0, i8 0) + %2 = bitcast <2 x i64>* %addr to i8* + %3 = bitcast <4 x i32> %1 to <16 x i8> + tail call void @llvm.x86.sse2.storeu.dq(i8* %2, <16 x i8> %3) + ret void +} + +declare void @llvm.x86.sse2.storeu.dq(i8*, <16 x i8>) nounwind diff --git a/test/CodeGen/X86/avx-vinsertf128.ll b/test/CodeGen/X86/avx-vinsertf128.ll index cda1331..9a954fe 100644 --- a/test/CodeGen/X86/avx-vinsertf128.ll +++ b/test/CodeGen/X86/avx-vinsertf128.ll @@ -56,3 +56,76 @@ define <8 x i32> @DAGCombineB(<8 x i32> %v1, <8 x i32> %v2) nounwind readonly { %2 = add <8 x i32> %1, %v1 ret <8 x i32> %2 } + +; CHECK: insert_pd +define <4 x double> @insert_pd(<4 x double> %a0, <2 x double> %a1) { +; CHECK: vinsertf128 +%res = call <4 x double> @llvm.x86.avx.vinsertf128.pd.256(<4 x double> %a0, <2 x double> %a1, i8 0) +ret <4 x double> %res +} + +; CHECK: insert_undef_pd +define <4 x double> @insert_undef_pd(<4 x double> %a0, <2 x double> %a1) { +; CHECK: vmovaps %ymm1, %ymm0 +%res = call <4 x double> @llvm.x86.avx.vinsertf128.pd.256(<4 x double> undef, <2 x double> %a1, i8 0) +ret <4 x double> %res +} +declare <4 x double> @llvm.x86.avx.vinsertf128.pd.256(<4 x double>, <2 x double>, i8) nounwind readnone + + +; CHECK: insert_ps +define <8 x float> @insert_ps(<8 x float> %a0, <4 x float> %a1) { +; CHECK: vinsertf128 +%res = call <8 x float> @llvm.x86.avx.vinsertf128.ps.256(<8 x float> %a0, <4 x float> %a1, i8 0) +ret <8 x float> %res +} + +; CHECK: insert_undef_ps +define <8 x float> @insert_undef_ps(<8 x float> %a0, <4 x float> %a1) { +; CHECK: vmovaps %ymm1, %ymm0 +%res = call <8 x float> @llvm.x86.avx.vinsertf128.ps.256(<8 x float> undef, <4 x float> %a1, i8 0) +ret <8 x float> %res +} +declare <8 x float> @llvm.x86.avx.vinsertf128.ps.256(<8 x float>, <4 x float>, i8) nounwind readnone + + +; CHECK: insert_si +define <8 x i32> @insert_si(<8 x i32> %a0, <4 x i32> %a1) { +; CHECK: vinsertf128 +%res = call <8 x i32> @llvm.x86.avx.vinsertf128.si.256(<8 x i32> %a0, <4 x i32> %a1, i8 0) +ret <8 x i32> %res +} + +; CHECK: insert_undef_si +define <8 x i32> @insert_undef_si(<8 x i32> %a0, <4 x i32> %a1) { +; CHECK: vmovaps %ymm1, %ymm0 +%res = call <8 x i32> @llvm.x86.avx.vinsertf128.si.256(<8 x i32> undef, <4 x i32> %a1, i8 0) +ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx.vinsertf128.si.256(<8 x i32>, <4 x i32>, i8) nounwind readnone + +; rdar://10643481 +; CHECK: vinsertf128_combine +define <8 x float> @vinsertf128_combine(float* nocapture %f) nounwind uwtable readonly ssp { +; CHECK-NOT: vmovaps +; CHECK: vinsertf128 +entry: + %add.ptr = getelementptr inbounds float* %f, i64 4 + %0 = bitcast float* %add.ptr to <4 x float>* + %1 = load <4 x float>* %0, align 16 + %2 = tail call <8 x float> @llvm.x86.avx.vinsertf128.ps.256(<8 x float> undef, <4 x float> %1, i8 1) + ret <8 x float> %2 +} + +; rdar://11076953 +; CHECK: vinsertf128_ucombine +define <8 x float> @vinsertf128_ucombine(float* nocapture %f) nounwind uwtable readonly ssp { +; CHECK-NOT: vmovups +; CHECK: vinsertf128 +entry: + %add.ptr = getelementptr inbounds float* %f, i64 4 + %0 = bitcast float* %add.ptr to <4 x float>* + %1 = load <4 x float>* %0, align 8 + %2 = tail call <8 x float> @llvm.x86.avx.vinsertf128.ps.256(<8 x float> undef, <4 x float> %1, i8 1) + ret <8 x float> %2 +} diff --git a/test/CodeGen/X86/avx-vperm2f128.ll b/test/CodeGen/X86/avx-vperm2f128.ll index 3550a90..caa21e5 100644 --- a/test/CodeGen/X86/avx-vperm2f128.ll +++ b/test/CodeGen/X86/avx-vperm2f128.ll @@ -1,5 +1,6 @@ ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s +; CHECK: _A ; CHECK: vperm2f128 $1 define <8 x float> @A(<8 x float> %a, <8 x float> %b) nounwind uwtable readnone ssp { entry: @@ -7,6 +8,7 @@ entry: ret <8 x float> %shuffle } +; CHECK: _B ; CHECK: vperm2f128 $48 define <8 x float> @B(<8 x float> %a, <8 x float> %b) nounwind uwtable readnone ssp { entry: @@ -14,6 +16,7 @@ entry: ret <8 x float> %shuffle } +; CHECK: _C ; CHECK: vperm2f128 $0 define <8 x float> @C(<8 x float> %a, <8 x float> %b) nounwind uwtable readnone ssp { entry: @@ -21,6 +24,7 @@ entry: ret <8 x float> %shuffle } +; CHECK: _D ; CHECK: vperm2f128 $17 define <8 x float> @D(<8 x float> %a, <8 x float> %b) nounwind uwtable readnone ssp { entry: @@ -28,6 +32,7 @@ entry: ret <8 x float> %shuffle } +; CHECK: _E ; CHECK: vperm2f128 $17 define <32 x i8> @E(<32 x i8> %a, <32 x i8> %b) nounwind uwtable readnone ssp { entry: @@ -35,7 +40,8 @@ entry: ret <32 x i8> %shuffle } -; CHECK: vperm2f128 $33 +; CHECK: _E2 +; CHECK: vperm2f128 $3 define <4 x i64> @E2(<4 x i64> %a, <4 x i64> %b) nounwind uwtable readnone ssp { entry: %shuffle = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> @@ -44,6 +50,7 @@ entry: ;;;; Cases with undef indicies mixed in the mask +; CHECK: _F ; CHECK: vperm2f128 $33 define <8 x float> @F(<8 x float> %a, <8 x float> %b) nounwind uwtable readnone ssp { entry: diff --git a/test/CodeGen/X86/avx-vpermil.ll b/test/CodeGen/X86/avx-vpermil.ll index 49b2f54..cb904b9 100644 --- a/test/CodeGen/X86/avx-vpermil.ll +++ b/test/CodeGen/X86/avx-vpermil.ll @@ -28,6 +28,14 @@ entry: ret <4 x i64> %shuffle } +; CHECK: vpermilpd +define <4 x i64> @funcQ(<4 x i64>* %a) nounwind uwtable readnone ssp { +entry: + %a2 = load <4 x i64>* %a + %shuffle = shufflevector <4 x i64> %a2, <4 x i64> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 3> + ret <4 x i64> %shuffle +} + ; vpermil should match masks like this: <u,3,1,2,4,u,5,6>. Check that the ; target specific mask was correctly generated. ; CHECK: vpermilps $-100 @@ -37,7 +45,8 @@ entry: ret <8 x float> %shuffle } -; CHECK-NOT: vpermilps +; CHECK: palignr +; CHECK: palignr define <8 x float> @funcF(<8 x float> %a) nounwind uwtable readnone ssp { entry: %shuffle = shufflevector <8 x float> %a, <8 x float> zeroinitializer, <8 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9> diff --git a/test/CodeGen/X86/avx-vshufp.ll b/test/CodeGen/X86/avx-vshufp.ll index f06548d..45883b7 100644 --- a/test/CodeGen/X86/avx-vshufp.ll +++ b/test/CodeGen/X86/avx-vshufp.ll @@ -7,6 +7,31 @@ entry: ret <8 x float> %shuffle } +; CHECK: vshufps $-53, (%{{.*}}), %ymm +define <8 x float> @A2(<8 x float>* %a, <8 x float>* %b) nounwind uwtable readnone ssp { +entry: + %a2 = load <8 x float>* %a + %b2 = load <8 x float>* %b + %shuffle = shufflevector <8 x float> %a2, <8 x float> %b2, <8 x i32> <i32 3, i32 2, i32 8, i32 11, i32 7, i32 6, i32 12, i32 15> + ret <8 x float> %shuffle +} + +; CHECK: vshufps $-53, %ymm +define <8 x i32> @A3(<8 x i32> %a, <8 x i32> %b) nounwind uwtable readnone ssp { +entry: + %shuffle = shufflevector <8 x i32> %a, <8 x i32> %b, <8 x i32> <i32 3, i32 2, i32 8, i32 11, i32 7, i32 6, i32 12, i32 15> + ret <8 x i32> %shuffle +} + +; CHECK: vshufps $-53, (%{{.*}}), %ymm +define <8 x i32> @A4(<8 x i32>* %a, <8 x i32>* %b) nounwind uwtable readnone ssp { +entry: + %a2 = load <8 x i32>* %a + %b2 = load <8 x i32>* %b + %shuffle = shufflevector <8 x i32> %a2, <8 x i32> %b2, <8 x i32> <i32 3, i32 2, i32 8, i32 11, i32 7, i32 6, i32 12, i32 15> + ret <8 x i32> %shuffle +} + ; CHECK: vshufpd $10, %ymm define <4 x double> @B(<4 x double> %a, <4 x double> %b) nounwind uwtable readnone ssp { entry: @@ -14,6 +39,31 @@ entry: ret <4 x double> %shuffle } +; CHECK: vshufpd $10, (%{{.*}}), %ymm +define <4 x double> @B2(<4 x double>* %a, <4 x double>* %b) nounwind uwtable readnone ssp { +entry: + %a2 = load <4 x double>* %a + %b2 = load <4 x double>* %b + %shuffle = shufflevector <4 x double> %a2, <4 x double> %b2, <4 x i32> <i32 0, i32 5, i32 2, i32 7> + ret <4 x double> %shuffle +} + +; CHECK: vshufpd $10, %ymm +define <4 x i64> @B3(<4 x i64> %a, <4 x i64> %b) nounwind uwtable readnone ssp { +entry: + %shuffle = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 7> + ret <4 x i64> %shuffle +} + +; CHECK: vshufpd $10, (%{{.*}}), %ymm +define <4 x i64> @B4(<4 x i64>* %a, <4 x i64>* %b) nounwind uwtable readnone ssp { +entry: + %a2 = load <4 x i64>* %a + %b2 = load <4 x i64>* %b + %shuffle = shufflevector <4 x i64> %a2, <4 x i64> %b2, <4 x i32> <i32 0, i32 5, i32 2, i32 7> + ret <4 x i64> %shuffle +} + ; CHECK: vshufps $-53, %ymm define <8 x float> @C(<8 x float> %a, <8 x float> %b) nounwind uwtable readnone ssp { entry: @@ -27,3 +77,81 @@ entry: %shuffle = shufflevector <4 x double> %a, <4 x double> %b, <4 x i32> <i32 0, i32 5, i32 2, i32 undef> ret <4 x double> %shuffle } + +; CHECK: vshufps $-55, %ymm +define <8 x float> @E(<8 x float> %a, <8 x float> %b) nounwind uwtable readnone ssp { +entry: + %shuffle = shufflevector <8 x float> %a, <8 x float> %b, <8 x i32> <i32 9, i32 10, i32 0, i32 3, i32 13, i32 14, i32 4, i32 7> + ret <8 x float> %shuffle +} + +; CHECK: vshufpd $8, %ymm +define <4 x double> @F(<4 x double> %a, <4 x double> %b) nounwind uwtable readnone ssp { +entry: + %shuffle = shufflevector <4 x double> %a, <4 x double> %b, <4 x i32> <i32 0, i32 4, i32 2, i32 7> + ret <4 x double> %shuffle +} + +; CHECK: vshufps $-53, %xmm +define <4 x float> @A128(<4 x float> %a, <4 x float> %b) nounwind uwtable readnone ssp { +entry: + %shuffle = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 3, i32 2, i32 4, i32 7> + ret <4 x float> %shuffle +} + +; CHECK: vshufps $-53, (%{{.*}}), %xmm +define <4 x float> @A2128(<4 x float>* %a, <4 x float>* %b) nounwind uwtable readnone ssp { +entry: + %a2 = load <4 x float>* %a + %b2 = load <4 x float>* %b + %shuffle = shufflevector <4 x float> %a2, <4 x float> %b2, <4 x i32> <i32 3, i32 2, i32 4, i32 7> + ret <4 x float> %shuffle +} + +; CHECK: vshufps $-53, %xmm +define <4 x i32> @A3128(<4 x i32> %a, <4 x i32> %b) nounwind uwtable readnone ssp { +entry: + %shuffle = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 3, i32 2, i32 4, i32 7> + ret <4 x i32> %shuffle +} + +; CHECK: vshufps $-53, (%{{.*}}), %xmm +define <4 x i32> @A4128(<4 x i32>* %a, <4 x i32>* %b) nounwind uwtable readnone ssp { +entry: + %a2 = load <4 x i32>* %a + %b2 = load <4 x i32>* %b + %shuffle = shufflevector <4 x i32> %a2, <4 x i32> %b2, <4 x i32> <i32 3, i32 2, i32 4, i32 7> + ret <4 x i32> %shuffle +} + +; CHECK: vshufpd $1, %xmm +define <2 x double> @B128(<2 x double> %a, <2 x double> %b) nounwind uwtable readnone ssp { +entry: + %shuffle = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 2> + ret <2 x double> %shuffle +} + +; CHECK: vshufpd $1, (%{{.*}}), %xmm +define <2 x double> @B2128(<2 x double>* %a, <2 x double>* %b) nounwind uwtable readnone ssp { +entry: + %a2 = load <2 x double>* %a + %b2 = load <2 x double>* %b + %shuffle = shufflevector <2 x double> %a2, <2 x double> %b2, <2 x i32> <i32 1, i32 2> + ret <2 x double> %shuffle +} + +; CHECK: vshufpd $1, %xmm +define <2 x i64> @B3128(<2 x i64> %a, <2 x i64> %b) nounwind uwtable readnone ssp { +entry: + %shuffle = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 2> + ret <2 x i64> %shuffle +} + +; CHECK: vshufpd $1, (%{{.*}}), %xmm +define <2 x i64> @B4128(<2 x i64>* %a, <2 x i64>* %b) nounwind uwtable readnone ssp { +entry: + %a2 = load <2 x i64>* %a + %b2 = load <2 x i64>* %b + %shuffle = shufflevector <2 x i64> %a2, <2 x i64> %b2, <2 x i32> <i32 1, i32 2> + ret <2 x i64> %shuffle +} diff --git a/test/CodeGen/X86/avx-vzeroupper.ll b/test/CodeGen/X86/avx-vzeroupper.ll index eaf236c..bf4ab5b 100644 --- a/test/CodeGen/X86/avx-vzeroupper.ll +++ b/test/CodeGen/X86/avx-vzeroupper.ll @@ -1,26 +1,83 @@ ; RUN: llc < %s -x86-use-vzeroupper -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s -define <4 x float> @do_sse_local(<4 x float> %a) nounwind uwtable readnone ssp { -entry: - %add.i = fadd <4 x float> %a, %a - ret <4 x float> %add.i -} +declare <4 x float> @do_sse(<4 x float>) +declare <8 x float> @do_avx(<8 x float>) +declare <4 x float> @llvm.x86.avx.vextractf128.ps.256(<8 x float>, i8) nounwind readnone +@x = common global <4 x float> zeroinitializer, align 16 +@g = common global <8 x float> zeroinitializer, align 32 + +;; Basic checking - don't emit any vzeroupper instruction ; CHECK: _test00 define <4 x float> @test00(<4 x float> %a, <4 x float> %b) nounwind uwtable ssp { entry: + ; CHECK-NOT: vzeroupper %add.i = fadd <4 x float> %a, %b + %call3 = call <4 x float> @do_sse(<4 x float> %add.i) nounwind + ; CHECK: ret + ret <4 x float> %call3 +} + +;; Check parameter 256-bit parameter passing + +; CHECK: _test01 +define <8 x float> @test01(<4 x float> %a, <4 x float> %b, <8 x float> %c) nounwind uwtable ssp { +entry: + %tmp = load <4 x float>* @x, align 16 ; CHECK: vzeroupper ; CHECK-NEXT: callq _do_sse - %call3 = tail call <4 x float> @do_sse(<4 x float> %add.i) nounwind - %sub.i = fsub <4 x float> %call3, %add.i + %call = tail call <4 x float> @do_sse(<4 x float> %tmp) nounwind + store <4 x float> %call, <4 x float>* @x, align 16 ; CHECK-NOT: vzeroupper - ; CHECK: callq _do_sse_local - %call8 = tail call <4 x float> @do_sse_local(<4 x float> %sub.i) + ; CHECK: callq _do_sse + %call2 = tail call <4 x float> @do_sse(<4 x float> %call) nounwind + store <4 x float> %call2, <4 x float>* @x, align 16 + ; CHECK: ret + ret <8 x float> %c +} + +;; Test the pass convergence and also that vzeroupper is only issued when necessary, +;; for this function it should be only once + +; CHECK: _test02 +define <4 x float> @test02(<4 x float> %a, <4 x float> %b) nounwind uwtable ssp { +entry: + %add.i = fadd <4 x float> %a, %b + br label %for.body + +for.body: ; preds = %for.body, %entry + ; CHECK: LBB + ; CHECK-NOT: vzeroupper + %i.018 = phi i32 [ 0, %entry ], [ %1, %for.body ] + %c.017 = phi <4 x float> [ %add.i, %entry ], [ %call14, %for.body ] + ; CHECK: callq _do_sse + %call5 = tail call <4 x float> @do_sse(<4 x float> %c.017) nounwind + ; CHECK-NEXT: callq _do_sse + %call7 = tail call <4 x float> @do_sse(<4 x float> %call5) nounwind + %tmp11 = load <8 x float>* @g, align 32 + %0 = tail call <4 x float> @llvm.x86.avx.vextractf128.ps.256(<8 x float> %tmp11, i8 1) nounwind ; CHECK: vzeroupper - ; CHECK-NEXT: jmp _do_sse - %call10 = tail call <4 x float> @do_sse(<4 x float> %call8) nounwind - ret <4 x float> %call10 + ; CHECK-NEXT: callq _do_sse + %call14 = tail call <4 x float> @do_sse(<4 x float> %0) nounwind + %1 = add nsw i32 %i.018, 1 + %exitcond = icmp eq i32 %1, 4 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret <4 x float> %call14 } -declare <4 x float> @do_sse(<4 x float>) +;; Check that we also perform vzeroupper when we return from a function. + +; CHECK: _test03 +define <4 x float> @test03(<4 x float> %a, <4 x float> %b) nounwind uwtable ssp { +entry: + %shuf = shufflevector <4 x float> %a, <4 x float> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> + ; CHECK-NOT: vzeroupper + ; CHECK: call + %call = call <8 x float> @do_avx(<8 x float> %shuf) nounwind + %shuf2 = shufflevector <8 x float> %call, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> + ; CHECK: vzeroupper + ; CHECK: ret + ret <4 x float> %shuf2 +} diff --git a/test/CodeGen/X86/avx-win64-args.ll b/test/CodeGen/X86/avx-win64-args.ll new file mode 100755 index 0000000..85b2634 --- /dev/null +++ b/test/CodeGen/X86/avx-win64-args.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mcpu=corei7-avx -mattr=+avx | FileCheck %s +target triple = "x86_64-pc-win32" + +declare <8 x float> @foo(<8 x float>, i32) + +define <8 x float> @test1(<8 x float> %x, <8 x float> %y) nounwind uwtable readnone ssp { +entry: +; CHECK: test1 +; CHECK: leaq {{.*}}, %rcx +; CHECK: movl {{.*}}, %edx +; CHECK: call +; CHECK: ret + %x1 = fadd <8 x float> %x, %y + %call = call <8 x float> @foo(<8 x float> %x1, i32 1) nounwind + %y1 = fsub <8 x float> %call, %y + ret <8 x float> %y1 +} + diff --git a/test/CodeGen/X86/avx-win64.ll b/test/CodeGen/X86/avx-win64.ll new file mode 100644 index 0000000..dc6bd59 --- /dev/null +++ b/test/CodeGen/X86/avx-win64.ll @@ -0,0 +1,47 @@ +; RUN: llc < %s -mcpu=corei7-avx -mattr=+avx | FileCheck %s +; PR11862 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-pc-win32" + +; This function has live ymm registers across a win64 call. +; The ymm6-15 registers are still call-clobbered even if xmm6-15 are callee-saved. +; Verify that callee-saved registers are not being used. + +; CHECK: f___vyf +; CHECK: pushq %rbp +; CHECK: vmovmsk +; CHECK: vmovaps %ymm{{.*}}(%r +; CHECK: vmovaps %ymm{{.*}}(%r +; CHECK: call +; Two reloads. It's OK if these get folded. +; CHECK: vmovaps {{.*\(%r.*}}, %ymm +; CHECK: vmovaps {{.*\(%r.*}}, %ymm +; CHECK: blend +define <8 x float> @f___vyf(<8 x float> %x, <8 x i32> %__mask) nounwind readnone { +allocas: + %bincmp = fcmp oeq <8 x float> %x, zeroinitializer + %val_to_boolvec32 = sext <8 x i1> %bincmp to <8 x i32> + %"~test" = xor <8 x i32> %val_to_boolvec32, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1> + %"internal_mask&function_mask25" = and <8 x i32> %"~test", %__mask + %floatmask.i46 = bitcast <8 x i32> %"internal_mask&function_mask25" to <8 x float> + %v.i47 = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %floatmask.i46) nounwind readnone + %any_mm_cmp27 = icmp eq i32 %v.i47, 0 + br i1 %any_mm_cmp27, label %safe_if_after_false, label %safe_if_run_false + +safe_if_run_false: ; preds = %allocas + %binop = fadd <8 x float> %x, <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00> + %calltmp = call <8 x float> @f___vyf(<8 x float> %binop, <8 x i32> %"internal_mask&function_mask25") + %binop33 = fadd <8 x float> %calltmp, %x + %mask_as_float.i48 = bitcast <8 x i32> %"~test" to <8 x float> + %blend.i52 = call <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float> %x, <8 x float> %binop33, <8 x float> %mask_as_float.i48) nounwind + br label %safe_if_after_false + +safe_if_after_false: ; preds = %safe_if_run_false, %allocas + %0 = phi <8 x float> [ %x, %allocas ], [ %blend.i52, %safe_if_run_false ] + ret <8 x float> %0 +} + +declare i32 @llvm.x86.avx.movmsk.ps.256(<8 x float>) nounwind readnone +declare <8 x float> @llvm.x86.avx.maskload.ps.256(i8*, <8 x float>) nounwind readonly +declare void @llvm.x86.avx.maskstore.ps.256(i8*, <8 x float>, <8 x float>) nounwind +declare <8 x float> @llvm.x86.avx.blendv.ps.256(<8 x float>, <8 x float>, <8 x float>) nounwind readnone diff --git a/test/CodeGen/X86/avx-zext.ll b/test/CodeGen/X86/avx-zext.ll new file mode 100755 index 0000000..b630e9d --- /dev/null +++ b/test/CodeGen/X86/avx-zext.ll @@ -0,0 +1,30 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s + +define <8 x i32> @zext_8i16_to_8i32(<8 x i16> %A) nounwind uwtable readnone ssp { +;CHECK: zext_8i16_to_8i32 +;CHECK: vpunpckhwd +;CHECK: ret + + %B = zext <8 x i16> %A to <8 x i32> + ret <8 x i32>%B +} + +define <4 x i64> @zext_4i32_to_4i64(<4 x i32> %A) nounwind uwtable readnone ssp { +;CHECK: zext_4i32_to_4i64 +;CHECK: vpunpckhdq +;CHECK: ret + + %B = zext <4 x i32> %A to <4 x i64> + ret <4 x i64>%B +} + + +define <8 x i32> @zext_8i8_to_8i32(<8 x i8> %z) { +;CHECK: zext_8i8_to_8i32 +;CHECK: vpunpckhwd +;CHECK: vpunpcklwd +;CHECK: vinsertf128 +;CHECK: ret + %t = zext <8 x i8> %z to <8 x i32> + ret <8 x i32> %t +} diff --git a/test/CodeGen/X86/avx2-arith.ll b/test/CodeGen/X86/avx2-arith.ll new file mode 100644 index 0000000..09f9538 --- /dev/null +++ b/test/CodeGen/X86/avx2-arith.ll @@ -0,0 +1,76 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=+avx2 | FileCheck %s + +; CHECK: vpaddq %ymm +define <4 x i64> @vpaddq(<4 x i64> %i, <4 x i64> %j) nounwind readnone { + %x = add <4 x i64> %i, %j + ret <4 x i64> %x +} + +; CHECK: vpaddd %ymm +define <8 x i32> @vpaddd(<8 x i32> %i, <8 x i32> %j) nounwind readnone { + %x = add <8 x i32> %i, %j + ret <8 x i32> %x +} + +; CHECK: vpaddw %ymm +define <16 x i16> @vpaddw(<16 x i16> %i, <16 x i16> %j) nounwind readnone { + %x = add <16 x i16> %i, %j + ret <16 x i16> %x +} + +; CHECK: vpaddb %ymm +define <32 x i8> @vpaddb(<32 x i8> %i, <32 x i8> %j) nounwind readnone { + %x = add <32 x i8> %i, %j + ret <32 x i8> %x +} + +; CHECK: vpsubq %ymm +define <4 x i64> @vpsubq(<4 x i64> %i, <4 x i64> %j) nounwind readnone { + %x = sub <4 x i64> %i, %j + ret <4 x i64> %x +} + +; CHECK: vpsubd %ymm +define <8 x i32> @vpsubd(<8 x i32> %i, <8 x i32> %j) nounwind readnone { + %x = sub <8 x i32> %i, %j + ret <8 x i32> %x +} + +; CHECK: vpsubw %ymm +define <16 x i16> @vpsubw(<16 x i16> %i, <16 x i16> %j) nounwind readnone { + %x = sub <16 x i16> %i, %j + ret <16 x i16> %x +} + +; CHECK: vpsubb %ymm +define <32 x i8> @vpsubb(<32 x i8> %i, <32 x i8> %j) nounwind readnone { + %x = sub <32 x i8> %i, %j + ret <32 x i8> %x +} + +; CHECK: vpmulld %ymm +define <8 x i32> @vpmulld(<8 x i32> %i, <8 x i32> %j) nounwind readnone { + %x = mul <8 x i32> %i, %j + ret <8 x i32> %x +} + +; CHECK: vpmullw %ymm +define <16 x i16> @vpmullw(<16 x i16> %i, <16 x i16> %j) nounwind readnone { + %x = mul <16 x i16> %i, %j + ret <16 x i16> %x +} + +; CHECK: vpmuludq %ymm +; CHECK-NEXT: vpsrlq $32, %ymm +; CHECK-NEXT: vpmuludq %ymm +; CHECK-NEXT: vpsllq $32, %ymm +; CHECK-NEXT: vpaddq %ymm +; CHECK-NEXT: vpsrlq $32, %ymm +; CHECK-NEXT: vpmuludq %ymm +; CHECK-NEXT: vpsllq $32, %ymm +; CHECK-NEXT: vpaddq %ymm +define <4 x i64> @mul-v4i64(<4 x i64> %i, <4 x i64> %j) nounwind readnone { + %x = mul <4 x i64> %i, %j + ret <4 x i64> %x +} + diff --git a/test/CodeGen/X86/avx2-cmp.ll b/test/CodeGen/X86/avx2-cmp.ll new file mode 100644 index 0000000..df30d9e --- /dev/null +++ b/test/CodeGen/X86/avx2-cmp.ll @@ -0,0 +1,58 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=+avx2 | FileCheck %s + +; CHECK: vpcmpgtd %ymm +define <8 x i32> @int256-cmp(<8 x i32> %i, <8 x i32> %j) nounwind readnone { + %bincmp = icmp slt <8 x i32> %i, %j + %x = sext <8 x i1> %bincmp to <8 x i32> + ret <8 x i32> %x +} + +; CHECK: vpcmpgtq %ymm +define <4 x i64> @v4i64-cmp(<4 x i64> %i, <4 x i64> %j) nounwind readnone { + %bincmp = icmp slt <4 x i64> %i, %j + %x = sext <4 x i1> %bincmp to <4 x i64> + ret <4 x i64> %x +} + +; CHECK: vpcmpgtw %ymm +define <16 x i16> @v16i16-cmp(<16 x i16> %i, <16 x i16> %j) nounwind readnone { + %bincmp = icmp slt <16 x i16> %i, %j + %x = sext <16 x i1> %bincmp to <16 x i16> + ret <16 x i16> %x +} + +; CHECK: vpcmpgtb %ymm +define <32 x i8> @v32i8-cmp(<32 x i8> %i, <32 x i8> %j) nounwind readnone { + %bincmp = icmp slt <32 x i8> %i, %j + %x = sext <32 x i1> %bincmp to <32 x i8> + ret <32 x i8> %x +} + +; CHECK: vpcmpeqd %ymm +define <8 x i32> @int256-cmpeq(<8 x i32> %i, <8 x i32> %j) nounwind readnone { + %bincmp = icmp eq <8 x i32> %i, %j + %x = sext <8 x i1> %bincmp to <8 x i32> + ret <8 x i32> %x +} + +; CHECK: vpcmpeqq %ymm +define <4 x i64> @v4i64-cmpeq(<4 x i64> %i, <4 x i64> %j) nounwind readnone { + %bincmp = icmp eq <4 x i64> %i, %j + %x = sext <4 x i1> %bincmp to <4 x i64> + ret <4 x i64> %x +} + +; CHECK: vpcmpeqw %ymm +define <16 x i16> @v16i16-cmpeq(<16 x i16> %i, <16 x i16> %j) nounwind readnone { + %bincmp = icmp eq <16 x i16> %i, %j + %x = sext <16 x i1> %bincmp to <16 x i16> + ret <16 x i16> %x +} + +; CHECK: vpcmpeqb %ymm +define <32 x i8> @v32i8-cmpeq(<32 x i8> %i, <32 x i8> %j) nounwind readnone { + %bincmp = icmp eq <32 x i8> %i, %j + %x = sext <32 x i1> %bincmp to <32 x i8> + ret <32 x i8> %x +} + diff --git a/test/CodeGen/X86/avx2-intrinsics-x86.ll b/test/CodeGen/X86/avx2-intrinsics-x86.ll new file mode 100644 index 0000000..1fb41c0 --- /dev/null +++ b/test/CodeGen/X86/avx2-intrinsics-x86.ll @@ -0,0 +1,994 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -march=x86 -mcpu=core-avx2 -mattr=avx2 | FileCheck %s + +define <16 x i16> @test_x86_avx2_packssdw(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpackssdw + %res = call <16 x i16> @llvm.x86.avx2.packssdw(<8 x i32> %a0, <8 x i32> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.packssdw(<8 x i32>, <8 x i32>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_packsswb(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpacksswb + %res = call <32 x i8> @llvm.x86.avx2.packsswb(<16 x i16> %a0, <16 x i16> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.packsswb(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_packuswb(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpackuswb + %res = call <32 x i8> @llvm.x86.avx2.packuswb(<16 x i16> %a0, <16 x i16> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.packuswb(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_padds_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpaddsb + %res = call <32 x i8> @llvm.x86.avx2.padds.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.padds.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_padds_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpaddsw + %res = call <16 x i16> @llvm.x86.avx2.padds.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.padds.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_paddus_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpaddusb + %res = call <32 x i8> @llvm.x86.avx2.paddus.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.paddus.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_paddus_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpaddusw + %res = call <16 x i16> @llvm.x86.avx2.paddus.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.paddus.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_pavg_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpavgb + %res = call <32 x i8> @llvm.x86.avx2.pavg.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pavg.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pavg_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpavgw + %res = call <16 x i16> @llvm.x86.avx2.pavg.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pavg.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pmadd_wd(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpmaddwd + %res = call <8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16> %a0, <16 x i16> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16>, <16 x i16>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmaxs_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpmaxsw + %res = call <16 x i16> @llvm.x86.avx2.pmaxs.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmaxs.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_pmaxu_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpmaxub + %res = call <32 x i8> @llvm.x86.avx2.pmaxu.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pmaxu.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmins_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpminsw + %res = call <16 x i16> @llvm.x86.avx2.pmins.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmins.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_pminu_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpminub + %res = call <32 x i8> @llvm.x86.avx2.pminu.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pminu.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define i32 @test_x86_avx2_pmovmskb(<32 x i8> %a0) { + ; CHECK: vpmovmskb + %res = call i32 @llvm.x86.avx2.pmovmskb(<32 x i8> %a0) ; <i32> [#uses=1] + ret i32 %res +} +declare i32 @llvm.x86.avx2.pmovmskb(<32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmulh_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpmulhw + %res = call <16 x i16> @llvm.x86.avx2.pmulh.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmulh.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmulhu_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpmulhuw + %res = call <16 x i16> @llvm.x86.avx2.pmulhu.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmulhu.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pmulu_dq(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpmuludq + %res = call <4 x i64> @llvm.x86.avx2.pmulu.dq(<8 x i32> %a0, <8 x i32> %a1) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pmulu.dq(<8 x i32>, <8 x i32>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psad_bw(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpsadbw + %res = call <4 x i64> @llvm.x86.avx2.psad.bw(<32 x i8> %a0, <32 x i8> %a1) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psad.bw(<32 x i8>, <32 x i8>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psll_d(<8 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpslld + %res = call <8 x i32> @llvm.x86.avx2.psll.d(<8 x i32> %a0, <4 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psll.d(<8 x i32>, <4 x i32>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psll_dq(<4 x i64> %a0) { + ; CHECK: vpslldq + %res = call <4 x i64> @llvm.x86.avx2.psll.dq(<4 x i64> %a0, i32 7) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psll.dq(<4 x i64>, i32) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psll_dq_bs(<4 x i64> %a0) { + ; CHECK: vpslldq + %res = call <4 x i64> @llvm.x86.avx2.psll.dq.bs(<4 x i64> %a0, i32 7) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psll.dq.bs(<4 x i64>, i32) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psll_q(<4 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpsllq + %res = call <4 x i64> @llvm.x86.avx2.psll.q(<4 x i64> %a0, <2 x i64> %a1) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psll.q(<4 x i64>, <2 x i64>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_psll_w(<16 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpsllw + %res = call <16 x i16> @llvm.x86.avx2.psll.w(<16 x i16> %a0, <8 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.psll.w(<16 x i16>, <8 x i16>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pslli_d(<8 x i32> %a0) { + ; CHECK: vpslld + %res = call <8 x i32> @llvm.x86.avx2.pslli.d(<8 x i32> %a0, i32 7) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pslli.d(<8 x i32>, i32) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pslli_q(<4 x i64> %a0) { + ; CHECK: vpsllq + %res = call <4 x i64> @llvm.x86.avx2.pslli.q(<4 x i64> %a0, i32 7) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pslli.q(<4 x i64>, i32) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pslli_w(<16 x i16> %a0) { + ; CHECK: vpsllw + %res = call <16 x i16> @llvm.x86.avx2.pslli.w(<16 x i16> %a0, i32 7) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pslli.w(<16 x i16>, i32) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psra_d(<8 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpsrad + %res = call <8 x i32> @llvm.x86.avx2.psra.d(<8 x i32> %a0, <4 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psra.d(<8 x i32>, <4 x i32>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_psra_w(<16 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpsraw + %res = call <16 x i16> @llvm.x86.avx2.psra.w(<16 x i16> %a0, <8 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.psra.w(<16 x i16>, <8 x i16>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psrai_d(<8 x i32> %a0) { + ; CHECK: vpsrad + %res = call <8 x i32> @llvm.x86.avx2.psrai.d(<8 x i32> %a0, i32 7) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psrai.d(<8 x i32>, i32) nounwind readnone + + +define <16 x i16> @test_x86_avx2_psrai_w(<16 x i16> %a0) { + ; CHECK: vpsraw + %res = call <16 x i16> @llvm.x86.avx2.psrai.w(<16 x i16> %a0, i32 7) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.psrai.w(<16 x i16>, i32) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psrl_d(<8 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpsrld + %res = call <8 x i32> @llvm.x86.avx2.psrl.d(<8 x i32> %a0, <4 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psrl.d(<8 x i32>, <4 x i32>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psrl_dq(<4 x i64> %a0) { + ; CHECK: vpsrldq + %res = call <4 x i64> @llvm.x86.avx2.psrl.dq(<4 x i64> %a0, i32 7) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psrl.dq(<4 x i64>, i32) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psrl_dq_bs(<4 x i64> %a0) { + ; CHECK: vpsrldq + %res = call <4 x i64> @llvm.x86.avx2.psrl.dq.bs(<4 x i64> %a0, i32 7) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psrl.dq.bs(<4 x i64>, i32) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psrl_q(<4 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpsrlq + %res = call <4 x i64> @llvm.x86.avx2.psrl.q(<4 x i64> %a0, <2 x i64> %a1) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psrl.q(<4 x i64>, <2 x i64>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_psrl_w(<16 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpsrlw + %res = call <16 x i16> @llvm.x86.avx2.psrl.w(<16 x i16> %a0, <8 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.psrl.w(<16 x i16>, <8 x i16>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psrli_d(<8 x i32> %a0) { + ; CHECK: vpsrld + %res = call <8 x i32> @llvm.x86.avx2.psrli.d(<8 x i32> %a0, i32 7) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psrli.d(<8 x i32>, i32) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psrli_q(<4 x i64> %a0) { + ; CHECK: vpsrlq + %res = call <4 x i64> @llvm.x86.avx2.psrli.q(<4 x i64> %a0, i32 7) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psrli.q(<4 x i64>, i32) nounwind readnone + + +define <16 x i16> @test_x86_avx2_psrli_w(<16 x i16> %a0) { + ; CHECK: vpsrlw + %res = call <16 x i16> @llvm.x86.avx2.psrli.w(<16 x i16> %a0, i32 7) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.psrli.w(<16 x i16>, i32) nounwind readnone + + +define <32 x i8> @test_x86_avx2_psubs_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpsubsb + %res = call <32 x i8> @llvm.x86.avx2.psubs.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.psubs.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_psubs_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpsubsw + %res = call <16 x i16> @llvm.x86.avx2.psubs.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.psubs.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_psubus_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpsubusb + %res = call <32 x i8> @llvm.x86.avx2.psubus.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.psubus.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_psubus_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpsubusw + %res = call <16 x i16> @llvm.x86.avx2.psubus.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.psubus.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_pabs_b(<32 x i8> %a0) { + ; CHECK: vpabsb + %res = call <32 x i8> @llvm.x86.avx2.pabs.b(<32 x i8> %a0) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pabs.b(<32 x i8>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pabs_d(<8 x i32> %a0) { + ; CHECK: vpabsd + %res = call <8 x i32> @llvm.x86.avx2.pabs.d(<8 x i32> %a0) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pabs.d(<8 x i32>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pabs_w(<16 x i16> %a0) { + ; CHECK: vpabsw + %res = call <16 x i16> @llvm.x86.avx2.pabs.w(<16 x i16> %a0) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pabs.w(<16 x i16>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_phadd_d(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vphaddd + %res = call <8 x i32> @llvm.x86.avx2.phadd.d(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.phadd.d(<8 x i32>, <8 x i32>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_phadd_sw(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vphaddsw + %res = call <16 x i16> @llvm.x86.avx2.phadd.sw(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.phadd.sw(<16 x i16>, <16 x i16>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_phadd_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vphaddw + %res = call <16 x i16> @llvm.x86.avx2.phadd.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.phadd.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_phsub_d(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vphsubd + %res = call <8 x i32> @llvm.x86.avx2.phsub.d(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.phsub.d(<8 x i32>, <8 x i32>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_phsub_sw(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vphsubsw + %res = call <16 x i16> @llvm.x86.avx2.phsub.sw(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.phsub.sw(<16 x i16>, <16 x i16>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_phsub_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vphsubw + %res = call <16 x i16> @llvm.x86.avx2.phsub.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.phsub.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmadd_ub_sw(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpmaddubsw + %res = call <16 x i16> @llvm.x86.avx2.pmadd.ub.sw(<32 x i8> %a0, <32 x i8> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmadd.ub.sw(<32 x i8>, <32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmul_hr_sw(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpmulhrsw + %res = call <16 x i16> @llvm.x86.avx2.pmul.hr.sw(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmul.hr.sw(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_pshuf_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpshufb + %res = call <32 x i8> @llvm.x86.avx2.pshuf.b(<32 x i8> %a0, <32 x i8> %a1) ; <<16 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pshuf.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_psign_b(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpsignb + %res = call <32 x i8> @llvm.x86.avx2.psign.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.psign.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psign_d(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpsignd + %res = call <8 x i32> @llvm.x86.avx2.psign.d(<8 x i32> %a0, <8 x i32> %a1) ; <<4 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psign.d(<8 x i32>, <8 x i32>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_psign_w(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpsignw + %res = call <16 x i16> @llvm.x86.avx2.psign.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.psign.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_movntdqa(i8* %a0) { + ; CHECK: movl + ; CHECK: vmovntdqa + %res = call <4 x i64> @llvm.x86.avx2.movntdqa(i8* %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.movntdqa(i8*) nounwind readonly + + +define <16 x i16> @test_x86_avx2_mpsadbw(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vmpsadbw + %res = call <16 x i16> @llvm.x86.avx2.mpsadbw(<32 x i8> %a0, <32 x i8> %a1, i32 7) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.mpsadbw(<32 x i8>, <32 x i8>, i32) nounwind readnone + + +define <16 x i16> @test_x86_avx2_packusdw(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpackusdw + %res = call <16 x i16> @llvm.x86.avx2.packusdw(<8 x i32> %a0, <8 x i32> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.packusdw(<8 x i32>, <8 x i32>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_pblendvb(<32 x i8> %a0, <32 x i8> %a1, <32 x i8> %a2) { + ; CHECK: vpblendvb + %res = call <32 x i8> @llvm.x86.avx2.pblendvb(<32 x i8> %a0, <32 x i8> %a1, <32 x i8> %a2) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pblendvb(<32 x i8>, <32 x i8>, <32 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pblendw(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpblendw + %res = call <16 x i16> @llvm.x86.avx2.pblendw(<16 x i16> %a0, <16 x i16> %a1, i32 7) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pblendw(<16 x i16>, <16 x i16>, i32) nounwind readnone + + +define <32 x i8> @test_x86_avx2_pmaxsb(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpmaxsb + %res = call <32 x i8> @llvm.x86.avx2.pmaxs.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pmaxs.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pmaxsd(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpmaxsd + %res = call <8 x i32> @llvm.x86.avx2.pmaxs.d(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pmaxs.d(<8 x i32>, <8 x i32>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pmaxud(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpmaxud + %res = call <8 x i32> @llvm.x86.avx2.pmaxu.d(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pmaxu.d(<8 x i32>, <8 x i32>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmaxuw(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpmaxuw + %res = call <16 x i16> @llvm.x86.avx2.pmaxu.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmaxu.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <32 x i8> @test_x86_avx2_pminsb(<32 x i8> %a0, <32 x i8> %a1) { + ; CHECK: vpminsb + %res = call <32 x i8> @llvm.x86.avx2.pmins.b(<32 x i8> %a0, <32 x i8> %a1) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pmins.b(<32 x i8>, <32 x i8>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pminsd(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpminsd + %res = call <8 x i32> @llvm.x86.avx2.pmins.d(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pmins.d(<8 x i32>, <8 x i32>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pminud(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpminud + %res = call <8 x i32> @llvm.x86.avx2.pminu.d(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pminu.d(<8 x i32>, <8 x i32>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pminuw(<16 x i16> %a0, <16 x i16> %a1) { + ; CHECK: vpminuw + %res = call <16 x i16> @llvm.x86.avx2.pminu.w(<16 x i16> %a0, <16 x i16> %a1) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pminu.w(<16 x i16>, <16 x i16>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pmovsxbd(<16 x i8> %a0) { + ; CHECK: vpmovsxbd + %res = call <8 x i32> @llvm.x86.avx2.pmovsxbd(<16 x i8> %a0) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pmovsxbd(<16 x i8>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pmovsxbq(<16 x i8> %a0) { + ; CHECK: vpmovsxbq + %res = call <4 x i64> @llvm.x86.avx2.pmovsxbq(<16 x i8> %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pmovsxbq(<16 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmovsxbw(<16 x i8> %a0) { + ; CHECK: vpmovsxbw + %res = call <16 x i16> @llvm.x86.avx2.pmovsxbw(<16 x i8> %a0) ; <<8 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmovsxbw(<16 x i8>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pmovsxdq(<4 x i32> %a0) { + ; CHECK: vpmovsxdq + %res = call <4 x i64> @llvm.x86.avx2.pmovsxdq(<4 x i32> %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pmovsxdq(<4 x i32>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pmovsxwd(<8 x i16> %a0) { + ; CHECK: vpmovsxwd + %res = call <8 x i32> @llvm.x86.avx2.pmovsxwd(<8 x i16> %a0) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pmovsxwd(<8 x i16>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pmovsxwq(<8 x i16> %a0) { + ; CHECK: vpmovsxwq + %res = call <4 x i64> @llvm.x86.avx2.pmovsxwq(<8 x i16> %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pmovsxwq(<8 x i16>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pmovzxbd(<16 x i8> %a0) { + ; CHECK: vpmovzxbd + %res = call <8 x i32> @llvm.x86.avx2.pmovzxbd(<16 x i8> %a0) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pmovzxbd(<16 x i8>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pmovzxbq(<16 x i8> %a0) { + ; CHECK: vpmovzxbq + %res = call <4 x i64> @llvm.x86.avx2.pmovzxbq(<16 x i8> %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pmovzxbq(<16 x i8>) nounwind readnone + + +define <16 x i16> @test_x86_avx2_pmovzxbw(<16 x i8> %a0) { + ; CHECK: vpmovzxbw + %res = call <16 x i16> @llvm.x86.avx2.pmovzxbw(<16 x i8> %a0) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pmovzxbw(<16 x i8>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pmovzxdq(<4 x i32> %a0) { + ; CHECK: vpmovzxdq + %res = call <4 x i64> @llvm.x86.avx2.pmovzxdq(<4 x i32> %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pmovzxdq(<4 x i32>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pmovzxwd(<8 x i16> %a0) { + ; CHECK: vpmovzxwd + %res = call <8 x i32> @llvm.x86.avx2.pmovzxwd(<8 x i16> %a0) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pmovzxwd(<8 x i16>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pmovzxwq(<8 x i16> %a0) { + ; CHECK: vpmovzxwq + %res = call <4 x i64> @llvm.x86.avx2.pmovzxwq(<8 x i16> %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pmovzxwq(<8 x i16>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_pmul.dq(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpmuldq + %res = call <4 x i64> @llvm.x86.avx2.pmul.dq(<8 x i32> %a0, <8 x i32> %a1) ; <<2 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pmul.dq(<8 x i32>, <8 x i32>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_vbroadcasti128(i8* %a0) { + ; CHECK: vbroadcasti128 + %res = call <4 x i64> @llvm.x86.avx2.vbroadcasti128(i8* %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.vbroadcasti128(i8*) nounwind readonly + +define <4 x double> @test_x86_avx2_vbroadcast_sd_pd_256(<2 x double> %a0) { + ; CHECK: vbroadcastsd + %res = call <4 x double> @llvm.x86.avx2.vbroadcast.sd.pd.256(<2 x double> %a0) ; <<4 x double>> [#uses=1] + ret <4 x double> %res +} +declare <4 x double> @llvm.x86.avx2.vbroadcast.sd.pd.256(<2 x double>) nounwind readonly + + +define <4 x float> @test_x86_avx2_vbroadcast_ss_ps(<4 x float> %a0) { + ; CHECK: vbroadcastss + %res = call <4 x float> @llvm.x86.avx2.vbroadcast.ss.ps(<4 x float> %a0) ; <<4 x float>> [#uses=1] + ret <4 x float> %res +} +declare <4 x float> @llvm.x86.avx2.vbroadcast.ss.ps(<4 x float>) nounwind readonly + + +define <8 x float> @test_x86_avx2_vbroadcast_ss_ps_256(<4 x float> %a0) { + ; CHECK: vbroadcastss + %res = call <8 x float> @llvm.x86.avx2.vbroadcast.ss.ps.256(<4 x float> %a0) ; <<8 x float>> [#uses=1] + ret <8 x float> %res +} +declare <8 x float> @llvm.x86.avx2.vbroadcast.ss.ps.256(<4 x float>) nounwind readonly + + +define <4 x i32> @test_x86_avx2_pblendd_128(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpblendd + %res = call <4 x i32> @llvm.x86.avx2.pblendd.128(<4 x i32> %a0, <4 x i32> %a1, i32 7) ; <<4 x i32>> [#uses=1] + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.avx2.pblendd.128(<4 x i32>, <4 x i32>, i32) nounwind readnone + + +define <8 x i32> @test_x86_avx2_pblendd_256(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpblendd + %res = call <8 x i32> @llvm.x86.avx2.pblendd.256(<8 x i32> %a0, <8 x i32> %a1, i32 7) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pblendd.256(<8 x i32>, <8 x i32>, i32) nounwind readnone + + +define <16 x i8> @test_x86_avx2_pbroadcastb_128(<16 x i8> %a0) { + ; CHECK: vpbroadcastb + %res = call <16 x i8> @llvm.x86.avx2.pbroadcastb.128(<16 x i8> %a0) ; <<16 x i8>> [#uses=1] + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.avx2.pbroadcastb.128(<16 x i8>) nounwind readonly + + +define <32 x i8> @test_x86_avx2_pbroadcastb_256(<16 x i8> %a0) { + ; CHECK: vpbroadcastb + %res = call <32 x i8> @llvm.x86.avx2.pbroadcastb.256(<16 x i8> %a0) ; <<32 x i8>> [#uses=1] + ret <32 x i8> %res +} +declare <32 x i8> @llvm.x86.avx2.pbroadcastb.256(<16 x i8>) nounwind readonly + + +define <8 x i16> @test_x86_avx2_pbroadcastw_128(<8 x i16> %a0) { + ; CHECK: vpbroadcastw + %res = call <8 x i16> @llvm.x86.avx2.pbroadcastw.128(<8 x i16> %a0) ; <<8 x i16>> [#uses=1] + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.avx2.pbroadcastw.128(<8 x i16>) nounwind readonly + + +define <16 x i16> @test_x86_avx2_pbroadcastw_256(<8 x i16> %a0) { + ; CHECK: vpbroadcastw + %res = call <16 x i16> @llvm.x86.avx2.pbroadcastw.256(<8 x i16> %a0) ; <<16 x i16>> [#uses=1] + ret <16 x i16> %res +} +declare <16 x i16> @llvm.x86.avx2.pbroadcastw.256(<8 x i16>) nounwind readonly + + +define <4 x i32> @test_x86_avx2_pbroadcastd_128(<4 x i32> %a0) { + ; CHECK: vpbroadcastd + %res = call <4 x i32> @llvm.x86.avx2.pbroadcastd.128(<4 x i32> %a0) ; <<4 x i32>> [#uses=1] + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.avx2.pbroadcastd.128(<4 x i32>) nounwind readonly + + +define <8 x i32> @test_x86_avx2_pbroadcastd_256(<4 x i32> %a0) { + ; CHECK: vpbroadcastd + %res = call <8 x i32> @llvm.x86.avx2.pbroadcastd.256(<4 x i32> %a0) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.pbroadcastd.256(<4 x i32>) nounwind readonly + + +define <2 x i64> @test_x86_avx2_pbroadcastq_128(<2 x i64> %a0) { + ; CHECK: vpbroadcastq + %res = call <2 x i64> @llvm.x86.avx2.pbroadcastq.128(<2 x i64> %a0) ; <<2 x i64>> [#uses=1] + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.avx2.pbroadcastq.128(<2 x i64>) nounwind readonly + + +define <4 x i64> @test_x86_avx2_pbroadcastq_256(<2 x i64> %a0) { + ; CHECK: vpbroadcastq + %res = call <4 x i64> @llvm.x86.avx2.pbroadcastq.256(<2 x i64> %a0) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.pbroadcastq.256(<2 x i64>) nounwind readonly + + +define <8 x i32> @test_x86_avx2_permd(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpermd + %res = call <8 x i32> @llvm.x86.avx2.permd(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.permd(<8 x i32>, <8 x i32>) nounwind readonly + + +define <8 x float> @test_x86_avx2_permps(<8 x float> %a0, <8 x float> %a1) { + ; CHECK: vpermps + %res = call <8 x float> @llvm.x86.avx2.permps(<8 x float> %a0, <8 x float> %a1) ; <<8 x float>> [#uses=1] + ret <8 x float> %res +} +declare <8 x float> @llvm.x86.avx2.permps(<8 x float>, <8 x float>) nounwind readonly + + +define <4 x i64> @test_x86_avx2_permq(<4 x i64> %a0) { + ; CHECK: vpermq + %res = call <4 x i64> @llvm.x86.avx2.permq(<4 x i64> %a0, i8 7) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.permq(<4 x i64>, i8) nounwind readonly + + +define <4 x double> @test_x86_avx2_permpd(<4 x double> %a0) { + ; CHECK: vpermpd + %res = call <4 x double> @llvm.x86.avx2.permpd(<4 x double> %a0, i8 7) ; <<4 x double>> [#uses=1] + ret <4 x double> %res +} +declare <4 x double> @llvm.x86.avx2.permpd(<4 x double>, i8) nounwind readonly + + +define <4 x i64> @test_x86_avx2_vperm2i128(<4 x i64> %a0, <4 x i64> %a1) { + ; CHECK: vperm2i128 + %res = call <4 x i64> @llvm.x86.avx2.vperm2i128(<4 x i64> %a0, <4 x i64> %a1, i8 1) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.vperm2i128(<4 x i64>, <4 x i64>, i8) nounwind readonly + + +define <2 x i64> @test_x86_avx2_vextracti128(<4 x i64> %a0) { + ; CHECK: vextracti128 + %res = call <2 x i64> @llvm.x86.avx2.vextracti128(<4 x i64> %a0, i8 7) ; <<2 x i64>> [#uses=1] + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.avx2.vextracti128(<4 x i64>, i8) nounwind readnone + + +define <4 x i64> @test_x86_avx2_vinserti128(<4 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vinserti128 + %res = call <4 x i64> @llvm.x86.avx2.vinserti128(<4 x i64> %a0, <2 x i64> %a1, i8 7) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.vinserti128(<4 x i64>, <2 x i64>, i8) nounwind readnone + + +define <2 x i64> @test_x86_avx2_maskload_q(i8* %a0, <2 x i64> %a1) { + ; CHECK: vpmaskmovq + %res = call <2 x i64> @llvm.x86.avx2.maskload.q(i8* %a0, <2 x i64> %a1) ; <<2 x i64>> [#uses=1] + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.avx2.maskload.q(i8*, <2 x i64>) nounwind readonly + + +define <4 x i64> @test_x86_avx2_maskload_q_256(i8* %a0, <4 x i64> %a1) { + ; CHECK: vpmaskmovq + %res = call <4 x i64> @llvm.x86.avx2.maskload.q.256(i8* %a0, <4 x i64> %a1) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.maskload.q.256(i8*, <4 x i64>) nounwind readonly + + +define <4 x i32> @test_x86_avx2_maskload_d(i8* %a0, <4 x i32> %a1) { + ; CHECK: vpmaskmovd + %res = call <4 x i32> @llvm.x86.avx2.maskload.d(i8* %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1] + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.avx2.maskload.d(i8*, <4 x i32>) nounwind readonly + + +define <8 x i32> @test_x86_avx2_maskload_d_256(i8* %a0, <8 x i32> %a1) { + ; CHECK: vpmaskmovd + %res = call <8 x i32> @llvm.x86.avx2.maskload.d.256(i8* %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.maskload.d.256(i8*, <8 x i32>) nounwind readonly + + +define void @test_x86_avx2_maskstore_q(i8* %a0, <2 x i64> %a1, <2 x i64> %a2) { + ; CHECK: vpmaskmovq + call void @llvm.x86.avx2.maskstore.q(i8* %a0, <2 x i64> %a1, <2 x i64> %a2) + ret void +} +declare void @llvm.x86.avx2.maskstore.q(i8*, <2 x i64>, <2 x i64>) nounwind + + +define void @test_x86_avx2_maskstore_q_256(i8* %a0, <4 x i64> %a1, <4 x i64> %a2) { + ; CHECK: vpmaskmovq + call void @llvm.x86.avx2.maskstore.q.256(i8* %a0, <4 x i64> %a1, <4 x i64> %a2) + ret void +} +declare void @llvm.x86.avx2.maskstore.q.256(i8*, <4 x i64>, <4 x i64>) nounwind + + +define void @test_x86_avx2_maskstore_d(i8* %a0, <4 x i32> %a1, <4 x i32> %a2) { + ; CHECK: vpmaskmovd + call void @llvm.x86.avx2.maskstore.d(i8* %a0, <4 x i32> %a1, <4 x i32> %a2) + ret void +} +declare void @llvm.x86.avx2.maskstore.d(i8*, <4 x i32>, <4 x i32>) nounwind + + +define void @test_x86_avx2_maskstore_d_256(i8* %a0, <8 x i32> %a1, <8 x i32> %a2) { + ; CHECK: vpmaskmovd + call void @llvm.x86.avx2.maskstore.d.256(i8* %a0, <8 x i32> %a1, <8 x i32> %a2) + ret void +} +declare void @llvm.x86.avx2.maskstore.d.256(i8*, <8 x i32>, <8 x i32>) nounwind + + +define <4 x i32> @test_x86_avx2_psllv_d(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpsllvd + %res = call <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1] + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32>, <4 x i32>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psllv_d_256(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpsllvd + %res = call <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32>, <8 x i32>) nounwind readnone + + +define <2 x i64> @test_x86_avx2_psllv_q(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpsllvq + %res = call <2 x i64> @llvm.x86.avx2.psllv.q(<2 x i64> %a0, <2 x i64> %a1) ; <<2 x i64>> [#uses=1] + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.avx2.psllv.q(<2 x i64>, <2 x i64>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psllv_q_256(<4 x i64> %a0, <4 x i64> %a1) { + ; CHECK: vpsllvq + %res = call <4 x i64> @llvm.x86.avx2.psllv.q.256(<4 x i64> %a0, <4 x i64> %a1) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psllv.q.256(<4 x i64>, <4 x i64>) nounwind readnone + + +define <4 x i32> @test_x86_avx2_psrlv_d(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpsrlvd + %res = call <4 x i32> @llvm.x86.avx2.psrlv.d(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1] + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.avx2.psrlv.d(<4 x i32>, <4 x i32>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psrlv_d_256(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpsrlvd + %res = call <8 x i32> @llvm.x86.avx2.psrlv.d.256(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psrlv.d.256(<8 x i32>, <8 x i32>) nounwind readnone + + +define <2 x i64> @test_x86_avx2_psrlv_q(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpsrlvq + %res = call <2 x i64> @llvm.x86.avx2.psrlv.q(<2 x i64> %a0, <2 x i64> %a1) ; <<2 x i64>> [#uses=1] + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.avx2.psrlv.q(<2 x i64>, <2 x i64>) nounwind readnone + + +define <4 x i64> @test_x86_avx2_psrlv_q_256(<4 x i64> %a0, <4 x i64> %a1) { + ; CHECK: vpsrlvq + %res = call <4 x i64> @llvm.x86.avx2.psrlv.q.256(<4 x i64> %a0, <4 x i64> %a1) ; <<4 x i64>> [#uses=1] + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.avx2.psrlv.q.256(<4 x i64>, <4 x i64>) nounwind readnone + + +define <4 x i32> @test_x86_avx2_psrav_d(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpsravd + %res = call <4 x i32> @llvm.x86.avx2.psrav.d(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1] + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.avx2.psrav.d(<4 x i32>, <4 x i32>) nounwind readnone + + +define <8 x i32> @test_x86_avx2_psrav_d_256(<8 x i32> %a0, <8 x i32> %a1) { + ; CHECK: vpsravd + %res = call <8 x i32> @llvm.x86.avx2.psrav.d.256(<8 x i32> %a0, <8 x i32> %a1) ; <<8 x i32>> [#uses=1] + ret <8 x i32> %res +} +declare <8 x i32> @llvm.x86.avx2.psrav.d.256(<8 x i32>, <8 x i32>) nounwind readnone + +; This is checked here because the execution dependency fix pass makes it hard to test in AVX mode since we don't have 256-bit integer instructions +define void @test_x86_avx_storeu_dq_256(i8* %a0, <32 x i8> %a1) { + ; CHECK: vmovdqu + ; add operation forces the execution domain. + %a2 = add <32 x i8> %a1, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + call void @llvm.x86.avx.storeu.dq.256(i8* %a0, <32 x i8> %a2) + ret void +} +declare void @llvm.x86.avx.storeu.dq.256(i8*, <32 x i8>) nounwind diff --git a/test/CodeGen/X86/avx2-logic.ll b/test/CodeGen/X86/avx2-logic.ll new file mode 100644 index 0000000..13ebaa6 --- /dev/null +++ b/test/CodeGen/X86/avx2-logic.ll @@ -0,0 +1,96 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=+avx2 | FileCheck %s + +; CHECK: vpandn +; CHECK: vpandn %ymm +; CHECK: ret +define <4 x i64> @vpandn(<4 x i64> %a, <4 x i64> %b) nounwind uwtable readnone ssp { +entry: + ; Force the execution domain with an add. + %a2 = add <4 x i64> %a, <i64 1, i64 1, i64 1, i64 1> + %y = xor <4 x i64> %a2, <i64 -1, i64 -1, i64 -1, i64 -1> + %x = and <4 x i64> %a, %y + ret <4 x i64> %x +} + +; CHECK: vpand +; CHECK: vpand %ymm +; CHECK: ret +define <4 x i64> @vpand(<4 x i64> %a, <4 x i64> %b) nounwind uwtable readnone ssp { +entry: + ; Force the execution domain with an add. + %a2 = add <4 x i64> %a, <i64 1, i64 1, i64 1, i64 1> + %x = and <4 x i64> %a2, %b + ret <4 x i64> %x +} + +; CHECK: vpor +; CHECK: vpor %ymm +; CHECK: ret +define <4 x i64> @vpor(<4 x i64> %a, <4 x i64> %b) nounwind uwtable readnone ssp { +entry: + ; Force the execution domain with an add. + %a2 = add <4 x i64> %a, <i64 1, i64 1, i64 1, i64 1> + %x = or <4 x i64> %a2, %b + ret <4 x i64> %x +} + +; CHECK: vpxor +; CHECK: vpxor %ymm +; CHECK: ret +define <4 x i64> @vpxor(<4 x i64> %a, <4 x i64> %b) nounwind uwtable readnone ssp { +entry: + ; Force the execution domain with an add. + %a2 = add <4 x i64> %a, <i64 1, i64 1, i64 1, i64 1> + %x = xor <4 x i64> %a2, %b + ret <4 x i64> %x +} + +; CHECK: vpblendvb +; CHECK: vpblendvb %ymm +; CHECK: ret +define <32 x i8> @vpblendvb(<32 x i8> %x, <32 x i8> %y) { + %min_is_x = icmp ult <32 x i8> %x, %y + %min = select <32 x i1> %min_is_x, <32 x i8> %x, <32 x i8> %y + ret <32 x i8> %min +} + +define <8 x i32> @signd(<8 x i32> %a, <8 x i32> %b) nounwind { +entry: +; CHECK: signd: +; CHECK: psignd +; CHECK-NOT: sub +; CHECK: ret + %b.lobit = ashr <8 x i32> %b, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31> + %sub = sub nsw <8 x i32> zeroinitializer, %a + %0 = xor <8 x i32> %b.lobit, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1> + %1 = and <8 x i32> %a, %0 + %2 = and <8 x i32> %b.lobit, %sub + %cond = or <8 x i32> %1, %2 + ret <8 x i32> %cond +} + +define <8 x i32> @blendvb(<8 x i32> %b, <8 x i32> %a, <8 x i32> %c) nounwind { +entry: +; CHECK: blendvb: +; CHECK: pblendvb +; CHECK: ret + %b.lobit = ashr <8 x i32> %b, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31> + %sub = sub nsw <8 x i32> zeroinitializer, %a + %0 = xor <8 x i32> %b.lobit, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1> + %1 = and <8 x i32> %c, %0 + %2 = and <8 x i32> %a, %b.lobit + %cond = or <8 x i32> %1, %2 + ret <8 x i32> %cond +} + +define <8 x i32> @allOnes() nounwind { +; CHECK: vpcmpeqd +; CHECK-NOT: vinsert + ret <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1> +} + +define <16 x i16> @allOnes2() nounwind { +; CHECK: vpcmpeqd +; CHECK-NOT: vinsert + ret <16 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> +} diff --git a/test/CodeGen/X86/avx2-nontemporal.ll b/test/CodeGen/X86/avx2-nontemporal.ll new file mode 100644 index 0000000..0768aae --- /dev/null +++ b/test/CodeGen/X86/avx2-nontemporal.ll @@ -0,0 +1,22 @@ +; RUN: llc < %s -march=x86 -mattr=+avx2 | FileCheck %s + +define void @f(<8 x float> %A, i8* %B, <4 x double> %C, i32 %D, <4 x i64> %E) { +; CHECK: vmovntps + %cast = bitcast i8* %B to <8 x float>* + %A2 = fadd <8 x float> %A, <float 0x0, float 0x0, float 0x0, float 0x0, float 0x0, float 0x0, float 0x0, float 0x4200000000000000> + store <8 x float> %A2, <8 x float>* %cast, align 16, !nontemporal !0 +; CHECK: vmovntdq + %cast1 = bitcast i8* %B to <4 x i64>* + %E2 = add <4 x i64> %E, <i64 1, i64 2, i64 3, i64 4> + store <4 x i64> %E2, <4 x i64>* %cast1, align 16, !nontemporal !0 +; CHECK: vmovntpd + %cast2 = bitcast i8* %B to <4 x double>* + %C2 = fadd <4 x double> %C, <double 0x0, double 0x0, double 0x0, double 0x4200000000000000> + store <4 x double> %C2, <4 x double>* %cast2, align 16, !nontemporal !0 +; CHECK: movnti + %cast3 = bitcast i8* %B to i32* + store i32 %D, i32* %cast3, align 16, !nontemporal !0 + ret void +} + +!0 = metadata !{i32 1} diff --git a/test/CodeGen/X86/avx2-palignr.ll b/test/CodeGen/X86/avx2-palignr.ll new file mode 100644 index 0000000..53b9da3 --- /dev/null +++ b/test/CodeGen/X86/avx2-palignr.ll @@ -0,0 +1,57 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=+avx2 | FileCheck %s + +define <8 x i32> @test1(<8 x i32> %A, <8 x i32> %B) nounwind { +; CHECK: test1: +; CHECK: vpalignr $4 + %C = shufflevector <8 x i32> %A, <8 x i32> %B, <8 x i32> <i32 1, i32 2, i32 3, i32 8, i32 5, i32 6, i32 7, i32 12> + ret <8 x i32> %C +} + +define <8 x i32> @test2(<8 x i32> %A, <8 x i32> %B) nounwind { +; CHECK: test2: +; CHECK: vpalignr $4 + %C = shufflevector <8 x i32> %A, <8 x i32> %B, <8 x i32> <i32 1, i32 2, i32 3, i32 8, i32 5, i32 6, i32 undef, i32 12> + ret <8 x i32> %C +} + +define <8 x i32> @test3(<8 x i32> %A, <8 x i32> %B) nounwind { +; CHECK: test3: +; CHECK: vpalignr $4 + %C = shufflevector <8 x i32> %A, <8 x i32> %B, <8 x i32> <i32 1, i32 undef, i32 3, i32 8, i32 5, i32 6, i32 7, i32 12> + ret <8 x i32> %C +} +; +define <8 x i32> @test4(<8 x i32> %A, <8 x i32> %B) nounwind { +; CHECK: test4: +; CHECK: vpalignr $8 + %C = shufflevector <8 x i32> %A, <8 x i32> %B, <8 x i32> <i32 10, i32 11, i32 undef, i32 1, i32 14, i32 15, i32 4, i32 5> + ret <8 x i32> %C +} + +define <16 x i16> @test5(<16 x i16> %A, <16 x i16> %B) nounwind { +; CHECK: test5: +; CHECK: vpalignr $6 + %C = shufflevector <16 x i16> %A, <16 x i16> %B, <16 x i32> <i32 3, i32 4, i32 undef, i32 6, i32 7, i32 16, i32 17, i32 18, i32 11, i32 12, i32 13, i32 undef, i32 15, i32 24, i32 25, i32 26> + ret <16 x i16> %C +} + +define <16 x i16> @test6(<16 x i16> %A, <16 x i16> %B) nounwind { +; CHECK: test6: +; CHECK: vpalignr $6 + %C = shufflevector <16 x i16> %A, <16 x i16> %B, <16 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 11, i32 12, i32 13, i32 undef, i32 15, i32 24, i32 25, i32 26> + ret <16 x i16> %C +} + +define <16 x i16> @test7(<16 x i16> %A, <16 x i16> %B) nounwind { +; CHECK: test7: +; CHECK: vpalignr $6 + %C = shufflevector <16 x i16> %A, <16 x i16> %B, <16 x i32> <i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> + ret <16 x i16> %C +} + +define <32 x i8> @test8(<32 x i8> %A, <32 x i8> %B) nounwind { +; CHECK: test8: +; CHECK: palignr $5 + %C = shufflevector <32 x i8> %A, <32 x i8> %B, <32 x i32> <i32 5, i32 6, i32 7, i32 undef, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 32, i32 33, i32 34, i32 35, i32 36, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 48, i32 49, i32 50, i32 51, i32 52> + ret <32 x i8> %C +} diff --git a/test/CodeGen/X86/avx2-phaddsub.ll b/test/CodeGen/X86/avx2-phaddsub.ll new file mode 100644 index 0000000..4eac71d --- /dev/null +++ b/test/CodeGen/X86/avx2-phaddsub.ll @@ -0,0 +1,73 @@ +; RUN: llc < %s -march=x86-64 -mattr=+avx2 | FileCheck %s + +; CHECK: phaddw1: +; CHECK: vphaddw +define <16 x i16> @phaddw1(<16 x i16> %x, <16 x i16> %y) { + %a = shufflevector <16 x i16> %x, <16 x i16> %y, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 16, i32 18, i32 20, i32 22, i32 8, i32 10, i32 12, i32 14, i32 24, i32 26, i32 28, i32 30> + %b = shufflevector <16 x i16> %x, <16 x i16> %y, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 17, i32 19, i32 21, i32 23, i32 9, i32 11, i32 13, i32 15, i32 25, i32 27, i32 29, i32 31> + %r = add <16 x i16> %a, %b + ret <16 x i16> %r +} + +; CHECK: phaddw2: +; CHECK: vphaddw +define <16 x i16> @phaddw2(<16 x i16> %x, <16 x i16> %y) { + %a = shufflevector <16 x i16> %x, <16 x i16> %y, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 17, i32 19, i32 21, i32 23, i32 9, i32 11, i32 13, i32 15, i32 25, i32 27, i32 29, i32 31> + %b = shufflevector <16 x i16> %y, <16 x i16> %x, <16 x i32> <i32 16, i32 18, i32 20, i32 22, i32 0, i32 2, i32 4, i32 6, i32 24, i32 26, i32 28, i32 30, i32 8, i32 10, i32 12, i32 14> + %r = add <16 x i16> %a, %b + ret <16 x i16> %r +} + +; CHECK: phaddd1: +; CHECK: vphaddd +define <8 x i32> @phaddd1(<8 x i32> %x, <8 x i32> %y) { + %a = shufflevector <8 x i32> %x, <8 x i32> %y, <8 x i32> <i32 0, i32 2, i32 8, i32 10, i32 4, i32 6, i32 12, i32 14> + %b = shufflevector <8 x i32> %x, <8 x i32> %y, <8 x i32> <i32 1, i32 3, i32 9, i32 11, i32 5, i32 7, i32 13, i32 15> + %r = add <8 x i32> %a, %b + ret <8 x i32> %r +} + +; CHECK: phaddd2: +; CHECK: vphaddd +define <8 x i32> @phaddd2(<8 x i32> %x, <8 x i32> %y) { + %a = shufflevector <8 x i32> %x, <8 x i32> %y, <8 x i32> <i32 1, i32 2, i32 9, i32 10, i32 5, i32 6, i32 13, i32 14> + %b = shufflevector <8 x i32> %y, <8 x i32> %x, <8 x i32> <i32 8, i32 11, i32 0, i32 3, i32 12, i32 15, i32 4, i32 7> + %r = add <8 x i32> %a, %b + ret <8 x i32> %r +} + +; CHECK: phaddd3: +; CHECK: vphaddd +define <8 x i32> @phaddd3(<8 x i32> %x) { + %a = shufflevector <8 x i32> %x, <8 x i32> undef, <8 x i32> <i32 undef, i32 2, i32 8, i32 10, i32 4, i32 6, i32 undef, i32 14> + %b = shufflevector <8 x i32> %x, <8 x i32> undef, <8 x i32> <i32 1, i32 3, i32 9, i32 undef, i32 5, i32 7, i32 13, i32 15> + %r = add <8 x i32> %a, %b + ret <8 x i32> %r +} + +; CHECK: phsubw1: +; CHECK: vphsubw +define <16 x i16> @phsubw1(<16 x i16> %x, <16 x i16> %y) { + %a = shufflevector <16 x i16> %x, <16 x i16> %y, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 16, i32 18, i32 20, i32 22, i32 8, i32 10, i32 12, i32 14, i32 24, i32 26, i32 28, i32 30> + %b = shufflevector <16 x i16> %x, <16 x i16> %y, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 17, i32 19, i32 21, i32 23, i32 9, i32 11, i32 13, i32 15, i32 25, i32 27, i32 29, i32 31> + %r = sub <16 x i16> %a, %b + ret <16 x i16> %r +} + +; CHECK: phsubd1: +; CHECK: vphsubd +define <8 x i32> @phsubd1(<8 x i32> %x, <8 x i32> %y) { + %a = shufflevector <8 x i32> %x, <8 x i32> %y, <8 x i32> <i32 0, i32 2, i32 8, i32 10, i32 4, i32 6, i32 12, i32 14> + %b = shufflevector <8 x i32> %x, <8 x i32> %y, <8 x i32> <i32 1, i32 3, i32 9, i32 11, i32 5, i32 7, i32 13, i32 15> + %r = sub <8 x i32> %a, %b + ret <8 x i32> %r +} + +; CHECK: phsubd2: +; CHECK: vphsubd +define <8 x i32> @phsubd2(<8 x i32> %x, <8 x i32> %y) { + %a = shufflevector <8 x i32> %x, <8 x i32> %y, <8 x i32> <i32 0, i32 undef, i32 8, i32 undef, i32 4, i32 6, i32 12, i32 14> + %b = shufflevector <8 x i32> %x, <8 x i32> %y, <8 x i32> <i32 1, i32 undef, i32 9, i32 11, i32 5, i32 7, i32 undef, i32 15> + %r = sub <8 x i32> %a, %b + ret <8 x i32> %r +} diff --git a/test/CodeGen/X86/avx2-shift.ll b/test/CodeGen/X86/avx2-shift.ll new file mode 100644 index 0000000..1f192a0 --- /dev/null +++ b/test/CodeGen/X86/avx2-shift.ll @@ -0,0 +1,268 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=+avx2 | FileCheck %s + +; CHECK: variable_shl0 +; CHECK: psllvd +; CHECK: ret +define <4 x i32> @variable_shl0(<4 x i32> %x, <4 x i32> %y) { + %k = shl <4 x i32> %x, %y + ret <4 x i32> %k +} +; CHECK: variable_shl1 +; CHECK: psllvd +; CHECK: ret +define <8 x i32> @variable_shl1(<8 x i32> %x, <8 x i32> %y) { + %k = shl <8 x i32> %x, %y + ret <8 x i32> %k +} +; CHECK: variable_shl2 +; CHECK: psllvq +; CHECK: ret +define <2 x i64> @variable_shl2(<2 x i64> %x, <2 x i64> %y) { + %k = shl <2 x i64> %x, %y + ret <2 x i64> %k +} +; CHECK: variable_shl3 +; CHECK: psllvq +; CHECK: ret +define <4 x i64> @variable_shl3(<4 x i64> %x, <4 x i64> %y) { + %k = shl <4 x i64> %x, %y + ret <4 x i64> %k +} +; CHECK: variable_srl0 +; CHECK: psrlvd +; CHECK: ret +define <4 x i32> @variable_srl0(<4 x i32> %x, <4 x i32> %y) { + %k = lshr <4 x i32> %x, %y + ret <4 x i32> %k +} +; CHECK: variable_srl1 +; CHECK: psrlvd +; CHECK: ret +define <8 x i32> @variable_srl1(<8 x i32> %x, <8 x i32> %y) { + %k = lshr <8 x i32> %x, %y + ret <8 x i32> %k +} +; CHECK: variable_srl2 +; CHECK: psrlvq +; CHECK: ret +define <2 x i64> @variable_srl2(<2 x i64> %x, <2 x i64> %y) { + %k = lshr <2 x i64> %x, %y + ret <2 x i64> %k +} +; CHECK: variable_srl3 +; CHECK: psrlvq +; CHECK: ret +define <4 x i64> @variable_srl3(<4 x i64> %x, <4 x i64> %y) { + %k = lshr <4 x i64> %x, %y + ret <4 x i64> %k +} + +; CHECK: variable_sra0 +; CHECK: vpsravd +; CHECK: ret +define <4 x i32> @variable_sra0(<4 x i32> %x, <4 x i32> %y) { + %k = ashr <4 x i32> %x, %y + ret <4 x i32> %k +} +; CHECK: variable_sra1 +; CHECK: vpsravd +; CHECK: ret +define <8 x i32> @variable_sra1(<8 x i32> %x, <8 x i32> %y) { + %k = ashr <8 x i32> %x, %y + ret <8 x i32> %k +} + +;;; Shift left +; CHECK: vpslld +define <8 x i32> @vshift00(<8 x i32> %a) nounwind readnone { + %s = shl <8 x i32> %a, <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 +2> + ret <8 x i32> %s +} + +; CHECK: vpsllw +define <16 x i16> @vshift01(<16 x i16> %a) nounwind readnone { + %s = shl <16 x i16> %a, <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2> + ret <16 x i16> %s +} + +; CHECK: vpsllq +define <4 x i64> @vshift02(<4 x i64> %a) nounwind readnone { + %s = shl <4 x i64> %a, <i64 2, i64 2, i64 2, i64 2> + ret <4 x i64> %s +} + +;;; Logical Shift right +; CHECK: vpsrld +define <8 x i32> @vshift03(<8 x i32> %a) nounwind readnone { + %s = lshr <8 x i32> %a, <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 +2> + ret <8 x i32> %s +} + +; CHECK: vpsrlw +define <16 x i16> @vshift04(<16 x i16> %a) nounwind readnone { + %s = lshr <16 x i16> %a, <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2> + ret <16 x i16> %s +} + +; CHECK: vpsrlq +define <4 x i64> @vshift05(<4 x i64> %a) nounwind readnone { + %s = lshr <4 x i64> %a, <i64 2, i64 2, i64 2, i64 2> + ret <4 x i64> %s +} + +;;; Arithmetic Shift right +; CHECK: vpsrad +define <8 x i32> @vshift06(<8 x i32> %a) nounwind readnone { + %s = ashr <8 x i32> %a, <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 +2> + ret <8 x i32> %s +} + +; CHECK: vpsraw +define <16 x i16> @vshift07(<16 x i16> %a) nounwind readnone { + %s = ashr <16 x i16> %a, <i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2> + ret <16 x i16> %s +} + +; CHECK: variable_sra0_load +; CHECK: vpsravd (% +; CHECK: ret +define <4 x i32> @variable_sra0_load(<4 x i32> %x, <4 x i32>* %y) { + %y1 = load <4 x i32>* %y + %k = ashr <4 x i32> %x, %y1 + ret <4 x i32> %k +} + +; CHECK: variable_sra1_load +; CHECK: vpsravd (% +; CHECK: ret +define <8 x i32> @variable_sra1_load(<8 x i32> %x, <8 x i32>* %y) { + %y1 = load <8 x i32>* %y + %k = ashr <8 x i32> %x, %y1 + ret <8 x i32> %k +} + +; CHECK: variable_shl0_load +; CHECK: vpsllvd (% +; CHECK: ret +define <4 x i32> @variable_shl0_load(<4 x i32> %x, <4 x i32>* %y) { + %y1 = load <4 x i32>* %y + %k = shl <4 x i32> %x, %y1 + ret <4 x i32> %k +} +; CHECK: variable_shl1_load +; CHECK: vpsllvd (% +; CHECK: ret +define <8 x i32> @variable_shl1_load(<8 x i32> %x, <8 x i32>* %y) { + %y1 = load <8 x i32>* %y + %k = shl <8 x i32> %x, %y1 + ret <8 x i32> %k +} +; CHECK: variable_shl2_load +; CHECK: vpsllvq (% +; CHECK: ret +define <2 x i64> @variable_shl2_load(<2 x i64> %x, <2 x i64>* %y) { + %y1 = load <2 x i64>* %y + %k = shl <2 x i64> %x, %y1 + ret <2 x i64> %k +} +; CHECK: variable_shl3_load +; CHECK: vpsllvq (% +; CHECK: ret +define <4 x i64> @variable_shl3_load(<4 x i64> %x, <4 x i64>* %y) { + %y1 = load <4 x i64>* %y + %k = shl <4 x i64> %x, %y1 + ret <4 x i64> %k +} +; CHECK: variable_srl0_load +; CHECK: vpsrlvd (% +; CHECK: ret +define <4 x i32> @variable_srl0_load(<4 x i32> %x, <4 x i32>* %y) { + %y1 = load <4 x i32>* %y + %k = lshr <4 x i32> %x, %y1 + ret <4 x i32> %k +} +; CHECK: variable_srl1_load +; CHECK: vpsrlvd (% +; CHECK: ret +define <8 x i32> @variable_srl1_load(<8 x i32> %x, <8 x i32>* %y) { + %y1 = load <8 x i32>* %y + %k = lshr <8 x i32> %x, %y1 + ret <8 x i32> %k +} +; CHECK: variable_srl2_load +; CHECK: vpsrlvq (% +; CHECK: ret +define <2 x i64> @variable_srl2_load(<2 x i64> %x, <2 x i64>* %y) { + %y1 = load <2 x i64>* %y + %k = lshr <2 x i64> %x, %y1 + ret <2 x i64> %k +} +; CHECK: variable_srl3_load +; CHECK: vpsrlvq (% +; CHECK: ret +define <4 x i64> @variable_srl3_load(<4 x i64> %x, <4 x i64>* %y) { + %y1 = load <4 x i64>* %y + %k = lshr <4 x i64> %x, %y1 + ret <4 x i64> %k +} + +define <32 x i8> @shl9(<32 x i8> %A) nounwind { + %B = shl <32 x i8> %A, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3> + ret <32 x i8> %B +; CHECK: shl9: +; CHECK: vpsllw $3 +; CHECK: vpand +; CHECK: ret +} + +define <32 x i8> @shr9(<32 x i8> %A) nounwind { + %B = lshr <32 x i8> %A, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3> + ret <32 x i8> %B +; CHECK: shr9: +; CHECK: vpsrlw $3 +; CHECK: vpand +; CHECK: ret +} + +define <32 x i8> @sra_v32i8_7(<32 x i8> %A) nounwind { + %B = ashr <32 x i8> %A, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7> + ret <32 x i8> %B +; CHECK: sra_v32i8_7: +; CHECK: vpxor +; CHECK: vpcmpgtb +; CHECK: ret +} + +define <32 x i8> @sra_v32i8(<32 x i8> %A) nounwind { + %B = ashr <32 x i8> %A, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3> + ret <32 x i8> %B +; CHECK: sra_v32i8: +; CHECK: vpsrlw $3 +; CHECK: vpand +; CHECK: vpxor +; CHECK: vpsubb +; CHECK: ret +} + +; CHECK: _sext_v16i16 +; CHECK: vpsllw +; CHECK: vpsraw +; CHECK-NOT: vinsertf128 +define <16 x i16> @sext_v16i16(<16 x i16> %a) nounwind { + %b = trunc <16 x i16> %a to <16 x i8> + %c = sext <16 x i8> %b to <16 x i16> + ret <16 x i16> %c +} + +; CHECK: _sext_v8i32 +; CHECK: vpslld +; CHECK: vpsrad +; CHECK-NOT: vinsertf128 +define <8 x i32> @sext_v8i32(<8 x i32> %a) nounwind { + %b = trunc <8 x i32> %a to <8 x i16> + %c = sext <8 x i16> %b to <8 x i32> + ret <8 x i32> %c +} diff --git a/test/CodeGen/X86/avx2-unpack.ll b/test/CodeGen/X86/avx2-unpack.ll new file mode 100644 index 0000000..6d17443 --- /dev/null +++ b/test/CodeGen/X86/avx2-unpack.ll @@ -0,0 +1,86 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=+avx2 | FileCheck %s + +; CHECK: vpunpckhdq +define <8 x i32> @unpackhidq1(<8 x i32> %src1, <8 x i32> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <8 x i32> %src1, <8 x i32> %src2, <8 x i32> <i32 2, i32 10, i32 3, i32 11, i32 6, i32 14, i32 7, i32 15> + ret <8 x i32> %shuffle.i +} + +; CHECK: vpunpckhqdq +define <4 x i64> @unpackhiqdq1(<4 x i64> %src1, <4 x i64> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <4 x i64> %src1, <4 x i64> %src2, <4 x i32> <i32 1, i32 5, i32 3, i32 7> + ret <4 x i64> %shuffle.i +} + +; CHECK: vpunpckldq +define <8 x i32> @unpacklodq1(<8 x i32> %src1, <8 x i32> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <8 x i32> %src1, <8 x i32> %src2, <8 x i32> <i32 0, i32 8, i32 1, i32 9, i32 4, i32 12, i32 5, i32 13> + ret <8 x i32> %shuffle.i +} + +; CHECK: vpunpcklqdq +define <4 x i64> @unpacklqdq1(<4 x i64> %src1, <4 x i64> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <4 x i64> %src1, <4 x i64> %src2, <4 x i32> <i32 0, i32 4, i32 2, i32 6> + ret <4 x i64> %shuffle.i +} + +; CHECK: vpunpckhwd +define <16 x i16> @unpackhwd(<16 x i16> %src1, <16 x i16> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <16 x i16> %src1, <16 x i16> %src2, <16 x i32> <i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23, i32 12, i32 28, i32 13, i32 29, i32 14, i32 30, i32 15, i32 31> + ret <16 x i16> %shuffle.i +} + +; CHECK: vpunpcklwd +define <16 x i16> @unpacklwd(<16 x i16> %src1, <16 x i16> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <16 x i16> %src1, <16 x i16> %src2, <16 x i32> <i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 8, i32 24, i32 9, i32 25, i32 10, i32 26, i32 11, i32 27> + ret <16 x i16> %shuffle.i +} + +; CHECK: vpunpckhbw +define <32 x i8> @unpackhbw(<32 x i8> %src1, <32 x i8> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <32 x i8> %src1, <32 x i8> %src2, <32 x i32> <i32 8, i32 40, i32 9, i32 41, i32 10, i32 42, i32 11, i32 43, i32 12, i32 44, i32 13, i32 45, i32 14, i32 46, i32 15, i32 47, i32 24, i32 56, i32 25, i32 57, i32 26, i32 58, i32 27, i32 59, i32 28, i32 60, i32 29, i32 61, i32 30, i32 62, i32 31, i32 63> + ret <32 x i8> %shuffle.i +} + +; CHECK: vpunpcklbw +define <32 x i8> @unpacklbw(<32 x i8> %src1, <32 x i8> %src2) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <32 x i8> %src1, <32 x i8> %src2, <32 x i32> <i32 0, i32 32, i32 1, i32 33, i32 2, i32 34, i32 3, i32 35, i32 4, i32 36, i32 5, i32 37, i32 6, i32 38, i32 7, i32 39, i32 16, i32 48, i32 17, i32 49, i32 18, i32 50, i32 19, i32 51, i32 20, i32 52, i32 21, i32 53, i32 22, i32 54, i32 23, i32 55> + ret <32 x i8> %shuffle.i +} + +; CHECK: vpunpckhdq +define <8 x i32> @unpackhidq1_undef(<8 x i32> %src1) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <8 x i32> %src1, <8 x i32> %src1, <8 x i32> <i32 2, i32 10, i32 3, i32 11, i32 6, i32 14, i32 7, i32 15> + ret <8 x i32> %shuffle.i +} + +; CHECK: vpunpckhqdq +define <4 x i64> @unpackhiqdq1_undef(<4 x i64> %src1) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <4 x i64> %src1, <4 x i64> %src1, <4 x i32> <i32 1, i32 5, i32 3, i32 7> + ret <4 x i64> %shuffle.i +} + +; CHECK: vpunpckhwd +define <16 x i16> @unpackhwd_undef(<16 x i16> %src1) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <16 x i16> %src1, <16 x i16> %src1, <16 x i32> <i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23, i32 12, i32 28, i32 13, i32 29, i32 14, i32 30, i32 15, i32 31> + ret <16 x i16> %shuffle.i +} + +; CHECK: vpunpcklwd +define <16 x i16> @unpacklwd_undef(<16 x i16> %src1) nounwind uwtable readnone ssp { +entry: + %shuffle.i = shufflevector <16 x i16> %src1, <16 x i16> %src1, <16 x i32> <i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 8, i32 24, i32 9, i32 25, i32 10, i32 26, i32 11, i32 27> + ret <16 x i16> %shuffle.i +} + diff --git a/test/CodeGen/X86/avx2-vbroadcast.ll b/test/CodeGen/X86/avx2-vbroadcast.ll new file mode 100644 index 0000000..1a78414 --- /dev/null +++ b/test/CodeGen/X86/avx2-vbroadcast.ll @@ -0,0 +1,187 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=+avx2 | FileCheck %s + +; CHECK: vpbroadcastb (% +define <16 x i8> @BB16(i8* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load i8* %ptr, align 4 + %q0 = insertelement <16 x i8> undef, i8 %q, i32 0 + %q1 = insertelement <16 x i8> %q0, i8 %q, i32 1 + %q2 = insertelement <16 x i8> %q1, i8 %q, i32 2 + %q3 = insertelement <16 x i8> %q2, i8 %q, i32 3 + %q4 = insertelement <16 x i8> %q3, i8 %q, i32 4 + %q5 = insertelement <16 x i8> %q4, i8 %q, i32 5 + %q6 = insertelement <16 x i8> %q5, i8 %q, i32 6 + %q7 = insertelement <16 x i8> %q6, i8 %q, i32 7 + %q8 = insertelement <16 x i8> %q7, i8 %q, i32 8 + %q9 = insertelement <16 x i8> %q8, i8 %q, i32 9 + %qa = insertelement <16 x i8> %q9, i8 %q, i32 10 + %qb = insertelement <16 x i8> %qa, i8 %q, i32 11 + %qc = insertelement <16 x i8> %qb, i8 %q, i32 12 + %qd = insertelement <16 x i8> %qc, i8 %q, i32 13 + %qe = insertelement <16 x i8> %qd, i8 %q, i32 14 + %qf = insertelement <16 x i8> %qe, i8 %q, i32 15 + ret <16 x i8> %qf +} +; CHECK: vpbroadcastb (% +define <32 x i8> @BB32(i8* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load i8* %ptr, align 4 + %q0 = insertelement <32 x i8> undef, i8 %q, i32 0 + %q1 = insertelement <32 x i8> %q0, i8 %q, i32 1 + %q2 = insertelement <32 x i8> %q1, i8 %q, i32 2 + %q3 = insertelement <32 x i8> %q2, i8 %q, i32 3 + %q4 = insertelement <32 x i8> %q3, i8 %q, i32 4 + %q5 = insertelement <32 x i8> %q4, i8 %q, i32 5 + %q6 = insertelement <32 x i8> %q5, i8 %q, i32 6 + %q7 = insertelement <32 x i8> %q6, i8 %q, i32 7 + %q8 = insertelement <32 x i8> %q7, i8 %q, i32 8 + %q9 = insertelement <32 x i8> %q8, i8 %q, i32 9 + %qa = insertelement <32 x i8> %q9, i8 %q, i32 10 + %qb = insertelement <32 x i8> %qa, i8 %q, i32 11 + %qc = insertelement <32 x i8> %qb, i8 %q, i32 12 + %qd = insertelement <32 x i8> %qc, i8 %q, i32 13 + %qe = insertelement <32 x i8> %qd, i8 %q, i32 14 + %qf = insertelement <32 x i8> %qe, i8 %q, i32 15 + + %q20 = insertelement <32 x i8> %qf, i8 %q, i32 16 + %q21 = insertelement <32 x i8> %q20, i8 %q, i32 17 + %q22 = insertelement <32 x i8> %q21, i8 %q, i32 18 + %q23 = insertelement <32 x i8> %q22, i8 %q, i32 19 + %q24 = insertelement <32 x i8> %q23, i8 %q, i32 20 + %q25 = insertelement <32 x i8> %q24, i8 %q, i32 21 + %q26 = insertelement <32 x i8> %q25, i8 %q, i32 22 + %q27 = insertelement <32 x i8> %q26, i8 %q, i32 23 + %q28 = insertelement <32 x i8> %q27, i8 %q, i32 24 + %q29 = insertelement <32 x i8> %q28, i8 %q, i32 25 + %q2a = insertelement <32 x i8> %q29, i8 %q, i32 26 + %q2b = insertelement <32 x i8> %q2a, i8 %q, i32 27 + %q2c = insertelement <32 x i8> %q2b, i8 %q, i32 28 + %q2d = insertelement <32 x i8> %q2c, i8 %q, i32 29 + %q2e = insertelement <32 x i8> %q2d, i8 %q, i32 30 + %q2f = insertelement <32 x i8> %q2e, i8 %q, i32 31 + ret <32 x i8> %q2f +} +; CHECK: vpbroadcastw (% + +define <8 x i16> @W16(i16* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load i16* %ptr, align 4 + %q0 = insertelement <8 x i16> undef, i16 %q, i32 0 + %q1 = insertelement <8 x i16> %q0, i16 %q, i32 1 + %q2 = insertelement <8 x i16> %q1, i16 %q, i32 2 + %q3 = insertelement <8 x i16> %q2, i16 %q, i32 3 + %q4 = insertelement <8 x i16> %q3, i16 %q, i32 4 + %q5 = insertelement <8 x i16> %q4, i16 %q, i32 5 + %q6 = insertelement <8 x i16> %q5, i16 %q, i32 6 + %q7 = insertelement <8 x i16> %q6, i16 %q, i32 7 + ret <8 x i16> %q7 +} +; CHECK: vpbroadcastw (% +define <16 x i16> @WW16(i16* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load i16* %ptr, align 4 + %q0 = insertelement <16 x i16> undef, i16 %q, i32 0 + %q1 = insertelement <16 x i16> %q0, i16 %q, i32 1 + %q2 = insertelement <16 x i16> %q1, i16 %q, i32 2 + %q3 = insertelement <16 x i16> %q2, i16 %q, i32 3 + %q4 = insertelement <16 x i16> %q3, i16 %q, i32 4 + %q5 = insertelement <16 x i16> %q4, i16 %q, i32 5 + %q6 = insertelement <16 x i16> %q5, i16 %q, i32 6 + %q7 = insertelement <16 x i16> %q6, i16 %q, i32 7 + %q8 = insertelement <16 x i16> %q7, i16 %q, i32 8 + %q9 = insertelement <16 x i16> %q8, i16 %q, i32 9 + %qa = insertelement <16 x i16> %q9, i16 %q, i32 10 + %qb = insertelement <16 x i16> %qa, i16 %q, i32 11 + %qc = insertelement <16 x i16> %qb, i16 %q, i32 12 + %qd = insertelement <16 x i16> %qc, i16 %q, i32 13 + %qe = insertelement <16 x i16> %qd, i16 %q, i32 14 + %qf = insertelement <16 x i16> %qe, i16 %q, i32 15 + ret <16 x i16> %qf +} +; CHECK: vpbroadcastd (% +define <4 x i32> @D32(i32* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load i32* %ptr, align 4 + %q0 = insertelement <4 x i32> undef, i32 %q, i32 0 + %q1 = insertelement <4 x i32> %q0, i32 %q, i32 1 + %q2 = insertelement <4 x i32> %q1, i32 %q, i32 2 + %q3 = insertelement <4 x i32> %q2, i32 %q, i32 3 + ret <4 x i32> %q3 +} +; CHECK: vpbroadcastd (% +define <8 x i32> @DD32(i32* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load i32* %ptr, align 4 + %q0 = insertelement <8 x i32> undef, i32 %q, i32 0 + %q1 = insertelement <8 x i32> %q0, i32 %q, i32 1 + %q2 = insertelement <8 x i32> %q1, i32 %q, i32 2 + %q3 = insertelement <8 x i32> %q2, i32 %q, i32 3 + %q4 = insertelement <8 x i32> %q3, i32 %q, i32 4 + %q5 = insertelement <8 x i32> %q4, i32 %q, i32 5 + %q6 = insertelement <8 x i32> %q5, i32 %q, i32 6 + %q7 = insertelement <8 x i32> %q6, i32 %q, i32 7 + ret <8 x i32> %q7 +} +; CHECK: vpbroadcastq (% +define <2 x i64> @Q64(i64* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load i64* %ptr, align 4 + %q0 = insertelement <2 x i64> undef, i64 %q, i32 0 + %q1 = insertelement <2 x i64> %q0, i64 %q, i32 1 + ret <2 x i64> %q1 +} +; CHECK: vpbroadcastq (% +define <4 x i64> @QQ64(i64* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load i64* %ptr, align 4 + %q0 = insertelement <4 x i64> undef, i64 %q, i32 0 + %q1 = insertelement <4 x i64> %q0, i64 %q, i32 1 + %q2 = insertelement <4 x i64> %q1, i64 %q, i32 2 + %q3 = insertelement <4 x i64> %q2, i64 %q, i32 3 + ret <4 x i64> %q3 +} + +; make sure that we still don't support broadcast double into 128-bit vector +; this used to crash +define <2 x double> @I(double* %ptr) nounwind uwtable readnone ssp { +entry: + %q = load double* %ptr, align 4 + %vecinit.i = insertelement <2 x double> undef, double %q, i32 0 + %vecinit2.i = insertelement <2 x double> %vecinit.i, double %q, i32 1 + ret <2 x double> %vecinit2.i +} + +; CHECK: V111 +; CHECK: vpbroadcastd +; CHECK: ret +define <8 x i32> @V111(<8 x i32> %in) nounwind uwtable readnone ssp { +entry: + %g = add <8 x i32> %in, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + ret <8 x i32> %g +} + +; CHECK: _e2 +; CHECK: vbroadcastss +; CHECK: ret +define <4 x float> @_e2(float* %ptr) nounwind uwtable readnone ssp { + %vecinit.i = insertelement <4 x float> undef, float 0xbf80000000000000, i32 0 + %vecinit2.i = insertelement <4 x float> %vecinit.i, float 0xbf80000000000000, i32 1 + %vecinit4.i = insertelement <4 x float> %vecinit2.i, float 0xbf80000000000000, i32 2 + %vecinit6.i = insertelement <4 x float> %vecinit4.i, float 0xbf80000000000000, i32 3 + ret <4 x float> %vecinit6.i +} + +; CHECK: _e4 +; CHECK-NOT: broadcast +; CHECK: ret +define <8 x i8> @_e4(i8* %ptr) nounwind uwtable readnone ssp { + %vecinit0.i = insertelement <8 x i8> undef, i8 52, i32 0 + %vecinit1.i = insertelement <8 x i8> %vecinit0.i, i8 52, i32 1 + %vecinit2.i = insertelement <8 x i8> %vecinit1.i, i8 52, i32 2 + %vecinit3.i = insertelement <8 x i8> %vecinit2.i, i8 52, i32 3 + %vecinit4.i = insertelement <8 x i8> %vecinit3.i, i8 52, i32 3 + %vecinit5.i = insertelement <8 x i8> %vecinit4.i, i8 52, i32 3 + %vecinit6.i = insertelement <8 x i8> %vecinit5.i, i8 52, i32 3 + %vecinit7.i = insertelement <8 x i8> %vecinit6.i, i8 52, i32 3 + ret <8 x i8> %vecinit7.i +} diff --git a/test/CodeGen/X86/avx2-vperm2i128.ll b/test/CodeGen/X86/avx2-vperm2i128.ll new file mode 100644 index 0000000..1937db5 --- /dev/null +++ b/test/CodeGen/X86/avx2-vperm2i128.ll @@ -0,0 +1,47 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=+avx2 | FileCheck %s + +; CHECK: vperm2i128 $17 +define <32 x i8> @E(<32 x i8> %a, <32 x i8> %b) nounwind uwtable readnone ssp { +entry: + ; add forces execution domain + %a2 = add <32 x i8> %a, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> + %shuffle = shufflevector <32 x i8> %a2, <32 x i8> %b, <32 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31> + ret <32 x i8> %shuffle +} + +; CHECK: vperm2i128 $3 +define <4 x i64> @E2(<4 x i64> %a, <4 x i64> %b) nounwind uwtable readnone ssp { +entry: + ; add forces execution domain + %a2 = add <4 x i64> %a, <i64 1, i64 1, i64 1, i64 1> + %shuffle = shufflevector <4 x i64> %a2, <4 x i64> %b, <4 x i32> <i32 6, i32 7, i32 0, i32 1> + ret <4 x i64> %shuffle +} + +; CHECK: vperm2i128 $49 +define <8 x i32> @E3(<8 x i32> %a, <8 x i32> %b) nounwind uwtable readnone ssp { +entry: + ; add forces execution domain + %a2 = add <8 x i32> %a, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1> + %shuffle = shufflevector <8 x i32> %a2, <8 x i32> %b, <8 x i32> <i32 undef, i32 5, i32 undef, i32 7, i32 12, i32 13, i32 14, i32 15> + ret <8 x i32> %shuffle +} + +; CHECK: vperm2i128 $2 +define <16 x i16> @E4(<16 x i16> %a, <16 x i16> %b) nounwind uwtable readnone ssp { +entry: + ; add forces execution domain + %a2 = add <16 x i16> %a, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %shuffle = shufflevector <16 x i16> %a2, <16 x i16> %b, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> + ret <16 x i16> %shuffle +} + +; CHECK: vperm2i128 $2, (% +define <16 x i16> @E5(<16 x i16>* %a, <16 x i16>* %b) nounwind uwtable readnone ssp { +entry: + %c = load <16 x i16>* %a + %d = load <16 x i16>* %b + %c2 = add <16 x i16> %c, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> + %shuffle = shufflevector <16 x i16> %c2, <16 x i16> %d, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> + ret <16 x i16> %shuffle +} diff --git a/test/CodeGen/X86/bc-extract.ll b/test/CodeGen/X86/bc-extract.ll index ac972a8..ceabcb7 100644 --- a/test/CodeGen/X86/bc-extract.ll +++ b/test/CodeGen/X86/bc-extract.ll @@ -11,7 +11,7 @@ entry: define float @extractFloat2() nounwind { entry: - ; CHECK: pxor %xmm0, %xmm0 + ; CHECK: xorps %xmm0, %xmm0 %tmp4 = bitcast <1 x double> <double 0x000000003F800000> to <2 x float> %tmp5 = extractelement <2 x float> %tmp4, i32 1 ret float %tmp5 diff --git a/test/CodeGen/X86/blend-msb.ll b/test/CodeGen/X86/blend-msb.ll new file mode 100644 index 0000000..3a10c70 --- /dev/null +++ b/test/CodeGen/X86/blend-msb.ll @@ -0,0 +1,37 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 -promote-elements -mattr=+sse41 | FileCheck %s + + +; In this test we check that sign-extend of the mask bit is performed by +; shifting the needed bit to the MSB, and not using shl+sra. + +;CHECK: vsel_float +;CHECK: pslld +;CHECK-NEXT: blendvps +;CHECK: ret +define <4 x float> @vsel_float(<4 x float> %v1, <4 x float> %v2) { + %vsel = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x float> %v1, <4 x float> %v2 + ret <4 x float> %vsel +} + +;CHECK: vsel_4xi8 +;CHECK: pslld +;CHECK-NEXT: blendvps +;CHECK: ret +define <4 x i8> @vsel_4xi8(<4 x i8> %v1, <4 x i8> %v2) { + %vsel = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x i8> %v1, <4 x i8> %v2 + ret <4 x i8> %vsel +} + + +; We do not have native support for v8i16 blends and we have to use the +; blendvb instruction or a sequence of NAND/OR/AND. Make sure that we do not r +; reduce the mask in this case. +;CHECK: vsel_8xi16 +;CHECK: psllw +;CHECK: psraw +;CHECK: pblendvb +;CHECK: ret +define <8 x i16> @vsel_8xi16(<8 x i16> %v1, <8 x i16> %v2) { + %vsel = select <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 false>, <8 x i16> %v1, <8 x i16> %v2 + ret <8 x i16> %vsel +} diff --git a/test/CodeGen/X86/block-placement.ll b/test/CodeGen/X86/block-placement.ll new file mode 100644 index 0000000..167d522 --- /dev/null +++ b/test/CodeGen/X86/block-placement.ll @@ -0,0 +1,930 @@ +; RUN: llc -mtriple=i686-linux -enable-block-placement < %s | FileCheck %s + +declare void @error(i32 %i, i32 %a, i32 %b) + +define i32 @test_ifchains(i32 %i, i32* %a, i32 %b) { +; Test a chain of ifs, where the block guarded by the if is error handling code +; that is not expected to run. +; CHECK: test_ifchains: +; CHECK: %entry +; CHECK: %else1 +; CHECK: %else2 +; CHECK: %else3 +; CHECK: %else4 +; CHECK: %exit +; CHECK: %then1 +; CHECK: %then2 +; CHECK: %then3 +; CHECK: %then4 +; CHECK: %then5 + +entry: + %gep1 = getelementptr i32* %a, i32 1 + %val1 = load i32* %gep1 + %cond1 = icmp ugt i32 %val1, 1 + br i1 %cond1, label %then1, label %else1, !prof !0 + +then1: + call void @error(i32 %i, i32 1, i32 %b) + br label %else1 + +else1: + %gep2 = getelementptr i32* %a, i32 2 + %val2 = load i32* %gep2 + %cond2 = icmp ugt i32 %val2, 2 + br i1 %cond2, label %then2, label %else2, !prof !0 + +then2: + call void @error(i32 %i, i32 1, i32 %b) + br label %else2 + +else2: + %gep3 = getelementptr i32* %a, i32 3 + %val3 = load i32* %gep3 + %cond3 = icmp ugt i32 %val3, 3 + br i1 %cond3, label %then3, label %else3, !prof !0 + +then3: + call void @error(i32 %i, i32 1, i32 %b) + br label %else3 + +else3: + %gep4 = getelementptr i32* %a, i32 4 + %val4 = load i32* %gep4 + %cond4 = icmp ugt i32 %val4, 4 + br i1 %cond4, label %then4, label %else4, !prof !0 + +then4: + call void @error(i32 %i, i32 1, i32 %b) + br label %else4 + +else4: + %gep5 = getelementptr i32* %a, i32 3 + %val5 = load i32* %gep5 + %cond5 = icmp ugt i32 %val5, 3 + br i1 %cond5, label %then5, label %exit, !prof !0 + +then5: + call void @error(i32 %i, i32 1, i32 %b) + br label %exit + +exit: + ret i32 %b +} + +define i32 @test_loop_cold_blocks(i32 %i, i32* %a) { +; Check that we sink cold loop blocks after the hot loop body. +; CHECK: test_loop_cold_blocks: +; CHECK: %entry +; CHECK: %body1 +; CHECK: %body2 +; CHECK: %body3 +; CHECK: %unlikely1 +; CHECK: %unlikely2 +; CHECK: %exit + +entry: + br label %body1 + +body1: + %iv = phi i32 [ 0, %entry ], [ %next, %body3 ] + %base = phi i32 [ 0, %entry ], [ %sum, %body3 ] + %unlikelycond1 = icmp slt i32 %base, 42 + br i1 %unlikelycond1, label %unlikely1, label %body2, !prof !0 + +unlikely1: + call void @error(i32 %i, i32 1, i32 %base) + br label %body2 + +body2: + %unlikelycond2 = icmp sgt i32 %base, 21 + br i1 %unlikelycond2, label %unlikely2, label %body3, !prof !0 + +unlikely2: + call void @error(i32 %i, i32 2, i32 %base) + br label %body3 + +body3: + %arrayidx = getelementptr inbounds i32* %a, i32 %iv + %0 = load i32* %arrayidx + %sum = add nsw i32 %0, %base + %next = add i32 %iv, 1 + %exitcond = icmp eq i32 %next, %i + br i1 %exitcond, label %exit, label %body1 + +exit: + ret i32 %sum +} + +!0 = metadata !{metadata !"branch_weights", i32 4, i32 64} + +define i32 @test_loop_early_exits(i32 %i, i32* %a) { +; Check that we sink early exit blocks out of loop bodies. +; CHECK: test_loop_early_exits: +; CHECK: %entry +; CHECK: %body2 +; CHECK: %body3 +; CHECK: %body4 +; CHECK: %body1 +; CHECK: %bail1 +; CHECK: %bail2 +; CHECK: %bail3 +; CHECK: %exit + +entry: + br label %body1 + +body1: + %iv = phi i32 [ 0, %entry ], [ %next, %body4 ] + %base = phi i32 [ 0, %entry ], [ %sum, %body4 ] + %bailcond1 = icmp eq i32 %base, 42 + br i1 %bailcond1, label %bail1, label %body2 + +bail1: + ret i32 -1 + +body2: + %bailcond2 = icmp eq i32 %base, 43 + br i1 %bailcond2, label %bail2, label %body3 + +bail2: + ret i32 -2 + +body3: + %bailcond3 = icmp eq i32 %base, 44 + br i1 %bailcond3, label %bail3, label %body4 + +bail3: + ret i32 -3 + +body4: + %arrayidx = getelementptr inbounds i32* %a, i32 %iv + %0 = load i32* %arrayidx + %sum = add nsw i32 %0, %base + %next = add i32 %iv, 1 + %exitcond = icmp eq i32 %next, %i + br i1 %exitcond, label %exit, label %body1 + +exit: + ret i32 %sum +} + +define i32 @test_loop_rotate(i32 %i, i32* %a) { +; Check that we rotate conditional exits from the loop to the bottom of the +; loop, eliminating unconditional branches to the top. +; CHECK: test_loop_rotate: +; CHECK: %entry +; CHECK: %body1 +; CHECK: %body0 +; CHECK: %exit + +entry: + br label %body0 + +body0: + %iv = phi i32 [ 0, %entry ], [ %next, %body1 ] + %base = phi i32 [ 0, %entry ], [ %sum, %body1 ] + %next = add i32 %iv, 1 + %exitcond = icmp eq i32 %next, %i + br i1 %exitcond, label %exit, label %body1 + +body1: + %arrayidx = getelementptr inbounds i32* %a, i32 %iv + %0 = load i32* %arrayidx + %sum = add nsw i32 %0, %base + %bailcond1 = icmp eq i32 %sum, 42 + br label %body0 + +exit: + ret i32 %base +} + +define void @test_loop_rotate_reversed_blocks() { +; This test case (greatly reduced from an Olden bencmark) ensures that the loop +; rotate implementation doesn't assume that loops are laid out in a particular +; order. The first loop will get split into two basic blocks, with the loop +; header coming after the loop latch. +; +; CHECK: test_loop_rotate_reversed_blocks +; CHECK: %entry +; Look for a jump into the middle of the loop, and no branches mid-way. +; CHECK: jmp +; CHECK: %loop1 +; CHECK-NOT: j{{\w*}} .LBB{{.*}} +; CHECK: %loop1 +; CHECK: je + +entry: + %cond1 = load volatile i1* undef + br i1 %cond1, label %loop2.preheader, label %loop1 + +loop1: + call i32 @f() + %cond2 = load volatile i1* undef + br i1 %cond2, label %loop2.preheader, label %loop1 + +loop2.preheader: + call i32 @f() + %cond3 = load volatile i1* undef + br i1 %cond3, label %exit, label %loop2 + +loop2: + call i32 @f() + %cond4 = load volatile i1* undef + br i1 %cond4, label %exit, label %loop2 + +exit: + ret void +} + +define i32 @test_loop_align(i32 %i, i32* %a) { +; Check that we provide basic loop body alignment with the block placement +; pass. +; CHECK: test_loop_align: +; CHECK: %entry +; CHECK: .align [[ALIGN:[0-9]+]], +; CHECK-NEXT: %body +; CHECK: %exit + +entry: + br label %body + +body: + %iv = phi i32 [ 0, %entry ], [ %next, %body ] + %base = phi i32 [ 0, %entry ], [ %sum, %body ] + %arrayidx = getelementptr inbounds i32* %a, i32 %iv + %0 = load i32* %arrayidx + %sum = add nsw i32 %0, %base + %next = add i32 %iv, 1 + %exitcond = icmp eq i32 %next, %i + br i1 %exitcond, label %exit, label %body + +exit: + ret i32 %sum +} + +define i32 @test_nested_loop_align(i32 %i, i32* %a, i32* %b) { +; Check that we provide nested loop body alignment. +; CHECK: test_nested_loop_align: +; CHECK: %entry +; CHECK: .align [[ALIGN]], +; CHECK-NEXT: %loop.body.1 +; CHECK: .align [[ALIGN]], +; CHECK-NEXT: %inner.loop.body +; CHECK-NOT: .align +; CHECK: %exit + +entry: + br label %loop.body.1 + +loop.body.1: + %iv = phi i32 [ 0, %entry ], [ %next, %loop.body.2 ] + %arrayidx = getelementptr inbounds i32* %a, i32 %iv + %bidx = load i32* %arrayidx + br label %inner.loop.body + +inner.loop.body: + %inner.iv = phi i32 [ 0, %loop.body.1 ], [ %inner.next, %inner.loop.body ] + %base = phi i32 [ 0, %loop.body.1 ], [ %sum, %inner.loop.body ] + %scaled_idx = mul i32 %bidx, %iv + %inner.arrayidx = getelementptr inbounds i32* %b, i32 %scaled_idx + %0 = load i32* %inner.arrayidx + %sum = add nsw i32 %0, %base + %inner.next = add i32 %iv, 1 + %inner.exitcond = icmp eq i32 %inner.next, %i + br i1 %inner.exitcond, label %loop.body.2, label %inner.loop.body + +loop.body.2: + %next = add i32 %iv, 1 + %exitcond = icmp eq i32 %next, %i + br i1 %exitcond, label %exit, label %loop.body.1 + +exit: + ret i32 %sum +} + +define void @unnatural_cfg1() { +; Test that we can handle a loop with an inner unnatural loop at the end of +; a function. This is a gross CFG reduced out of the single source GCC. +; CHECK: unnatural_cfg1 +; CHECK: %entry +; CHECK: %loop.body1 +; CHECK: %loop.body2 +; CHECK: %loop.body3 + +entry: + br label %loop.header + +loop.header: + br label %loop.body1 + +loop.body1: + br i1 undef, label %loop.body3, label %loop.body2 + +loop.body2: + %ptr = load i32** undef, align 4 + br label %loop.body3 + +loop.body3: + %myptr = phi i32* [ %ptr2, %loop.body5 ], [ %ptr, %loop.body2 ], [ undef, %loop.body1 ] + %bcmyptr = bitcast i32* %myptr to i32* + %val = load i32* %bcmyptr, align 4 + %comp = icmp eq i32 %val, 48 + br i1 %comp, label %loop.body4, label %loop.body5 + +loop.body4: + br i1 undef, label %loop.header, label %loop.body5 + +loop.body5: + %ptr2 = load i32** undef, align 4 + br label %loop.body3 +} + +define void @unnatural_cfg2() { +; Test that we can handle a loop with a nested natural loop *and* an unnatural +; loop. This was reduced from a crash on block placement when run over +; single-source GCC. +; CHECK: unnatural_cfg2 +; CHECK: %entry +; CHECK: %loop.body1 +; CHECK: %loop.body2 +; CHECK: %loop.header +; CHECK: %loop.body3 +; CHECK: %loop.inner1.begin +; The end block is folded with %loop.body3... +; CHECK-NOT: %loop.inner1.end +; CHECK: %loop.body4 +; CHECK: %loop.inner2.begin +; The loop.inner2.end block is folded +; CHECK: %bail + +entry: + br label %loop.header + +loop.header: + %comp0 = icmp eq i32* undef, null + br i1 %comp0, label %bail, label %loop.body1 + +loop.body1: + %val0 = load i32** undef, align 4 + br i1 undef, label %loop.body2, label %loop.inner1.begin + +loop.body2: + br i1 undef, label %loop.body4, label %loop.body3 + +loop.body3: + %ptr1 = getelementptr inbounds i32* %val0, i32 0 + %castptr1 = bitcast i32* %ptr1 to i32** + %val1 = load i32** %castptr1, align 4 + br label %loop.inner1.begin + +loop.inner1.begin: + %valphi = phi i32* [ %val2, %loop.inner1.end ], [ %val1, %loop.body3 ], [ %val0, %loop.body1 ] + %castval = bitcast i32* %valphi to i32* + %comp1 = icmp eq i32 undef, 48 + br i1 %comp1, label %loop.inner1.end, label %loop.body4 + +loop.inner1.end: + %ptr2 = getelementptr inbounds i32* %valphi, i32 0 + %castptr2 = bitcast i32* %ptr2 to i32** + %val2 = load i32** %castptr2, align 4 + br label %loop.inner1.begin + +loop.body4.dead: + br label %loop.body4 + +loop.body4: + %comp2 = icmp ult i32 undef, 3 + br i1 %comp2, label %loop.inner2.begin, label %loop.end + +loop.inner2.begin: + br i1 false, label %loop.end, label %loop.inner2.end + +loop.inner2.end: + %comp3 = icmp eq i32 undef, 1769472 + br i1 %comp3, label %loop.end, label %loop.inner2.begin + +loop.end: + br label %loop.header + +bail: + unreachable +} + +define i32 @problematic_switch() { +; This function's CFG caused overlow in the machine branch probability +; calculation, triggering asserts. Make sure we don't crash on it. +; CHECK: problematic_switch + +entry: + switch i32 undef, label %exit [ + i32 879, label %bogus + i32 877, label %step + i32 876, label %step + i32 875, label %step + i32 874, label %step + i32 873, label %step + i32 872, label %step + i32 868, label %step + i32 867, label %step + i32 866, label %step + i32 861, label %step + i32 860, label %step + i32 856, label %step + i32 855, label %step + i32 854, label %step + i32 831, label %step + i32 830, label %step + i32 829, label %step + i32 828, label %step + i32 815, label %step + i32 814, label %step + i32 811, label %step + i32 806, label %step + i32 805, label %step + i32 804, label %step + i32 803, label %step + i32 802, label %step + i32 801, label %step + i32 800, label %step + i32 799, label %step + i32 798, label %step + i32 797, label %step + i32 796, label %step + i32 795, label %step + ] +bogus: + unreachable +step: + br label %exit +exit: + %merge = phi i32 [ 3, %step ], [ 6, %entry ] + ret i32 %merge +} + +define void @fpcmp_unanalyzable_branch(i1 %cond) { +; This function's CFG contains an unanalyzable branch that is likely to be +; split due to having a different high-probability predecessor. +; CHECK: fpcmp_unanalyzable_branch +; CHECK: %entry +; CHECK: %exit +; CHECK-NOT: %if.then +; CHECK-NOT: %if.end +; CHECK-NOT: jne +; CHECK-NOT: jnp +; CHECK: jne +; CHECK-NEXT: jnp +; CHECK-NEXT: %if.then + +entry: +; Note that this branch must be strongly biased toward +; 'entry.if.then_crit_edge' to ensure that we would try to form a chain for +; 'entry' -> 'entry.if.then_crit_edge' -> 'if.then'. It is the last edge in that +; chain which would violate the unanalyzable branch in 'exit', but we won't even +; try this trick unless 'if.then' is believed to almost always be reached from +; 'entry.if.then_crit_edge'. + br i1 %cond, label %entry.if.then_crit_edge, label %lor.lhs.false, !prof !1 + +entry.if.then_crit_edge: + %.pre14 = load i8* undef, align 1, !tbaa !0 + br label %if.then + +lor.lhs.false: + br i1 undef, label %if.end, label %exit + +exit: + %cmp.i = fcmp une double 0.000000e+00, undef + br i1 %cmp.i, label %if.then, label %if.end + +if.then: + %0 = phi i8 [ %.pre14, %entry.if.then_crit_edge ], [ undef, %exit ] + %1 = and i8 %0, 1 + store i8 %1, i8* undef, align 4, !tbaa !0 + br label %if.end + +if.end: + ret void +} + +!1 = metadata !{metadata !"branch_weights", i32 1000, i32 1} + +declare i32 @f() +declare i32 @g() +declare i32 @h(i32 %x) + +define i32 @test_global_cfg_break_profitability() { +; Check that our metrics for the profitability of a CFG break are global rather +; than local. A successor may be very hot, but if the current block isn't, it +; doesn't matter. Within this test the 'then' block is slightly warmer than the +; 'else' block, but not nearly enough to merit merging it with the exit block +; even though the probability of 'then' branching to the 'exit' block is very +; high. +; CHECK: test_global_cfg_break_profitability +; CHECK: calll {{_?}}f +; CHECK: calll {{_?}}g +; CHECK: calll {{_?}}h +; CHECK: ret + +entry: + br i1 undef, label %then, label %else, !prof !2 + +then: + %then.result = call i32 @f() + br label %exit + +else: + %else.result = call i32 @g() + br label %exit + +exit: + %result = phi i32 [ %then.result, %then ], [ %else.result, %else ] + %result2 = call i32 @h(i32 %result) + ret i32 %result +} + +!2 = metadata !{metadata !"branch_weights", i32 3, i32 1} + +declare i32 @__gxx_personality_v0(...) + +define void @test_eh_lpad_successor() { +; Some times the landing pad ends up as the first successor of an invoke block. +; When this happens, a strange result used to fall out of updateTerminators: we +; didn't correctly locate the fallthrough successor, assuming blindly that the +; first one was the fallthrough successor. As a result, we would add an +; erroneous jump to the landing pad thinking *that* was the default successor. +; CHECK: test_eh_lpad_successor +; CHECK: %entry +; CHECK-NOT: jmp +; CHECK: %loop + +entry: + invoke i32 @f() to label %preheader unwind label %lpad + +preheader: + br label %loop + +lpad: + %lpad.val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + resume { i8*, i32 } %lpad.val + +loop: + br label %loop +} + +declare void @fake_throw() noreturn + +define void @test_eh_throw() { +; For blocks containing a 'throw' (or similar functionality), we have +; a no-return invoke. In this case, only EH successors will exist, and +; fallthrough simply won't occur. Make sure we don't crash trying to update +; terminators for such constructs. +; +; CHECK: test_eh_throw +; CHECK: %entry +; CHECK: %cleanup + +entry: + invoke void @fake_throw() to label %continue unwind label %cleanup + +continue: + unreachable + +cleanup: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + unreachable +} + +define void @test_unnatural_cfg_backwards_inner_loop() { +; Test that when we encounter an unnatural CFG structure after having formed +; a chain for an inner loop which happened to be laid out backwards we don't +; attempt to merge onto the wrong end of the inner loop just because we find it +; first. This was reduced from a crasher in GCC's single source. +; +; CHECK: test_unnatural_cfg_backwards_inner_loop +; CHECK: %entry +; CHECK: %body +; CHECK: %loop2b +; CHECK: %loop1 +; CHECK: %loop2a + +entry: + br i1 undef, label %loop2a, label %body + +body: + br label %loop2a + +loop1: + %next.load = load i32** undef + br i1 %comp.a, label %loop2a, label %loop2b + +loop2a: + %var = phi i32* [ null, %entry ], [ null, %body ], [ %next.phi, %loop1 ] + %next.var = phi i32* [ null, %entry ], [ undef, %body ], [ %next.load, %loop1 ] + %comp.a = icmp eq i32* %var, null + br label %loop3 + +loop2b: + %gep = getelementptr inbounds i32* %var.phi, i32 0 + %next.ptr = bitcast i32* %gep to i32** + store i32* %next.phi, i32** %next.ptr + br label %loop3 + +loop3: + %var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ] + %next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ] + br label %loop1 +} + +define void @unanalyzable_branch_to_loop_header() { +; Ensure that we can handle unanalyzable branches into loop headers. We +; pre-form chains for unanalyzable branches, and will find the tail end of that +; at the start of the loop. This function uses floating point comparison +; fallthrough because that happens to always produce unanalyzable branches on +; x86. +; +; CHECK: unanalyzable_branch_to_loop_header +; CHECK: %entry +; CHECK: %loop +; CHECK: %exit + +entry: + %cmp = fcmp une double 0.000000e+00, undef + br i1 %cmp, label %loop, label %exit + +loop: + %cond = icmp eq i8 undef, 42 + br i1 %cond, label %exit, label %loop + +exit: + ret void +} + +define void @unanalyzable_branch_to_best_succ(i1 %cond) { +; Ensure that we can handle unanalyzable branches where the destination block +; gets selected as the optimal sucessor to merge. +; +; CHECK: unanalyzable_branch_to_best_succ +; CHECK: %entry +; CHECK: %foo +; CHECK: %bar +; CHECK: %exit + +entry: + ; Bias this branch toward bar to ensure we form that chain. + br i1 %cond, label %bar, label %foo, !prof !1 + +foo: + %cmp = fcmp une double 0.000000e+00, undef + br i1 %cmp, label %bar, label %exit + +bar: + call i32 @f() + br label %exit + +exit: + ret void +} + +define void @unanalyzable_branch_to_free_block(float %x) { +; Ensure that we can handle unanalyzable branches where the destination block +; gets selected as the best free block in the CFG. +; +; CHECK: unanalyzable_branch_to_free_block +; CHECK: %entry +; CHECK: %a +; CHECK: %b +; CHECK: %c +; CHECK: %exit + +entry: + br i1 undef, label %a, label %b + +a: + call i32 @f() + br label %c + +b: + %cmp = fcmp une float %x, undef + br i1 %cmp, label %c, label %exit + +c: + call i32 @g() + br label %exit + +exit: + ret void +} + +define void @many_unanalyzable_branches() { +; Ensure that we don't crash as we're building up many unanalyzable branches, +; blocks, and loops. +; +; CHECK: many_unanalyzable_branches +; CHECK: %entry +; CHECK: %exit + +entry: + br label %0 + + %val0 = load volatile float* undef + %cmp0 = fcmp une float %val0, undef + br i1 %cmp0, label %1, label %0 + %val1 = load volatile float* undef + %cmp1 = fcmp une float %val1, undef + br i1 %cmp1, label %2, label %1 + %val2 = load volatile float* undef + %cmp2 = fcmp une float %val2, undef + br i1 %cmp2, label %3, label %2 + %val3 = load volatile float* undef + %cmp3 = fcmp une float %val3, undef + br i1 %cmp3, label %4, label %3 + %val4 = load volatile float* undef + %cmp4 = fcmp une float %val4, undef + br i1 %cmp4, label %5, label %4 + %val5 = load volatile float* undef + %cmp5 = fcmp une float %val5, undef + br i1 %cmp5, label %6, label %5 + %val6 = load volatile float* undef + %cmp6 = fcmp une float %val6, undef + br i1 %cmp6, label %7, label %6 + %val7 = load volatile float* undef + %cmp7 = fcmp une float %val7, undef + br i1 %cmp7, label %8, label %7 + %val8 = load volatile float* undef + %cmp8 = fcmp une float %val8, undef + br i1 %cmp8, label %9, label %8 + %val9 = load volatile float* undef + %cmp9 = fcmp une float %val9, undef + br i1 %cmp9, label %10, label %9 + %val10 = load volatile float* undef + %cmp10 = fcmp une float %val10, undef + br i1 %cmp10, label %11, label %10 + %val11 = load volatile float* undef + %cmp11 = fcmp une float %val11, undef + br i1 %cmp11, label %12, label %11 + %val12 = load volatile float* undef + %cmp12 = fcmp une float %val12, undef + br i1 %cmp12, label %13, label %12 + %val13 = load volatile float* undef + %cmp13 = fcmp une float %val13, undef + br i1 %cmp13, label %14, label %13 + %val14 = load volatile float* undef + %cmp14 = fcmp une float %val14, undef + br i1 %cmp14, label %15, label %14 + %val15 = load volatile float* undef + %cmp15 = fcmp une float %val15, undef + br i1 %cmp15, label %16, label %15 + %val16 = load volatile float* undef + %cmp16 = fcmp une float %val16, undef + br i1 %cmp16, label %17, label %16 + %val17 = load volatile float* undef + %cmp17 = fcmp une float %val17, undef + br i1 %cmp17, label %18, label %17 + %val18 = load volatile float* undef + %cmp18 = fcmp une float %val18, undef + br i1 %cmp18, label %19, label %18 + %val19 = load volatile float* undef + %cmp19 = fcmp une float %val19, undef + br i1 %cmp19, label %20, label %19 + %val20 = load volatile float* undef + %cmp20 = fcmp une float %val20, undef + br i1 %cmp20, label %21, label %20 + %val21 = load volatile float* undef + %cmp21 = fcmp une float %val21, undef + br i1 %cmp21, label %22, label %21 + %val22 = load volatile float* undef + %cmp22 = fcmp une float %val22, undef + br i1 %cmp22, label %23, label %22 + %val23 = load volatile float* undef + %cmp23 = fcmp une float %val23, undef + br i1 %cmp23, label %24, label %23 + %val24 = load volatile float* undef + %cmp24 = fcmp une float %val24, undef + br i1 %cmp24, label %25, label %24 + %val25 = load volatile float* undef + %cmp25 = fcmp une float %val25, undef + br i1 %cmp25, label %26, label %25 + %val26 = load volatile float* undef + %cmp26 = fcmp une float %val26, undef + br i1 %cmp26, label %27, label %26 + %val27 = load volatile float* undef + %cmp27 = fcmp une float %val27, undef + br i1 %cmp27, label %28, label %27 + %val28 = load volatile float* undef + %cmp28 = fcmp une float %val28, undef + br i1 %cmp28, label %29, label %28 + %val29 = load volatile float* undef + %cmp29 = fcmp une float %val29, undef + br i1 %cmp29, label %30, label %29 + %val30 = load volatile float* undef + %cmp30 = fcmp une float %val30, undef + br i1 %cmp30, label %31, label %30 + %val31 = load volatile float* undef + %cmp31 = fcmp une float %val31, undef + br i1 %cmp31, label %32, label %31 + %val32 = load volatile float* undef + %cmp32 = fcmp une float %val32, undef + br i1 %cmp32, label %33, label %32 + %val33 = load volatile float* undef + %cmp33 = fcmp une float %val33, undef + br i1 %cmp33, label %34, label %33 + %val34 = load volatile float* undef + %cmp34 = fcmp une float %val34, undef + br i1 %cmp34, label %35, label %34 + %val35 = load volatile float* undef + %cmp35 = fcmp une float %val35, undef + br i1 %cmp35, label %36, label %35 + %val36 = load volatile float* undef + %cmp36 = fcmp une float %val36, undef + br i1 %cmp36, label %37, label %36 + %val37 = load volatile float* undef + %cmp37 = fcmp une float %val37, undef + br i1 %cmp37, label %38, label %37 + %val38 = load volatile float* undef + %cmp38 = fcmp une float %val38, undef + br i1 %cmp38, label %39, label %38 + %val39 = load volatile float* undef + %cmp39 = fcmp une float %val39, undef + br i1 %cmp39, label %40, label %39 + %val40 = load volatile float* undef + %cmp40 = fcmp une float %val40, undef + br i1 %cmp40, label %41, label %40 + %val41 = load volatile float* undef + %cmp41 = fcmp une float %val41, undef + br i1 %cmp41, label %42, label %41 + %val42 = load volatile float* undef + %cmp42 = fcmp une float %val42, undef + br i1 %cmp42, label %43, label %42 + %val43 = load volatile float* undef + %cmp43 = fcmp une float %val43, undef + br i1 %cmp43, label %44, label %43 + %val44 = load volatile float* undef + %cmp44 = fcmp une float %val44, undef + br i1 %cmp44, label %45, label %44 + %val45 = load volatile float* undef + %cmp45 = fcmp une float %val45, undef + br i1 %cmp45, label %46, label %45 + %val46 = load volatile float* undef + %cmp46 = fcmp une float %val46, undef + br i1 %cmp46, label %47, label %46 + %val47 = load volatile float* undef + %cmp47 = fcmp une float %val47, undef + br i1 %cmp47, label %48, label %47 + %val48 = load volatile float* undef + %cmp48 = fcmp une float %val48, undef + br i1 %cmp48, label %49, label %48 + %val49 = load volatile float* undef + %cmp49 = fcmp une float %val49, undef + br i1 %cmp49, label %50, label %49 + %val50 = load volatile float* undef + %cmp50 = fcmp une float %val50, undef + br i1 %cmp50, label %51, label %50 + %val51 = load volatile float* undef + %cmp51 = fcmp une float %val51, undef + br i1 %cmp51, label %52, label %51 + %val52 = load volatile float* undef + %cmp52 = fcmp une float %val52, undef + br i1 %cmp52, label %53, label %52 + %val53 = load volatile float* undef + %cmp53 = fcmp une float %val53, undef + br i1 %cmp53, label %54, label %53 + %val54 = load volatile float* undef + %cmp54 = fcmp une float %val54, undef + br i1 %cmp54, label %55, label %54 + %val55 = load volatile float* undef + %cmp55 = fcmp une float %val55, undef + br i1 %cmp55, label %56, label %55 + %val56 = load volatile float* undef + %cmp56 = fcmp une float %val56, undef + br i1 %cmp56, label %57, label %56 + %val57 = load volatile float* undef + %cmp57 = fcmp une float %val57, undef + br i1 %cmp57, label %58, label %57 + %val58 = load volatile float* undef + %cmp58 = fcmp une float %val58, undef + br i1 %cmp58, label %59, label %58 + %val59 = load volatile float* undef + %cmp59 = fcmp une float %val59, undef + br i1 %cmp59, label %60, label %59 + %val60 = load volatile float* undef + %cmp60 = fcmp une float %val60, undef + br i1 %cmp60, label %61, label %60 + %val61 = load volatile float* undef + %cmp61 = fcmp une float %val61, undef + br i1 %cmp61, label %62, label %61 + %val62 = load volatile float* undef + %cmp62 = fcmp une float %val62, undef + br i1 %cmp62, label %63, label %62 + %val63 = load volatile float* undef + %cmp63 = fcmp une float %val63, undef + br i1 %cmp63, label %64, label %63 + %val64 = load volatile float* undef + %cmp64 = fcmp une float %val64, undef + br i1 %cmp64, label %65, label %64 + + br label %exit +exit: + ret void +} diff --git a/test/CodeGen/X86/bmi.ll b/test/CodeGen/X86/bmi.ll index 88c09e3..43c47c0 100644 --- a/test/CodeGen/X86/bmi.ll +++ b/test/CodeGen/X86/bmi.ll @@ -1,40 +1,65 @@ -; RUN: llc < %s -march=x86-64 -mattr=+bmi | FileCheck %s +; RUN: llc < %s -march=x86-64 -mattr=+bmi,+bmi2 | FileCheck %s -define i32 @t1(i32 %x) nounwind { - %tmp = tail call i32 @llvm.cttz.i32( i32 %x ) - ret i32 %tmp +declare i8 @llvm.cttz.i8(i8, i1) nounwind readnone +declare i16 @llvm.cttz.i16(i16, i1) nounwind readnone +declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone +declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone + +define i8 @t1(i8 %x) nounwind { + %tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 false ) + ret i8 %tmp ; CHECK: t1: ; CHECK: tzcntl } -declare i32 @llvm.cttz.i32(i32) nounwind readnone - define i16 @t2(i16 %x) nounwind { - %tmp = tail call i16 @llvm.cttz.i16( i16 %x ) - ret i16 %tmp + %tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 false ) + ret i16 %tmp ; CHECK: t2: ; CHECK: tzcntw } -declare i16 @llvm.cttz.i16(i16) nounwind readnone - -define i64 @t3(i64 %x) nounwind { - %tmp = tail call i64 @llvm.cttz.i64( i64 %x ) - ret i64 %tmp +define i32 @t3(i32 %x) nounwind { + %tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 false ) + ret i32 %tmp ; CHECK: t3: +; CHECK: tzcntl +} + +define i64 @t4(i64 %x) nounwind { + %tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 false ) + ret i64 %tmp +; CHECK: t4: ; CHECK: tzcntq } -declare i64 @llvm.cttz.i64(i64) nounwind readnone +define i8 @t5(i8 %x) nounwind { + %tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 true ) + ret i8 %tmp +; CHECK: t5: +; CHECK: tzcntl +} -define i8 @t4(i8 %x) nounwind { - %tmp = tail call i8 @llvm.cttz.i8( i8 %x ) - ret i8 %tmp -; CHECK: t4: +define i16 @t6(i16 %x) nounwind { + %tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 true ) + ret i16 %tmp +; CHECK: t6: ; CHECK: tzcntw } -declare i8 @llvm.cttz.i8(i8) nounwind readnone +define i32 @t7(i32 %x) nounwind { + %tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 true ) + ret i32 %tmp +; CHECK: t7: +; CHECK: tzcntl +} + +define i64 @t8(i64 %x) nounwind { + %tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 true ) + ret i64 %tmp +; CHECK: t8: +; CHECK: tzcntq +} define i32 @andn32(i32 %x, i32 %y) nounwind readnone { %tmp1 = xor i32 %x, -1 @@ -51,3 +76,124 @@ define i64 @andn64(i64 %x, i64 %y) nounwind readnone { ; CHECK: andn64: ; CHECK: andnq } + +define i32 @bextr32(i32 %x, i32 %y) nounwind readnone { + %tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y) + ret i32 %tmp +; CHECK: bextr32: +; CHECK: bextrl +} + +declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone + +define i64 @bextr64(i64 %x, i64 %y) nounwind readnone { + %tmp = tail call i64 @llvm.x86.bmi.bextr.64(i64 %x, i64 %y) + ret i64 %tmp +; CHECK: bextr64: +; CHECK: bextrq +} + +declare i64 @llvm.x86.bmi.bextr.64(i64, i64) nounwind readnone + +define i32 @bzhi32(i32 %x, i32 %y) nounwind readnone { + %tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x, i32 %y) + ret i32 %tmp +; CHECK: bzhi32: +; CHECK: bzhil +} + +declare i32 @llvm.x86.bmi.bzhi.32(i32, i32) nounwind readnone + +define i64 @bzhi64(i64 %x, i64 %y) nounwind readnone { + %tmp = tail call i64 @llvm.x86.bmi.bzhi.64(i64 %x, i64 %y) + ret i64 %tmp +; CHECK: bzhi64: +; CHECK: bzhiq +} + +declare i64 @llvm.x86.bmi.bzhi.64(i64, i64) nounwind readnone + +define i32 @blsi32(i32 %x) nounwind readnone { + %tmp = sub i32 0, %x + %tmp2 = and i32 %x, %tmp + ret i32 %tmp2 +; CHECK: blsi32: +; CHECK: blsil +} + +define i64 @blsi64(i64 %x) nounwind readnone { + %tmp = sub i64 0, %x + %tmp2 = and i64 %tmp, %x + ret i64 %tmp2 +; CHECK: blsi64: +; CHECK: blsiq +} + +define i32 @blsmsk32(i32 %x) nounwind readnone { + %tmp = sub i32 %x, 1 + %tmp2 = xor i32 %x, %tmp + ret i32 %tmp2 +; CHECK: blsmsk32: +; CHECK: blsmskl +} + +define i64 @blsmsk64(i64 %x) nounwind readnone { + %tmp = sub i64 %x, 1 + %tmp2 = xor i64 %tmp, %x + ret i64 %tmp2 +; CHECK: blsmsk64: +; CHECK: blsmskq +} + +define i32 @blsr32(i32 %x) nounwind readnone { + %tmp = sub i32 %x, 1 + %tmp2 = and i32 %x, %tmp + ret i32 %tmp2 +; CHECK: blsr32: +; CHECK: blsrl +} + +define i64 @blsr64(i64 %x) nounwind readnone { + %tmp = sub i64 %x, 1 + %tmp2 = and i64 %tmp, %x + ret i64 %tmp2 +; CHECK: blsr64: +; CHECK: blsrq +} + +define i32 @pdep32(i32 %x, i32 %y) nounwind readnone { + %tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y) + ret i32 %tmp +; CHECK: pdep32: +; CHECK: pdepl +} + +declare i32 @llvm.x86.bmi.pdep.32(i32, i32) nounwind readnone + +define i64 @pdep64(i64 %x, i64 %y) nounwind readnone { + %tmp = tail call i64 @llvm.x86.bmi.pdep.64(i64 %x, i64 %y) + ret i64 %tmp +; CHECK: pdep64: +; CHECK: pdepq +} + +declare i64 @llvm.x86.bmi.pdep.64(i64, i64) nounwind readnone + +define i32 @pext32(i32 %x, i32 %y) nounwind readnone { + %tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y) + ret i32 %tmp +; CHECK: pext32: +; CHECK: pextl +} + +declare i32 @llvm.x86.bmi.pext.32(i32, i32) nounwind readnone + +define i64 @pext64(i64 %x, i64 %y) nounwind readnone { + %tmp = tail call i64 @llvm.x86.bmi.pext.64(i64 %x, i64 %y) + ret i64 %tmp +; CHECK: pext64: +; CHECK: pextq +} + +declare i64 @llvm.x86.bmi.pext.64(i64, i64) nounwind readnone + diff --git a/test/CodeGen/X86/brcond.ll b/test/CodeGen/X86/brcond.ll index 5cdc100..44670c8 100644 --- a/test/CodeGen/X86/brcond.ll +++ b/test/CodeGen/X86/brcond.ll @@ -1,4 +1,5 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin10 -mcpu=core2 | FileCheck %s +; RUN: llc < %s -mtriple=i386-apple-darwin10 -mcpu=penryn | FileCheck %s + ; rdar://7475489 define i32 @test1(i32 %a, i32 %b) nounwind ssp { @@ -106,3 +107,4 @@ bb2: ; preds = %entry, %bb1 %.0 = fptrunc double %.0.in to float ; <float> [#uses=1] ret float %.0 } + diff --git a/test/CodeGen/X86/btq.ll b/test/CodeGen/X86/btq.ll new file mode 100644 index 0000000..9c137a7 --- /dev/null +++ b/test/CodeGen/X86/btq.ll @@ -0,0 +1,35 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +declare void @bar() + +define void @test1(i64 %foo) nounwind { + %and = and i64 %foo, 4294967296 + %tobool = icmp eq i64 %and, 0 + br i1 %tobool, label %if.end, label %if.then + +; CHECK: test1: +; CHECK: btq $32 + +if.then: + tail call void @bar() nounwind + br label %if.end + +if.end: + ret void +} + +define void @test2(i64 %foo) nounwind { + %and = and i64 %foo, 2147483648 + %tobool = icmp eq i64 %and, 0 + br i1 %tobool, label %if.end, label %if.then + +; CHECK: test2: +; CHECK: testl $-2147483648 + +if.then: + tail call void @bar() nounwind + br label %if.end + +if.end: + ret void +} diff --git a/test/CodeGen/X86/byval6.ll b/test/CodeGen/X86/byval6.ll index b060369..2d39901 100644 --- a/test/CodeGen/X86/byval6.ll +++ b/test/CodeGen/X86/byval6.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 | grep add | not grep 16 +; RUN: llc < %s -mcpu=generic -march=x86 | grep add | not grep 16 %struct.W = type { x86_fp80, x86_fp80 } @B = global %struct.W { x86_fp80 0xK4001A000000000000000, x86_fp80 0xK4001C000000000000000 }, align 32 diff --git a/test/CodeGen/X86/cfstring.ll b/test/CodeGen/X86/cfstring.ll new file mode 100644 index 0000000..7420ce7 --- /dev/null +++ b/test/CodeGen/X86/cfstring.ll @@ -0,0 +1,36 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s +; <rdar://problem/10564621> + +%0 = type opaque +%struct.NSConstantString = type { i32*, i32, i8*, i32 } + +; Make sure that the string ends up the the correct section. + +; CHECK: .section __TEXT,__cstring +; CHECK-NEXT: l_.str3: + +; CHECK: .section __DATA,__cfstring +; CHECK-NEXT: .align 4 +; CHECK-NEXT: L__unnamed_cfstring_4: +; CHECK-NEXT: .quad ___CFConstantStringClassReference +; CHECK-NEXT: .long 1992 +; CHECK-NEXT: .space 4 +; CHECK-NEXT: .quad l_.str3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .space 4 + +@isLogVisible = global i8 0, align 1 +@__CFConstantStringClassReference = external global [0 x i32] +@.str3 = linker_private unnamed_addr constant [1 x i8] zeroinitializer, align 1 +@_unnamed_cfstring_4 = private constant %struct.NSConstantString { i32* getelementptr inbounds ([0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([1 x i8]* @.str3, i32 0, i32 0), i32 0 }, section "__DATA,__cfstring" +@null.array = weak_odr constant [1 x i8] zeroinitializer, align 1 + +define linkonce_odr void @bar() nounwind ssp align 2 { +entry: + %stack = alloca i8*, align 4 + %call = call %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %0* (i8*, i8*, %0*)*)(i8* null, i8* null, %0* bitcast (%struct.NSConstantString* @_unnamed_cfstring_4 to %0*)) + store i8* getelementptr inbounds ([1 x i8]* @null.array, i32 0, i32 0), i8** %stack, align 4 + ret void +} + +declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind diff --git a/test/CodeGen/X86/change-compare-stride-0.ll b/test/CodeGen/X86/change-compare-stride-0.ll deleted file mode 100644 index 439f7b0..0000000 --- a/test/CodeGen/X86/change-compare-stride-0.ll +++ /dev/null @@ -1,83 +0,0 @@ -; RUN: llc < %s -march=x86 -enable-lsr-nested | FileCheck %s -; -; Nested LSR is required to optimize this case. -; We do not expect to see this form of IR without -enable-iv-rewrite. - -define void @borf(i8* nocapture %in, i8* nocapture %out) nounwind { -; CHECK: borf: -; CHECK-NOT: inc -; CHECK-NOT: leal 1( -; CHECK-NOT: leal -1( -; CHECK: decl -; CHECK-NEXT: cmpl $-478 -; CHECK: ret - -bb4.thread: - br label %bb2.outer - -bb2.outer: ; preds = %bb4, %bb4.thread - %indvar18 = phi i32 [ 0, %bb4.thread ], [ %indvar.next28, %bb4 ] ; <i32> [#uses=3] - %tmp34 = mul i32 %indvar18, 65535 ; <i32> [#uses=1] - %i.0.reg2mem.0.ph = add i32 %tmp34, 639 ; <i32> [#uses=1] - %0 = and i32 %i.0.reg2mem.0.ph, 65535 ; <i32> [#uses=1] - %1 = mul i32 %0, 480 ; <i32> [#uses=1] - %tmp20 = mul i32 %indvar18, -478 ; <i32> [#uses=1] - br label %bb2 - -bb2: ; preds = %bb2, %bb2.outer - %indvar = phi i32 [ 0, %bb2.outer ], [ %indvar.next, %bb2 ] ; <i32> [#uses=3] - %ctg2 = getelementptr i8* %out, i32 %tmp20 ; <i8*> [#uses=1] - %tmp21 = ptrtoint i8* %ctg2 to i32 ; <i32> [#uses=1] - %tmp23 = sub i32 %tmp21, %indvar ; <i32> [#uses=1] - %out_addr.0.reg2mem.0 = inttoptr i32 %tmp23 to i8* ; <i8*> [#uses=1] - %tmp25 = mul i32 %indvar, 65535 ; <i32> [#uses=1] - %j.0.reg2mem.0 = add i32 %tmp25, 479 ; <i32> [#uses=1] - %2 = and i32 %j.0.reg2mem.0, 65535 ; <i32> [#uses=1] - %3 = add i32 %1, %2 ; <i32> [#uses=9] - %4 = add i32 %3, -481 ; <i32> [#uses=1] - %5 = getelementptr i8* %in, i32 %4 ; <i8*> [#uses=1] - %6 = load i8* %5, align 1 ; <i8> [#uses=1] - %7 = add i32 %3, -480 ; <i32> [#uses=1] - %8 = getelementptr i8* %in, i32 %7 ; <i8*> [#uses=1] - %9 = load i8* %8, align 1 ; <i8> [#uses=1] - %10 = add i32 %3, -479 ; <i32> [#uses=1] - %11 = getelementptr i8* %in, i32 %10 ; <i8*> [#uses=1] - %12 = load i8* %11, align 1 ; <i8> [#uses=1] - %13 = add i32 %3, -1 ; <i32> [#uses=1] - %14 = getelementptr i8* %in, i32 %13 ; <i8*> [#uses=1] - %15 = load i8* %14, align 1 ; <i8> [#uses=1] - %16 = getelementptr i8* %in, i32 %3 ; <i8*> [#uses=1] - %17 = load i8* %16, align 1 ; <i8> [#uses=1] - %18 = add i32 %3, 1 ; <i32> [#uses=1] - %19 = getelementptr i8* %in, i32 %18 ; <i8*> [#uses=1] - %20 = load i8* %19, align 1 ; <i8> [#uses=1] - %21 = add i32 %3, 481 ; <i32> [#uses=1] - %22 = getelementptr i8* %in, i32 %21 ; <i8*> [#uses=1] - %23 = load i8* %22, align 1 ; <i8> [#uses=1] - %24 = add i32 %3, 480 ; <i32> [#uses=1] - %25 = getelementptr i8* %in, i32 %24 ; <i8*> [#uses=1] - %26 = load i8* %25, align 1 ; <i8> [#uses=1] - %27 = add i32 %3, 479 ; <i32> [#uses=1] - %28 = getelementptr i8* %in, i32 %27 ; <i8*> [#uses=1] - %29 = load i8* %28, align 1 ; <i8> [#uses=1] - %30 = add i8 %9, %6 ; <i8> [#uses=1] - %31 = add i8 %30, %12 ; <i8> [#uses=1] - %32 = add i8 %31, %15 ; <i8> [#uses=1] - %33 = add i8 %32, %17 ; <i8> [#uses=1] - %34 = add i8 %33, %20 ; <i8> [#uses=1] - %35 = add i8 %34, %23 ; <i8> [#uses=1] - %36 = add i8 %35, %26 ; <i8> [#uses=1] - %37 = add i8 %36, %29 ; <i8> [#uses=1] - store i8 %37, i8* %out_addr.0.reg2mem.0, align 1 - %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2] - %exitcond = icmp eq i32 %indvar.next, 478 ; <i1> [#uses=1] - br i1 %exitcond, label %bb4, label %bb2 - -bb4: ; preds = %bb2 - %indvar.next28 = add i32 %indvar18, 1 ; <i32> [#uses=2] - %exitcond29 = icmp eq i32 %indvar.next28, 638 ; <i1> [#uses=1] - br i1 %exitcond29, label %return, label %bb2.outer - -return: ; preds = %bb4 - ret void -} diff --git a/test/CodeGen/X86/change-compare-stride-1.ll b/test/CodeGen/X86/change-compare-stride-1.ll index 8b53ae2..1c5c113 100644 --- a/test/CodeGen/X86/change-compare-stride-1.ll +++ b/test/CodeGen/X86/change-compare-stride-1.ll @@ -3,6 +3,10 @@ ; Nested LSR is required to optimize this case. ; We do not expect to see this form of IR without -enable-iv-rewrite. +; xfailed for now because the scheduler two-address hack has been disabled. +; Now it's generating a leal -1 rather than a decq. +; XFAIL: * + define void @borf(i8* nocapture %in, i8* nocapture %out) nounwind { ; CHECK: borf: ; CHECK-NOT: inc diff --git a/test/CodeGen/X86/clz.ll b/test/CodeGen/X86/clz.ll index d76fab4..763079f 100644 --- a/test/CodeGen/X86/clz.ll +++ b/test/CodeGen/X86/clz.ll @@ -1,48 +1,141 @@ -; RUN: llc < %s -march=x86 -mcpu=yonah | FileCheck %s +; RUN: llc < %s -march=x86-64 -mcpu=yonah | FileCheck %s -define i32 @t1(i32 %x) nounwind { - %tmp = tail call i32 @llvm.ctlz.i32( i32 %x ) - ret i32 %tmp -; CHECK: t1: -; CHECK: bsrl -; CHECK: cmov +declare i8 @llvm.cttz.i8(i8, i1) +declare i16 @llvm.cttz.i16(i16, i1) +declare i32 @llvm.cttz.i32(i32, i1) +declare i64 @llvm.cttz.i64(i64, i1) +declare i8 @llvm.ctlz.i8(i8, i1) +declare i16 @llvm.ctlz.i16(i16, i1) +declare i32 @llvm.ctlz.i32(i32, i1) +declare i64 @llvm.ctlz.i64(i64, i1) + +define i8 @cttz_i8(i8 %x) { + %tmp = call i8 @llvm.cttz.i8( i8 %x, i1 true ) + ret i8 %tmp +; CHECK: cttz_i8: +; CHECK: bsfl +; CHECK-NOT: cmov +; CHECK: ret } -declare i32 @llvm.ctlz.i32(i32) nounwind readnone +define i16 @cttz_i16(i16 %x) { + %tmp = call i16 @llvm.cttz.i16( i16 %x, i1 true ) + ret i16 %tmp +; CHECK: cttz_i16: +; CHECK: bsfw +; CHECK-NOT: cmov +; CHECK: ret +} -define i32 @t2(i32 %x) nounwind { - %tmp = tail call i32 @llvm.cttz.i32( i32 %x ) - ret i32 %tmp -; CHECK: t2: +define i32 @cttz_i32(i32 %x) { + %tmp = call i32 @llvm.cttz.i32( i32 %x, i1 true ) + ret i32 %tmp +; CHECK: cttz_i32: ; CHECK: bsfl -; CHECK: cmov +; CHECK-NOT: cmov +; CHECK: ret +} + +define i64 @cttz_i64(i64 %x) { + %tmp = call i64 @llvm.cttz.i64( i64 %x, i1 true ) + ret i64 %tmp +; CHECK: cttz_i64: +; CHECK: bsfq +; CHECK-NOT: cmov +; CHECK: ret } -declare i32 @llvm.cttz.i32(i32) nounwind readnone +define i8 @ctlz_i8(i8 %x) { +entry: + %tmp2 = call i8 @llvm.ctlz.i8( i8 %x, i1 true ) + ret i8 %tmp2 +; CHECK: ctlz_i8: +; CHECK: bsrl +; CHECK-NOT: cmov +; CHECK: xorl $7, +; CHECK: ret +} -define i16 @t3(i16 %x, i16 %y) nounwind { +define i16 @ctlz_i16(i16 %x) { entry: - %tmp1 = add i16 %x, %y - %tmp2 = tail call i16 @llvm.ctlz.i16( i16 %tmp1 ) ; <i16> [#uses=1] - ret i16 %tmp2 -; CHECK: t3: + %tmp2 = call i16 @llvm.ctlz.i16( i16 %x, i1 true ) + ret i16 %tmp2 +; CHECK: ctlz_i16: ; CHECK: bsrw -; CHECK: cmov +; CHECK-NOT: cmov +; CHECK: xorl $15, +; CHECK: ret +} + +define i32 @ctlz_i32(i32 %x) { + %tmp = call i32 @llvm.ctlz.i32( i32 %x, i1 true ) + ret i32 %tmp +; CHECK: ctlz_i32: +; CHECK: bsrl +; CHECK-NOT: cmov +; CHECK: xorl $31, +; CHECK: ret +} + +define i64 @ctlz_i64(i64 %x) { + %tmp = call i64 @llvm.ctlz.i64( i64 %x, i1 true ) + ret i64 %tmp +; CHECK: ctlz_i64: +; CHECK: bsrq +; CHECK-NOT: cmov +; CHECK: xorq $63, +; CHECK: ret } -declare i16 @llvm.ctlz.i16(i16) nounwind readnone +define i32 @ctlz_i32_cmov(i32 %n) { +entry: +; Generate a cmov to handle zero inputs when necessary. +; CHECK: ctlz_i32_cmov: +; CHECK: bsrl +; CHECK: cmov +; CHECK: xorl $31, +; CHECK: ret + %tmp1 = call i32 @llvm.ctlz.i32(i32 %n, i1 false) + ret i32 %tmp1 +} +define i32 @ctlz_i32_fold_cmov(i32 %n) { +entry: ; Don't generate the cmovne when the source is known non-zero (and bsr would ; not set ZF). ; rdar://9490949 - -define i32 @t4(i32 %n) nounwind { -entry: -; CHECK: t4: +; CHECK: ctlz_i32_fold_cmov: ; CHECK: bsrl ; CHECK-NOT: cmov +; CHECK: xorl $31, ; CHECK: ret %or = or i32 %n, 1 - %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %or) + %tmp1 = call i32 @llvm.ctlz.i32(i32 %or, i1 false) ret i32 %tmp1 } + +define i32 @ctlz_bsr(i32 %n) { +entry: +; Don't generate any xors when a 'ctlz' intrinsic is actually used to compute +; the most significant bit, which is what 'bsr' does natively. +; CHECK: ctlz_bsr: +; CHECK: bsrl +; CHECK-NOT: xorl +; CHECK: ret + %ctlz = call i32 @llvm.ctlz.i32(i32 %n, i1 true) + %bsr = xor i32 %ctlz, 31 + ret i32 %bsr +} + +define i32 @ctlz_bsr_cmov(i32 %n) { +entry: +; Same as ctlz_bsr, but ensure this happens even when there is a potential +; zero. +; CHECK: ctlz_bsr_cmov: +; CHECK: bsrl +; CHECK-NOT: xorl +; CHECK: ret + %ctlz = call i32 @llvm.ctlz.i32(i32 %n, i1 false) + %bsr = xor i32 %ctlz, 31 + ret i32 %bsr +} diff --git a/test/CodeGen/X86/cmov.ll b/test/CodeGen/X86/cmov.ll index 7a8d6e6..2e7ffbf 100644 --- a/test/CodeGen/X86/cmov.ll +++ b/test/CodeGen/X86/cmov.ll @@ -84,7 +84,7 @@ entry: br i1 %3, label %func_4.exit.i, label %bb.i.i.i bb.i.i.i: ; preds = %entry - %4 = volatile load i8* @g_100, align 1 ; <i8> [#uses=0] + %4 = load volatile i8* @g_100, align 1 ; <i8> [#uses=0] br label %func_4.exit.i ; CHECK: test4: @@ -101,7 +101,7 @@ func_4.exit.i: ; preds = %bb.i.i.i, %entry br i1 %brmerge.i, label %func_1.exit, label %bb.i.i bb.i.i: ; preds = %func_4.exit.i - %5 = volatile load i8* @g_100, align 1 ; <i8> [#uses=0] + %5 = load volatile i8* @g_100, align 1 ; <i8> [#uses=0] br label %func_1.exit func_1.exit: ; preds = %bb.i.i, %func_4.exit.i diff --git a/test/CodeGen/X86/cmpxchg16b.ll b/test/CodeGen/X86/cmpxchg16b.ll index ba1c4ef..edbd0bc 100644 --- a/test/CodeGen/X86/cmpxchg16b.ll +++ b/test/CodeGen/X86/cmpxchg16b.ll @@ -3,7 +3,7 @@ ; Basic 128-bit cmpxchg define void @t1(i128* nocapture %p) nounwind ssp { entry: -; CHECK movl $1, %ebx +; CHECK: movl $1, %ebx ; CHECK: lock ; CHECK-NEXT: cmpxchg16b %r = cmpxchg i128* %p, i128 0, i128 1 seq_cst diff --git a/test/CodeGen/X86/coalescer-commute1.ll b/test/CodeGen/X86/coalescer-commute1.ll index 8aa0bfd..d9e0778 100644 --- a/test/CodeGen/X86/coalescer-commute1.ll +++ b/test/CodeGen/X86/coalescer-commute1.ll @@ -21,6 +21,6 @@ bb: ; preds = %bb, %entry br i1 %exitcond, label %bb13, label %bb bb13: ; preds = %bb - volatile store float %tmp6, float* @G, align 4 + store volatile float %tmp6, float* @G, align 4 ret void } diff --git a/test/CodeGen/X86/crash.ll b/test/CodeGen/X86/crash.ll index 1531457..cf6e27d 100644 --- a/test/CodeGen/X86/crash.ll +++ b/test/CodeGen/X86/crash.ll @@ -6,16 +6,16 @@ ; Chain and flag folding issues. define i32 @test1() nounwind ssp { entry: - %tmp5.i = volatile load i32* undef ; <i32> [#uses=1] + %tmp5.i = load volatile i32* undef ; <i32> [#uses=1] %conv.i = zext i32 %tmp5.i to i64 ; <i64> [#uses=1] - %tmp12.i = volatile load i32* undef ; <i32> [#uses=1] + %tmp12.i = load volatile i32* undef ; <i32> [#uses=1] %conv13.i = zext i32 %tmp12.i to i64 ; <i64> [#uses=1] %shl.i = shl i64 %conv13.i, 32 ; <i64> [#uses=1] %or.i = or i64 %shl.i, %conv.i ; <i64> [#uses=1] %add16.i = add i64 %or.i, 256 ; <i64> [#uses=1] %shr.i = lshr i64 %add16.i, 8 ; <i64> [#uses=1] %conv19.i = trunc i64 %shr.i to i32 ; <i32> [#uses=1] - volatile store i32 %conv19.i, i32* undef + store volatile i32 %conv19.i, i32* undef ret i32 undef } diff --git a/test/CodeGen/X86/dbg-file-name.ll b/test/CodeGen/X86/dbg-file-name.ll index 3a849aa..adf9854 100644 --- a/test/CodeGen/X86/dbg-file-name.ll +++ b/test/CodeGen/X86/dbg-file-name.ll @@ -1,7 +1,7 @@ -; RUN: llc -mtriple x86_64-apple-darwin10.0.0 < %s | FileCheck %s +; RUN: llc -enable-dwarf-directory -mtriple x86_64-apple-darwin10.0.0 < %s | FileCheck %s ; Radar 8884898 -; CHECK: file 1 "/Users/manav/one/two{{/|\\\\}}simple.c" +; CHECK: file 1 "simple.c" declare i32 @printf(i8*, ...) nounwind diff --git a/test/CodeGen/X86/dbg-inline.ll b/test/CodeGen/X86/dbg-inline.ll deleted file mode 100644 index 523c62e..0000000 --- a/test/CodeGen/X86/dbg-inline.ll +++ /dev/null @@ -1,140 +0,0 @@ -; RUN: llc < %s | FileCheck %s -; Radar 7881628, 9747970 -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" -target triple = "x86_64-apple-macosx10.7.0" - -%class.APFloat = type { i32 } - -define i32 @_ZNK7APFloat9partCountEv(%class.APFloat* nocapture %this) nounwind uwtable readonly optsize ssp align 2 { -entry: - tail call void @llvm.dbg.value(metadata !{%class.APFloat* %this}, i64 0, metadata !28), !dbg !41 - %prec = getelementptr inbounds %class.APFloat* %this, i64 0, i32 0, !dbg !42 - %tmp = load i32* %prec, align 4, !dbg !42, !tbaa !44 - tail call void @llvm.dbg.value(metadata !{i32 %tmp}, i64 0, metadata !47), !dbg !48 - %add.i = add i32 %tmp, 42, !dbg !49 - ret i32 %add.i, !dbg !42 -} - -define zeroext i1 @_ZNK7APFloat14bitwiseIsEqualERKS_(%class.APFloat* %this, %class.APFloat* %rhs) uwtable optsize ssp align 2 { -entry: - tail call void @llvm.dbg.value(metadata !{%class.APFloat* %this}, i64 0, metadata !29), !dbg !51 - tail call void @llvm.dbg.value(metadata !{%class.APFloat* %rhs}, i64 0, metadata !30), !dbg !52 - tail call void @llvm.dbg.value(metadata !{%class.APFloat* %this}, i64 0, metadata !53), !dbg !55 - %prec.i = getelementptr inbounds %class.APFloat* %this, i64 0, i32 0, !dbg !56 -;CHECK: DW_TAG_inlined_subroutine -;CHECK: DW_AT_abstract_origin -;CHECK: DW_AT_ranges - %tmp.i = load i32* %prec.i, align 4, !dbg !56, !tbaa !44 - tail call void @llvm.dbg.value(metadata !{i32 %tmp.i}, i64 0, metadata !57), !dbg !58 - %add.i.i = add i32 %tmp.i, 42, !dbg !59 - tail call void @llvm.dbg.value(metadata !{i32 %add.i.i}, i64 0, metadata !31), !dbg !54 - %call2 = tail call i64* @_ZNK7APFloat16significandPartsEv(%class.APFloat* %this) optsize, !dbg !60 - tail call void @llvm.dbg.value(metadata !{i64* %call2}, i64 0, metadata !34), !dbg !60 - %call3 = tail call i64* @_ZNK7APFloat16significandPartsEv(%class.APFloat* %rhs) optsize, !dbg !61 - tail call void @llvm.dbg.value(metadata !{i64* %call3}, i64 0, metadata !37), !dbg !61 - %tmp = zext i32 %add.i.i to i64 - br label %for.cond, !dbg !62 - -for.cond: ; preds = %for.inc, %entry - %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] - %tmp13 = sub i64 %tmp, %indvar, !dbg !62 - %i.0 = trunc i64 %tmp13 to i32, !dbg !62 - %cmp = icmp sgt i32 %i.0, 0, !dbg !62 - br i1 %cmp, label %for.body, label %return, !dbg !62 - -for.body: ; preds = %for.cond - %p.0 = getelementptr i64* %call2, i64 %indvar, !dbg !63 - %tmp6 = load i64* %p.0, align 8, !dbg !63, !tbaa !66 - %tmp8 = load i64* %call3, align 8, !dbg !63, !tbaa !66 - %cmp9 = icmp eq i64 %tmp6, %tmp8, !dbg !63 - br i1 %cmp9, label %for.inc, label %return, !dbg !63 - -for.inc: ; preds = %for.body - %indvar.next = add i64 %indvar, 1, !dbg !67 - br label %for.cond, !dbg !67 - -return: ; preds = %for.cond, %for.body - %retval.0 = phi i1 [ false, %for.body ], [ true, %for.cond ] - ret i1 %retval.0, !dbg !68 -} - -declare i64* @_ZNK7APFloat16significandPartsEv(%class.APFloat*) optsize - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.cu = !{!0} -!llvm.dbg.sp = !{!1, !7, !12, !23, !24, !25} -!llvm.dbg.lv._ZNK7APFloat9partCountEv = !{!28} -!llvm.dbg.lv._ZNK7APFloat14bitwiseIsEqualERKS_ = !{!29, !30, !31, !34, !37} -!llvm.dbg.lv._ZL16partCountForBitsj = !{!38} -!llvm.dbg.gv = !{!39} - -!0 = metadata !{i32 655377, i32 0, i32 4, metadata !"/Volumes/Athwagate/R9747970/apf.cc", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 136149)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!1 = metadata !{i32 655406, i32 0, metadata !2, metadata !"bitwiseIsEqual", metadata !"bitwiseIsEqual", metadata !"_ZNK7APFloat14bitwiseIsEqualERKS_", metadata !3, i32 8, metadata !19, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null} ; [ DW_TAG_subprogram ] -!2 = metadata !{i32 655362, metadata !0, metadata !"APFloat", metadata !3, i32 6, i64 32, i64 32, i32 0, i32 0, null, metadata !4, i32 0, null, null} ; [ DW_TAG_class_type ] -!3 = metadata !{i32 655401, metadata !"/Volumes/Athwagate/R9747970/apf.cc", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] -!4 = metadata !{metadata !5, metadata !1, metadata !7, metadata !12} -!5 = metadata !{i32 655373, metadata !2, metadata !"prec", metadata !3, i32 13, i64 32, i64 32, i64 0, i32 0, metadata !6} ; [ DW_TAG_member ] -!6 = metadata !{i32 655396, metadata !0, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!7 = metadata !{i32 655406, i32 0, metadata !2, metadata !"partCount", metadata !"partCount", metadata !"_ZNK7APFloat9partCountEv", metadata !3, i32 9, metadata !8, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null} ; [ DW_TAG_subprogram ] -!8 = metadata !{i32 655381, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !9, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] -!9 = metadata !{metadata !6, metadata !10} -!10 = metadata !{i32 655375, metadata !0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !11} ; [ DW_TAG_pointer_type ] -!11 = metadata !{i32 655398, metadata !0, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !2} ; [ DW_TAG_const_type ] -!12 = metadata !{i32 655406, i32 0, metadata !2, metadata !"significandParts", metadata !"significandParts", metadata !"_ZNK7APFloat16significandPartsEv", metadata !3, i32 11, metadata !13, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null} ; [ DW_TAG_subprogram ] -!13 = metadata !{i32 655381, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !14, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] -!14 = metadata !{metadata !15, metadata !10} -!15 = metadata !{i32 655375, metadata !0, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !16} ; [ DW_TAG_pointer_type ] -!16 = metadata !{i32 655382, metadata !0, metadata !"integerPart", metadata !3, i32 2, i64 0, i64 0, i64 0, i32 0, metadata !17} ; [ DW_TAG_typedef ] -!17 = metadata !{i32 655382, metadata !0, metadata !"uint64_t", metadata !3, i32 1, i64 0, i64 0, i64 0, i32 0, metadata !18} ; [ DW_TAG_typedef ] -!18 = metadata !{i32 655396, metadata !0, metadata !"long long unsigned int", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] -!19 = metadata !{i32 655381, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !20, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] -!20 = metadata !{metadata !21, metadata !10, metadata !22} -!21 = metadata !{i32 655396, metadata !0, metadata !"bool", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 2} ; [ DW_TAG_base_type ] -!22 = metadata !{i32 655376, metadata !0, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_reference_type ] -!23 = metadata !{i32 655406, i32 0, metadata !0, metadata !"partCount", metadata !"partCount", metadata !"_ZNK7APFloat9partCountEv", metadata !3, i32 23, metadata !8, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (%class.APFloat*)* @_ZNK7APFloat9partCountEv, null, metadata !7} ; [ DW_TAG_subprogram ] -!24 = metadata !{i32 655406, i32 0, metadata !0, metadata !"bitwiseIsEqual", metadata !"bitwiseIsEqual", metadata !"_ZNK7APFloat14bitwiseIsEqualERKS_", metadata !3, i32 28, metadata !19, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i1 (%class.APFloat*, %class.APFloat*)* @_ZNK7APFloat14bitwiseIsEqualERKS_, null, metadata !1} ; [ DW_TAG_subprogram ] -!25 = metadata !{i32 655406, i32 0, metadata !3, metadata !"partCountForBits", metadata !"partCountForBits", metadata !"", metadata !3, i32 17, metadata !26, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, null, null, null} ; [ DW_TAG_subprogram ] -!26 = metadata !{i32 655381, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !27, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] -!27 = metadata !{metadata !6} -!28 = metadata !{i32 655617, metadata !23, metadata !"this", metadata !3, i32 16777238, metadata !10, i32 64, i32 0} ; [ DW_TAG_arg_variable ] -!29 = metadata !{i32 655617, metadata !24, metadata !"this", metadata !3, i32 16777244, metadata !10, i32 64, i32 0} ; [ DW_TAG_arg_variable ] -!30 = metadata !{i32 655617, metadata !24, metadata !"rhs", metadata !3, i32 33554460, metadata !22, i32 0, i32 0} ; [ DW_TAG_arg_variable ] -!31 = metadata !{i32 655616, metadata !32, metadata !"i", metadata !3, i32 29, metadata !33, i32 0, i32 0} ; [ DW_TAG_auto_variable ] -!32 = metadata !{i32 655371, metadata !24, i32 28, i32 56, metadata !3, i32 1} ; [ DW_TAG_lexical_block ] -!33 = metadata !{i32 655396, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!34 = metadata !{i32 655616, metadata !32, metadata !"p", metadata !3, i32 30, metadata !35, i32 0, i32 0} ; [ DW_TAG_auto_variable ] -!35 = metadata !{i32 655375, metadata !0, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !36} ; [ DW_TAG_pointer_type ] -!36 = metadata !{i32 655398, metadata !0, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !16} ; [ DW_TAG_const_type ] -!37 = metadata !{i32 655616, metadata !32, metadata !"q", metadata !3, i32 31, metadata !35, i32 0, i32 0} ; [ DW_TAG_auto_variable ] -!38 = metadata !{i32 655617, metadata !25, metadata !"bits", metadata !3, i32 16777232, metadata !6, i32 0, i32 0} ; [ DW_TAG_arg_variable ] -!39 = metadata !{i32 655412, i32 0, metadata !3, metadata !"integerPartWidth", metadata !"integerPartWidth", metadata !"integerPartWidth", metadata !3, i32 3, metadata !40, i32 1, i32 1, i32 42} ; [ DW_TAG_variable ] -!40 = metadata !{i32 655398, metadata !0, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !6} ; [ DW_TAG_const_type ] -!41 = metadata !{i32 22, i32 23, metadata !23, null} -!42 = metadata !{i32 24, i32 10, metadata !43, null} -!43 = metadata !{i32 655371, metadata !23, i32 23, i32 1, metadata !3, i32 0} ; [ DW_TAG_lexical_block ] -!44 = metadata !{metadata !"int", metadata !45} -!45 = metadata !{metadata !"omnipotent char", metadata !46} -!46 = metadata !{metadata !"Simple C/C++ TBAA", null} -!47 = metadata !{i32 655617, metadata !25, metadata !"bits", metadata !3, i32 16777232, metadata !6, i32 0, metadata !42} ; [ DW_TAG_arg_variable ] -!48 = metadata !{i32 16, i32 58, metadata !25, metadata !42} -!49 = metadata !{i32 18, i32 3, metadata !50, metadata !42} -!50 = metadata !{i32 655371, metadata !25, i32 17, i32 1, metadata !3, i32 4} ; [ DW_TAG_lexical_block ] -!51 = metadata !{i32 28, i32 15, metadata !24, null} -!52 = metadata !{i32 28, i32 45, metadata !24, null} -!53 = metadata !{i32 655617, metadata !23, metadata !"this", metadata !3, i32 16777238, metadata !10, i32 64, metadata !54} ; [ DW_TAG_arg_variable ] -!54 = metadata !{i32 29, i32 10, metadata !32, null} -!55 = metadata !{i32 22, i32 23, metadata !23, metadata !54} -!56 = metadata !{i32 24, i32 10, metadata !43, metadata !54} -!57 = metadata !{i32 655617, metadata !25, metadata !"bits", metadata !3, i32 16777232, metadata !6, i32 0, metadata !56} ; [ DW_TAG_arg_variable ] -!58 = metadata !{i32 16, i32 58, metadata !25, metadata !56} -!59 = metadata !{i32 18, i32 3, metadata !50, metadata !56} -!60 = metadata !{i32 30, i32 24, metadata !32, null} -!61 = metadata !{i32 31, i32 24, metadata !32, null} -!62 = metadata !{i32 32, i32 3, metadata !32, null} -!63 = metadata !{i32 33, i32 5, metadata !64, null} -!64 = metadata !{i32 655371, metadata !65, i32 32, i32 25, metadata !3, i32 3} ; [ DW_TAG_lexical_block ] -!65 = metadata !{i32 655371, metadata !32, i32 32, i32 3, metadata !3, i32 2} ; [ DW_TAG_lexical_block ] -!66 = metadata !{metadata !"long long", metadata !45} -!67 = metadata !{i32 32, i32 15, metadata !65, null} -!68 = metadata !{i32 37, i32 1, metadata !32, null} diff --git a/test/CodeGen/X86/dbg-merge-loc-entry.ll b/test/CodeGen/X86/dbg-merge-loc-entry.ll index afe1729..c35935f 100644 --- a/test/CodeGen/X86/dbg-merge-loc-entry.ll +++ b/test/CodeGen/X86/dbg-merge-loc-entry.ll @@ -10,7 +10,7 @@ target triple = "x86_64-apple-darwin8" ;CHECK-NEXT: .short Lset ;CHECK-NEXT: Ltmp ;CHECK-NEXT: .byte 85 ## DW_OP_reg5 -;CHECK-NEXT: Ltmp7 +;CHECK-NEXT: Ltmp5 ;CHECK-NEXT: .quad 0 ;CHECK-NEXT: .quad 0 diff --git a/test/CodeGen/X86/dbg-subrange.ll b/test/CodeGen/X86/dbg-subrange.ll new file mode 100644 index 0000000..788910c --- /dev/null +++ b/test/CodeGen/X86/dbg-subrange.ll @@ -0,0 +1,37 @@ +; RUN: llc -O0 < %s | FileCheck %s +; Radar 10464995 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7.2" + +@s = common global [4294967296 x i8] zeroinitializer, align 16 +;CHECK: .long 4294967295 + +define void @bar() nounwind uwtable ssp { +entry: + store i8 97, i8* getelementptr inbounds ([4294967296 x i8]* @s, i32 0, i64 0), align 1, !dbg !18 + ret void, !dbg !20 +} + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 720913, i32 0, i32 12, metadata !"small.c", metadata !"/private/tmp", metadata !"clang version 3.1 (trunk 144833)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !11} ; [ DW_TAG_compile_unit ] +!1 = metadata !{metadata !2} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{metadata !5} +!5 = metadata !{i32 720942, i32 0, metadata !6, metadata !"bar", metadata !"bar", metadata !"", metadata !6, i32 4, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void ()* @bar, null, null, metadata !9} ; [ DW_TAG_subprogram ] +!6 = metadata !{i32 720937, metadata !"small.c", metadata !"/private/tmp", null} ; [ DW_TAG_file_type ] +!7 = metadata !{i32 720917, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!8 = metadata !{null} +!9 = metadata !{metadata !10} +!10 = metadata !{i32 720932} ; [ DW_TAG_base_type ] +!11 = metadata !{metadata !12} +!12 = metadata !{metadata !13} +!13 = metadata !{i32 720948, i32 0, null, metadata !"s", metadata !"s", metadata !"", metadata !6, i32 2, metadata !14, i32 0, i32 1, [4294967296 x i8]* @s} ; [ DW_TAG_variable ] +!14 = metadata !{i32 720897, null, metadata !"", null, i32 0, i64 34359738368, i64 8, i32 0, i32 0, metadata !15, metadata !16, i32 0, i32 0} ; [ DW_TAG_array_type ] +!15 = metadata !{i32 720932, null, metadata !"char", null, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!16 = metadata !{metadata !17} +!17 = metadata !{i32 720929, i64 0, i64 4294967295} ; [ DW_TAG_subrange_type ] +!18 = metadata !{i32 5, i32 3, metadata !19, null} +!19 = metadata !{i32 720907, metadata !5, i32 4, i32 1, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] +!20 = metadata !{i32 6, i32 1, metadata !19, null} diff --git a/test/CodeGen/X86/dbg-value-inlined-parameter.ll b/test/CodeGen/X86/dbg-value-inlined-parameter.ll index 481c4ba..d248a41 100644 --- a/test/CodeGen/X86/dbg-value-inlined-parameter.ll +++ b/test/CodeGen/X86/dbg-value-inlined-parameter.ll @@ -8,7 +8,7 @@ ;CHECK-NEXT: DW_AT_call_file ;CHECK-NEXT: DW_AT_call_line ;CHECK-NEXT: DW_TAG_formal_parameter -;CHECK-NEXT: .ascii "sp" ## DW_AT_name +;CHECK-NEXT: Lstring11-Lsection_str ## DW_AT_name %struct.S1 = type { float*, i32 } diff --git a/test/CodeGen/X86/dbg-value-location.ll b/test/CodeGen/X86/dbg-value-location.ll index a0e4d16..05e29ec 100644 --- a/test/CodeGen/X86/dbg-value-location.ll +++ b/test/CodeGen/X86/dbg-value-location.ll @@ -4,8 +4,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 target triple = "x86_64-apple-darwin10.0.0" ;Radar 8950491 -;CHECK: .ascii "var" ## DW_AT_name -;CHECK-NEXT: .byte 0 +;CHECK: .long Lset5 ;CHECK-NEXT: ## DW_AT_decl_file ;CHECK-NEXT: ## DW_AT_decl_line ;CHECK-NEXT: ## DW_AT_type diff --git a/test/CodeGen/X86/dg.exp b/test/CodeGen/X86/dg.exp deleted file mode 100644 index 629a147..0000000 --- a/test/CodeGen/X86/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if { [llvm_supports_target X86] } { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] -} diff --git a/test/CodeGen/X86/divide-by-constant.ll b/test/CodeGen/X86/divide-by-constant.ll index 87c1be5..e577ecb 100644 --- a/test/CodeGen/X86/divide-by-constant.ll +++ b/test/CodeGen/X86/divide-by-constant.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=i686-pc-linux-gnu -asm-verbose=0 | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=i686-pc-linux-gnu -asm-verbose=0 | FileCheck %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" target triple = "i686-pc-linux-gnu" diff --git a/test/CodeGen/X86/dwarf-comp-dir.ll b/test/CodeGen/X86/dwarf-comp-dir.ll new file mode 100644 index 0000000..c64752c --- /dev/null +++ b/test/CodeGen/X86/dwarf-comp-dir.ll @@ -0,0 +1,16 @@ +; RUN: llc %s -o %t -filetype=obj +; RUN: llvm-dwarfdump %t | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 720913, i32 0, i32 12, metadata !"empty.c", metadata !"/home/nlewycky", metadata !"clang version 3.1 (trunk 143523)", i1 true, i1 true, metadata !"", i32 0, metadata !1, metadata !1, metadata !1, metadata !1} ; [ DW_TAG_compile_unit ] +!1 = metadata !{metadata !2} +!2 = metadata !{i32 0} + +; The important part of the following check is that dir = #0. +; Dir Mod Time File Len File Name +; ---- ---------- ---------- --------------------------- +; CHECK: file_names[ 1] 0 0x00000000 0x00000000 empty.c diff --git a/test/CodeGen/X86/empty-functions.ll b/test/CodeGen/X86/empty-functions.ll index 874c53a..ac5174d 100644 --- a/test/CodeGen/X86/empty-functions.ll +++ b/test/CodeGen/X86/empty-functions.ll @@ -6,14 +6,11 @@ entry: unreachable } ; CHECK-NO-FP: _func: -; CHECK-NO-FP-NEXT: : ; CHECK-NO-FP-NEXT: .cfi_startproc ; CHECK-NO-FP: nop -; CHECK-NO-FP-NEXT: : ; CHECK-NO-FP-NEXT: .cfi_endproc ; CHECK-FP: _func: -; CHECK-FP-NEXT: : ; CHECK-FP-NEXT: .cfi_startproc ; CHECK-FP-NEXT: : ; CHECK-FP-NEXT: pushq %rbp @@ -25,5 +22,4 @@ entry: ; CHECK-FP-NEXT: : ; CHECK-FP-NEXT: .cfi_def_cfa_register %rbp ; CHECK-FP-NEXT: nop -; CHECK-FP-NEXT: : ; CHECK-FP-NEXT: .cfi_endproc diff --git a/test/CodeGen/X86/epilogue.ll b/test/CodeGen/X86/epilogue.ll index 52dcb61..0f16a64 100644 --- a/test/CodeGen/X86/epilogue.ll +++ b/test/CodeGen/X86/epilogue.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -march=x86 | not grep lea -; RUN: llc < %s -march=x86 | grep {movl %ebp} +; RUN: llc < %s -mcpu=generic -march=x86 | not grep lea +; RUN: llc < %s -mcpu=generic -march=x86 | grep {movl %ebp} declare void @bar(<2 x i64>* %n) diff --git a/test/CodeGen/X86/f16c-intrinsics.ll b/test/CodeGen/X86/f16c-intrinsics.ll new file mode 100644 index 0000000..2135f94 --- /dev/null +++ b/test/CodeGen/X86/f16c-intrinsics.ll @@ -0,0 +1,32 @@ +; RUN: llc < %s -march=x86 -mattr=+avx,+f16c | FileCheck %s + +define <4 x float> @test_x86_vcvtph2ps_128(<8 x i16> %a0) { + ; CHECK: vcvtph2ps + %res = call <4 x float> @llvm.x86.vcvtph2ps.128(<8 x i16> %a0) ; <<4 x float>> [#uses=1] + ret <4 x float> %res +} +declare <4 x float> @llvm.x86.vcvtph2ps.128(<8 x i16>) nounwind readonly + + +define <8 x float> @test_x86_vcvtph2ps_256(<8 x i16> %a0) { + ; CHECK: vcvtph2ps + %res = call <8 x float> @llvm.x86.vcvtph2ps.256(<8 x i16> %a0) ; <<8 x float>> [#uses=1] + ret <8 x float> %res +} +declare <8 x float> @llvm.x86.vcvtph2ps.256(<8 x i16>) nounwind readonly + + +define <8 x i16> @test_x86_vcvtps2ph_128(<4 x float> %a0) { + ; CHECK: vcvtps2ph + %res = call <8 x i16> @llvm.x86.vcvtps2ph.128(<4 x float> %a0, i32 0) ; <<8 x i16>> [#uses=1] + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.vcvtps2ph.128(<4 x float>, i32) nounwind readonly + + +define <8 x i16> @test_x86_vcvtps2ph_256(<8 x float> %a0) { + ; CHECK: vcvtps2ph + %res = call <8 x i16> @llvm.x86.vcvtps2ph.256(<8 x float> %a0, i32 0) ; <<8 x i16>> [#uses=1] + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.vcvtps2ph.256(<8 x float>, i32) nounwind readonly diff --git a/test/CodeGen/X86/fast-cc-merge-stack-adj.ll b/test/CodeGen/X86/fast-cc-merge-stack-adj.ll index e151821..e4982f0 100644 --- a/test/CodeGen/X86/fast-cc-merge-stack-adj.ll +++ b/test/CodeGen/X86/fast-cc-merge-stack-adj.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | \ +; RUN: llc < %s -mcpu=generic -march=x86 -x86-asm-syntax=intel | \ ; RUN: grep {add ESP, 8} target triple = "i686-pc-linux-gnu" diff --git a/test/CodeGen/X86/fast-isel-bc.ll b/test/CodeGen/X86/fast-isel-bc.ll index 4abc3b5..8ac15cd 100644 --- a/test/CodeGen/X86/fast-isel-bc.ll +++ b/test/CodeGen/X86/fast-isel-bc.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -O0 -regalloc=linearscan -march=x86-64 -mattr=+mmx,+sse2 | FileCheck %s +; RUN: llc < %s -O0 -march=x86-64 -mattr=+mmx,+sse2 | FileCheck %s ; PR4684 target datalayout = diff --git a/test/CodeGen/X86/fast-isel-gep.ll b/test/CodeGen/X86/fast-isel-gep.ll index 91d1f5d..f0375f8 100644 --- a/test/CodeGen/X86/fast-isel-gep.ll +++ b/test/CodeGen/X86/fast-isel-gep.ll @@ -82,9 +82,8 @@ define i64 @test5(i8* %A, i32 %I, i64 %B) nounwind { ret i64 %v11 ; X64: test5: ; X64: movslq %e[[A1]], %rax -; X64-NEXT: movq (%r[[A0]],%rax), %rax -; X64-NEXT: addq %{{rdx|r8}}, %rax -; X64-NEXT: ret +; X64-NEXT: (%r[[A0]],%rax), +; X64: ret } ; PR9500, rdar://9156159 - Don't do non-local address mode folding, diff --git a/test/CodeGen/X86/fast-isel-x86-64.ll b/test/CodeGen/X86/fast-isel-x86-64.ll index 6a5a102..d8f4663 100644 --- a/test/CodeGen/X86/fast-isel-x86-64.ll +++ b/test/CodeGen/X86/fast-isel-x86-64.ll @@ -82,7 +82,7 @@ entry: ret i64 %mul ; CHECK: test6: -; CHECK: leaq (,%rdi,8), %rax +; CHECK: shlq $3, %rdi } define i32 @test7(i32 %x) nounwind ssp { @@ -90,7 +90,7 @@ entry: %mul = mul nsw i32 %x, 8 ret i32 %mul ; CHECK: test7: -; CHECK: leal (,%rdi,8), %eax +; CHECK: shll $3, %edi } @@ -225,18 +225,20 @@ if.else: ; preds = %entry ; CHECK-NEXT: je } -; Check that 0.0 is materialized using pxor +; Check that 0.0 is materialized using xorps define void @test18(float* %p1) { store float 0.0, float* %p1 ret void ; CHECK: test18: -; CHECK: pxor +; CHECK: xorps } + +; Without any type hints, doubles use the smaller xorps instead of xorpd. define void @test19(double* %p1) { store double 0.0, double* %p1 ret void ; CHECK: test19: -; CHECK: pxor +; CHECK: xorps } ; Check that we fast-isel sret @@ -252,12 +254,12 @@ entry: } declare void @test20sret(%struct.a* sret) -; Check that -0.0 is not materialized using pxor +; Check that -0.0 is not materialized using xor define void @test21(double* %p1) { store double -0.0, double* %p1 ret void ; CHECK: test21: -; CHECK-NOT: pxor +; CHECK-NOT: xor ; CHECK: movsd LCPI } diff --git a/test/CodeGen/X86/fast-isel-x86.ll b/test/CodeGen/X86/fast-isel-x86.ll index 19972f7..b9598bb 100644 --- a/test/CodeGen/X86/fast-isel-x86.ll +++ b/test/CodeGen/X86/fast-isel-x86.ll @@ -1,4 +1,4 @@ -; RUN: llc -fast-isel -O0 -mtriple=i386-apple-darwin10 -relocation-model=pic < %s | FileCheck %s +; RUN: llc -fast-isel -O0 -mcpu=generic -mtriple=i386-apple-darwin10 -relocation-model=pic < %s | FileCheck %s ; This should use flds to set the return value. ; CHECK: test0: diff --git a/test/CodeGen/X86/fast-isel.ll b/test/CodeGen/X86/fast-isel.ll index 8391860..c88d529 100644 --- a/test/CodeGen/X86/fast-isel.ll +++ b/test/CodeGen/X86/fast-isel.ll @@ -99,7 +99,6 @@ define void @load_store_i1(i1* %p, i1* %q) nounwind { ret void } - @crash_test1x = external global <2 x i32>, align 8 define void @crash_test1() nounwind ssp { @@ -108,3 +107,13 @@ define void @crash_test1() nounwind ssp { ret void } +declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind + +define i64* @life() nounwind { + %a1 = alloca i64*, align 8 + %a2 = bitcast i64** %a1 to i8* + call void @llvm.lifetime.start(i64 -1, i8* %a2) nounwind + %a3 = load i64** %a1, align 8 + ret i64* %a3 +} + diff --git a/test/CodeGen/X86/fdiv.ll b/test/CodeGen/X86/fdiv.ll new file mode 100644 index 0000000..0749682 --- /dev/null +++ b/test/CodeGen/X86/fdiv.ll @@ -0,0 +1,41 @@ +; RUN: llc < %s -march=x86-64 -enable-unsafe-fp-math | FileCheck %s + +define double @exact(double %x) { +; Exact division by a constant converted to multiplication. +; CHECK: @exact +; CHECK: mulsd + %div = fdiv double %x, 2.0 + ret double %div +} + +define double @inexact(double %x) { +; Inexact division by a constant converted to multiplication. +; CHECK: @inexact +; CHECK: mulsd + %div = fdiv double %x, 0x41DFFFFFFFC00000 + ret double %div +} + +define double @funky(double %x) { +; No conversion to multiplication if too funky. +; CHECK: @funky +; CHECK: divsd + %div = fdiv double %x, 0.0 + ret double %div +} + +define double @denormal1(double %x) { +; Don't generate multiplication by a denormal. +; CHECK: @denormal1 +; CHECK: divsd + %div = fdiv double %x, 0x7FD0000000000001 + ret double %div +} + +define double @denormal2(double %x) { +; Don't generate multiplication by a denormal. +; CHECK: @denormal +; CHECK: divsd + %div = fdiv double %x, 0x7FEFFFFFFFFFFFFF + ret double %div +} diff --git a/test/CodeGen/X86/fltused.ll b/test/CodeGen/X86/fltused.ll index 2ffcb96..81511a3 100644 --- a/test/CodeGen/X86/fltused.ll +++ b/test/CodeGen/X86/fltused.ll @@ -4,6 +4,8 @@ ; RUN: llc < %s -mtriple i686-pc-win32 | FileCheck %s --check-prefix WIN32 ; RUN: llc < %s -mtriple x86_64-pc-win32 | FileCheck %s --check-prefix WIN64 +; RUN: llc < %s -O0 -mtriple i686-pc-win32 | FileCheck %s --check-prefix WIN32 +; RUN: llc < %s -O0 -mtriple x86_64-pc-win32 | FileCheck %s --check-prefix WIN64 @.str = private constant [4 x i8] c"%f\0A\00" diff --git a/test/CodeGen/X86/fltused_function_pointer.ll b/test/CodeGen/X86/fltused_function_pointer.ll new file mode 100644 index 0000000..cfe484a --- /dev/null +++ b/test/CodeGen/X86/fltused_function_pointer.ll @@ -0,0 +1,19 @@ +; The purpose of this test to to verify that the fltused symbol is emitted when +; any function is called with floating point arguments on Windows. And that it +; is not emitted otherwise. + +; RUN: llc < %s -mtriple i686-pc-win32 | FileCheck %s --check-prefix WIN32 +; RUN: llc < %s -mtriple x86_64-pc-win32 | FileCheck %s --check-prefix WIN64 +; RUN: llc < %s -O0 -mtriple i686-pc-win32 | FileCheck %s --check-prefix WIN32 +; RUN: llc < %s -O0 -mtriple x86_64-pc-win32 | FileCheck %s --check-prefix WIN64 + +@.str = private constant [4 x i8] c"%f\0A\00" + +define i32 @foo(i32 (i8*, ...)* %f) nounwind { +entry: + %call = tail call i32 (i8*, ...)* %f(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double 1.000000e+000) nounwind + ret i32 0 +} + +; WIN32: .globl __fltused +; WIN64: .globl _fltused diff --git a/test/CodeGen/X86/fma4-intrinsics-x86_64.ll b/test/CodeGen/X86/fma4-intrinsics-x86_64.ll new file mode 100644 index 0000000..5ed03ef --- /dev/null +++ b/test/CodeGen/X86/fma4-intrinsics-x86_64.ll @@ -0,0 +1,295 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -march=x86-64 -mattr=+avx,+fma4 | FileCheck %s + +; VFMADD +define < 4 x float > @test_x86_fma4_vfmadd_ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfmaddss + %res = call < 4 x float > @llvm.x86.fma4.vfmadd.ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +define < 4 x float > @test_x86_fma4_vfmadd_ss_load(< 4 x float > %a0, < 4 x float > %a1, float* %a2) { + ; CHECK: vfmaddss (%{{.*}}) + %x = load float *%a2 + %y = insertelement <4 x float> undef, float %x, i32 0 + %res = call < 4 x float > @llvm.x86.fma4.vfmadd.ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %y) ; <i64> [#uses=1] + ret < 4 x float > %res +} +define < 4 x float > @test_x86_fma4_vfmadd_ss_load2(< 4 x float > %a0, float* %a1, < 4 x float > %a2) { + ; CHECK: vfmaddss %{{.*}}, (%{{.*}}) + %x = load float *%a1 + %y = insertelement <4 x float> undef, float %x, i32 0 + %res = call < 4 x float > @llvm.x86.fma4.vfmadd.ss(< 4 x float > %a0, < 4 x float > %y, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfmadd.ss(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfmadd_sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfmaddsd + %res = call < 2 x double > @llvm.x86.fma4.vfmadd.sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +define < 2 x double > @test_x86_fma4_vfmadd_sd_load(< 2 x double > %a0, < 2 x double > %a1, double* %a2) { + ; CHECK: vfmaddsd (%{{.*}}) + %x = load double *%a2 + %y = insertelement <2 x double> undef, double %x, i32 0 + %res = call < 2 x double > @llvm.x86.fma4.vfmadd.sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %y) ; <i64> [#uses=1] + ret < 2 x double > %res +} +define < 2 x double > @test_x86_fma4_vfmadd_sd_load2(< 2 x double > %a0, double* %a1, < 2 x double > %a2) { + ; CHECK: vfmaddsd %{{.*}}, (%{{.*}}) + %x = load double *%a1 + %y = insertelement <2 x double> undef, double %x, i32 0 + %res = call < 2 x double > @llvm.x86.fma4.vfmadd.sd(< 2 x double > %a0, < 2 x double > %y, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfmadd.sd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 4 x float > @test_x86_fma4_vfmadd_ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfmaddps + %res = call < 4 x float > @llvm.x86.fma4.vfmadd.ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +define < 4 x float > @test_x86_fma4_vfmadd_ps_load(< 4 x float > %a0, < 4 x float > %a1, < 4 x float >* %a2) { + ; CHECK: vfmaddps (%{{.*}}) + %x = load <4 x float>* %a2 + %res = call < 4 x float > @llvm.x86.fma4.vfmadd.ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %x) ; <i64> [#uses=1] + ret < 4 x float > %res +} +define < 4 x float > @test_x86_fma4_vfmadd_ps_load2(< 4 x float > %a0, < 4 x float >* %a1, < 4 x float > %a2) { + ; CHECK: vfmaddps %{{.*}}, (%{{.*}}) + %x = load <4 x float>* %a1 + %res = call < 4 x float > @llvm.x86.fma4.vfmadd.ps(< 4 x float > %a0, < 4 x float > %x, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfmadd.ps(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfmadd_pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfmaddpd + %res = call < 2 x double > @llvm.x86.fma4.vfmadd.pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +define < 2 x double > @test_x86_fma4_vfmadd_pd_load(< 2 x double > %a0, < 2 x double > %a1, < 2 x double >* %a2) { + ; CHECK: vfmaddpd (%{{.*}}) + %x = load <2 x double>* %a2 + %res = call < 2 x double > @llvm.x86.fma4.vfmadd.pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %x) ; <i64> [#uses=1] + ret < 2 x double > %res +} +define < 2 x double > @test_x86_fma4_vfmadd_pd_load2(< 2 x double > %a0, < 2 x double >* %a1, < 2 x double > %a2) { + ; CHECK: vfmaddpd %{{.*}}, (%{{.*}}) + %x = load <2 x double>* %a1 + %res = call < 2 x double > @llvm.x86.fma4.vfmadd.pd(< 2 x double > %a0, < 2 x double > %x, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfmadd.pd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 8 x float > @test_x86_fma4_vfmadd_ps_256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) { + ; CHECK: vfmaddps + ; CHECK: ymm + %res = call < 8 x float > @llvm.x86.fma4.vfmadd.ps.256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) ; <i64> [#uses=1] + ret < 8 x float > %res +} +declare < 8 x float > @llvm.x86.fma4.vfmadd.ps.256(< 8 x float >, < 8 x float >, < 8 x float >) nounwind readnone + +define < 4 x double > @test_x86_fma4_vfmadd_pd_256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) { + ; CHECK: vfmaddpd + ; CHECK: ymm + %res = call < 4 x double > @llvm.x86.fma4.vfmadd.pd.256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) ; <i64> [#uses=1] + ret < 4 x double > %res +} +declare < 4 x double > @llvm.x86.fma4.vfmadd.pd.256(< 4 x double >, < 4 x double >, < 4 x double >) nounwind readnone + +; VFMSUB +define < 4 x float > @test_x86_fma4_vfmsub_ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfmsubss + %res = call < 4 x float > @llvm.x86.fma4.vfmsub.ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfmsub.ss(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfmsub_sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfmsubsd + %res = call < 2 x double > @llvm.x86.fma4.vfmsub.sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfmsub.sd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 4 x float > @test_x86_fma4_vfmsub_ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfmsubps + %res = call < 4 x float > @llvm.x86.fma4.vfmsub.ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfmsub.ps(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfmsub_pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfmsubpd + %res = call < 2 x double > @llvm.x86.fma4.vfmsub.pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfmsub.pd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 8 x float > @test_x86_fma4_vfmsub_ps_256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) { + ; CHECK: vfmsubps + ; CHECK: ymm + %res = call < 8 x float > @llvm.x86.fma4.vfmsub.ps.256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) ; <i64> [#uses=1] + ret < 8 x float > %res +} +declare < 8 x float > @llvm.x86.fma4.vfmsub.ps.256(< 8 x float >, < 8 x float >, < 8 x float >) nounwind readnone + +define < 4 x double > @test_x86_fma4_vfmsub_pd_256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) { + ; CHECK: vfmsubpd + ; CHECK: ymm + %res = call < 4 x double > @llvm.x86.fma4.vfmsub.pd.256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) ; <i64> [#uses=1] + ret < 4 x double > %res +} +declare < 4 x double > @llvm.x86.fma4.vfmsub.pd.256(< 4 x double >, < 4 x double >, < 4 x double >) nounwind readnone + +; VFNMADD +define < 4 x float > @test_x86_fma4_vfnmadd_ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfnmaddss + %res = call < 4 x float > @llvm.x86.fma4.vfnmadd.ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfnmadd.ss(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfnmadd_sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfnmaddsd + %res = call < 2 x double > @llvm.x86.fma4.vfnmadd.sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfnmadd.sd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 4 x float > @test_x86_fma4_vfnmadd_ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfnmaddps + %res = call < 4 x float > @llvm.x86.fma4.vfnmadd.ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfnmadd.ps(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfnmadd_pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfnmaddpd + %res = call < 2 x double > @llvm.x86.fma4.vfnmadd.pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfnmadd.pd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 8 x float > @test_x86_fma4_vfnmadd_ps_256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) { + ; CHECK: vfnmaddps + ; CHECK: ymm + %res = call < 8 x float > @llvm.x86.fma4.vfnmadd.ps.256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) ; <i64> [#uses=1] + ret < 8 x float > %res +} +declare < 8 x float > @llvm.x86.fma4.vfnmadd.ps.256(< 8 x float >, < 8 x float >, < 8 x float >) nounwind readnone + +define < 4 x double > @test_x86_fma4_vfnmadd_pd_256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) { + ; CHECK: vfnmaddpd + ; CHECK: ymm + %res = call < 4 x double > @llvm.x86.fma4.vfnmadd.pd.256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) ; <i64> [#uses=1] + ret < 4 x double > %res +} +declare < 4 x double > @llvm.x86.fma4.vfnmadd.pd.256(< 4 x double >, < 4 x double >, < 4 x double >) nounwind readnone + +; VFNMSUB +define < 4 x float > @test_x86_fma4_vfnmsub_ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfnmsubss + %res = call < 4 x float > @llvm.x86.fma4.vfnmsub.ss(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfnmsub.ss(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfnmsub_sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfnmsubsd + %res = call < 2 x double > @llvm.x86.fma4.vfnmsub.sd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfnmsub.sd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 4 x float > @test_x86_fma4_vfnmsub_ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfnmsubps + %res = call < 4 x float > @llvm.x86.fma4.vfnmsub.ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfnmsub.ps(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfnmsub_pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfnmsubpd + %res = call < 2 x double > @llvm.x86.fma4.vfnmsub.pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfnmsub.pd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 8 x float > @test_x86_fma4_vfnmsub_ps_256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) { + ; CHECK: vfnmsubps + ; CHECK: ymm + %res = call < 8 x float > @llvm.x86.fma4.vfnmsub.ps.256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) ; <i64> [#uses=1] + ret < 8 x float > %res +} +declare < 8 x float > @llvm.x86.fma4.vfnmsub.ps.256(< 8 x float >, < 8 x float >, < 8 x float >) nounwind readnone + +define < 4 x double > @test_x86_fma4_vfnmsub_pd_256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) { + ; CHECK: vfnmsubpd + ; CHECK: ymm + %res = call < 4 x double > @llvm.x86.fma4.vfnmsub.pd.256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) ; <i64> [#uses=1] + ret < 4 x double > %res +} +declare < 4 x double > @llvm.x86.fma4.vfnmsub.pd.256(< 4 x double >, < 4 x double >, < 4 x double >) nounwind readnone + +; VFMADDSUB +define < 4 x float > @test_x86_fma4_vfmaddsub_ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfmaddsubps + %res = call < 4 x float > @llvm.x86.fma4.vfmaddsub.ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfmaddsub.ps(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfmaddsub_pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfmaddsubpd + %res = call < 2 x double > @llvm.x86.fma4.vfmaddsub.pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfmaddsub.pd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 8 x float > @test_x86_fma4_vfmaddsub_ps_256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) { + ; CHECK: vfmaddsubps + ; CHECK: ymm + %res = call < 8 x float > @llvm.x86.fma4.vfmaddsub.ps.256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) ; <i64> [#uses=1] + ret < 8 x float > %res +} +declare < 8 x float > @llvm.x86.fma4.vfmaddsub.ps.256(< 8 x float >, < 8 x float >, < 8 x float >) nounwind readnone + +define < 4 x double > @test_x86_fma4_vfmaddsub_pd_256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) { + ; CHECK: vfmaddsubpd + ; CHECK: ymm + %res = call < 4 x double > @llvm.x86.fma4.vfmaddsub.pd.256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) ; <i64> [#uses=1] + ret < 4 x double > %res +} +declare < 4 x double > @llvm.x86.fma4.vfmaddsub.pd.256(< 4 x double >, < 4 x double >, < 4 x double >) nounwind readnone + +; VFMSUBADD +define < 4 x float > @test_x86_fma4_vfmsubadd_ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) { + ; CHECK: vfmsubaddps + %res = call < 4 x float > @llvm.x86.fma4.vfmsubadd.ps(< 4 x float > %a0, < 4 x float > %a1, < 4 x float > %a2) ; <i64> [#uses=1] + ret < 4 x float > %res +} +declare < 4 x float > @llvm.x86.fma4.vfmsubadd.ps(< 4 x float >, < 4 x float >, < 4 x float >) nounwind readnone + +define < 2 x double > @test_x86_fma4_vfmsubadd_pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) { + ; CHECK: vfmsubaddpd + %res = call < 2 x double > @llvm.x86.fma4.vfmsubadd.pd(< 2 x double > %a0, < 2 x double > %a1, < 2 x double > %a2) ; <i64> [#uses=1] + ret < 2 x double > %res +} +declare < 2 x double > @llvm.x86.fma4.vfmsubadd.pd(< 2 x double >, < 2 x double >, < 2 x double >) nounwind readnone + +define < 8 x float > @test_x86_fma4_vfmsubadd_ps_256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) { + ; CHECK: vfmsubaddps + ; CHECK: ymm + %res = call < 8 x float > @llvm.x86.fma4.vfmsubadd.ps.256(< 8 x float > %a0, < 8 x float > %a1, < 8 x float > %a2) ; <i64> [#uses=1] + ret < 8 x float > %res +} +declare < 8 x float > @llvm.x86.fma4.vfmsubadd.ps.256(< 8 x float >, < 8 x float >, < 8 x float >) nounwind readnone + +define < 4 x double > @test_x86_fma4_vfmsubadd_pd_256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) { + ; CHECK: vfmsubaddpd + ; CHECK: ymm + %res = call < 4 x double > @llvm.x86.fma4.vfmsubadd.pd.256(< 4 x double > %a0, < 4 x double > %a1, < 4 x double > %a2) ; <i64> [#uses=1] + ret < 4 x double > %res +} +declare < 4 x double > @llvm.x86.fma4.vfmsubadd.pd.256(< 4 x double >, < 4 x double >, < 4 x double >) nounwind readnone diff --git a/test/CodeGen/X86/fold-and-shift.ll b/test/CodeGen/X86/fold-and-shift.ll index 9f79f77..93baa0e 100644 --- a/test/CodeGen/X86/fold-and-shift.ll +++ b/test/CodeGen/X86/fold-and-shift.ll @@ -1,21 +1,77 @@ -; RUN: llc < %s -march=x86 | not grep and +; RUN: llc < %s -march=x86 | FileCheck %s define i32 @t1(i8* %X, i32 %i) { +; CHECK: t1: +; CHECK-NOT: and +; CHECK: movzbl +; CHECK: movl (%{{...}},%{{...}},4), +; CHECK: ret + entry: - %tmp2 = shl i32 %i, 2 ; <i32> [#uses=1] - %tmp4 = and i32 %tmp2, 1020 ; <i32> [#uses=1] - %tmp7 = getelementptr i8* %X, i32 %tmp4 ; <i8*> [#uses=1] - %tmp78 = bitcast i8* %tmp7 to i32* ; <i32*> [#uses=1] - %tmp9 = load i32* %tmp78, align 4 ; <i32> [#uses=1] - ret i32 %tmp9 + %tmp2 = shl i32 %i, 2 + %tmp4 = and i32 %tmp2, 1020 + %tmp7 = getelementptr i8* %X, i32 %tmp4 + %tmp78 = bitcast i8* %tmp7 to i32* + %tmp9 = load i32* %tmp78 + ret i32 %tmp9 } define i32 @t2(i16* %X, i32 %i) { +; CHECK: t2: +; CHECK-NOT: and +; CHECK: movzwl +; CHECK: movl (%{{...}},%{{...}},4), +; CHECK: ret + +entry: + %tmp2 = shl i32 %i, 1 + %tmp4 = and i32 %tmp2, 131070 + %tmp7 = getelementptr i16* %X, i32 %tmp4 + %tmp78 = bitcast i16* %tmp7 to i32* + %tmp9 = load i32* %tmp78 + ret i32 %tmp9 +} + +define i32 @t3(i16* %i.ptr, i32* %arr) { +; This case is tricky. The lshr followed by a gep will produce a lshr followed +; by an and to remove the low bits. This can be simplified by doing the lshr by +; a greater constant and using the addressing mode to scale the result back up. +; To make matters worse, because of the two-phase zext of %i and their reuse in +; the function, the DAG can get confusing trying to re-use both of them and +; prevent easy analysis of the mask in order to match this. +; CHECK: t3: +; CHECK-NOT: and +; CHECK: shrl +; CHECK: addl (%{{...}},%{{...}},4), +; CHECK: ret + +entry: + %i = load i16* %i.ptr + %i.zext = zext i16 %i to i32 + %index = lshr i32 %i.zext, 11 + %val.ptr = getelementptr inbounds i32* %arr, i32 %index + %val = load i32* %val.ptr + %sum = add i32 %val, %i.zext + ret i32 %sum +} + +define i32 @t4(i16* %i.ptr, i32* %arr) { +; A version of @t3 that has more zero extends and more re-use of intermediate +; values. This exercise slightly different bits of canonicalization. +; CHECK: t4: +; CHECK-NOT: and +; CHECK: shrl +; CHECK: addl (%{{...}},%{{...}},4), +; CHECK: ret + entry: - %tmp2 = shl i32 %i, 1 ; <i32> [#uses=1] - %tmp4 = and i32 %tmp2, 131070 ; <i32> [#uses=1] - %tmp7 = getelementptr i16* %X, i32 %tmp4 ; <i16*> [#uses=1] - %tmp78 = bitcast i16* %tmp7 to i32* ; <i32*> [#uses=1] - %tmp9 = load i32* %tmp78, align 4 ; <i32> [#uses=1] - ret i32 %tmp9 + %i = load i16* %i.ptr + %i.zext = zext i16 %i to i32 + %index = lshr i32 %i.zext, 11 + %index.zext = zext i32 %index to i64 + %val.ptr = getelementptr inbounds i32* %arr, i64 %index.zext + %val = load i32* %val.ptr + %sum.1 = add i32 %val, %i.zext + %sum.2 = add i32 %sum.1, %index + ret i32 %sum.2 } diff --git a/test/CodeGen/X86/fold-load.ll b/test/CodeGen/X86/fold-load.ll index 5525af2..e03cb7e 100644 --- a/test/CodeGen/X86/fold-load.ll +++ b/test/CodeGen/X86/fold-load.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -mcpu=generic -march=x86 | FileCheck %s %struct._obstack_chunk = type { i8*, %struct._obstack_chunk*, [4 x i8] } %struct.obstack = type { i32, %struct._obstack_chunk*, i8*, i8*, i8*, i32, i32, %struct._obstack_chunk* (...)*, void (...)*, i8*, i8 } @stmt_obstack = external global %struct.obstack ; <%struct.obstack*> [#uses=1] diff --git a/test/CodeGen/X86/fold-pcmpeqd-0.ll b/test/CodeGen/X86/fold-pcmpeqd-0.ll index 647bbdb..1d315ff 100644 --- a/test/CodeGen/X86/fold-pcmpeqd-0.ll +++ b/test/CodeGen/X86/fold-pcmpeqd-0.ll @@ -1,5 +1,7 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=yonah -regalloc=linearscan | FileCheck --check-prefix=I386 %s ; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck --check-prefix=X86-64 %s +; DISABLED: llc < %s -mtriple=i386-apple-darwin -mcpu=yonah -regalloc=linearscan | FileCheck --check-prefix=I386 %s + +; i386 test has been disabled when scheduler 2-addr hack is disabled. ; This testcase shouldn't need to spill the -1 value, ; so it should just use pcmpeqd to materialize an all-ones vector. diff --git a/test/CodeGen/X86/fold-pcmpeqd-2.ll b/test/CodeGen/X86/fold-pcmpeqd-2.ll index 9f8d990..9cf4607 100644 --- a/test/CodeGen/X86/fold-pcmpeqd-2.ll +++ b/test/CodeGen/X86/fold-pcmpeqd-2.ll @@ -1,15 +1,14 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=yonah -regalloc=linearscan | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-apple-darwin -regalloc=linearscan | FileCheck %s +; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=yonah -regalloc=basic | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-darwin -regalloc=basic | FileCheck %s ; This testcase should need to spill the -1 value on both x86-32 and x86-64, ; so it shouldn't use pcmpeqd to materialize an all-ones vector; it ; should use a constant-pool load instead. +; +; RAGreedy defeats the test by splitting live ranges. ; Constant pool all-ones vector: -; CHECK: .long 4294967295 -; CHECK-NEXT: .long 4294967295 -; CHECK-NEXT: .long 4294967295 -; CHECK-NEXT: .long 4294967295 +; CHECK: .space 16,255 ; No pcmpeqd instructions, everybody uses the constant pool. ; CHECK: program_1: diff --git a/test/CodeGen/X86/fp-stack-O0.ll b/test/CodeGen/X86/fp-stack-O0.ll index b9cb5d7..df90254 100644 --- a/test/CodeGen/X86/fp-stack-O0.ll +++ b/test/CodeGen/X86/fp-stack-O0.ll @@ -10,7 +10,7 @@ declare i32 @x2(x86_fp80, x86_fp80) nounwind ; Pass arguments on the stack. ; CHECK-NEXT: movq %rsp, [[RCX:%r..]] ; Copy constant-pool value. -; CHECK-NEXT: fldt LCPI +; CHECK-NEXT: fldl LCPI ; CHECK-NEXT: fstpt 16([[RCX]]) ; Copy x1 return value. ; CHECK-NEXT: fstpt ([[RCX]]) diff --git a/test/CodeGen/X86/fp-stack-ret-conv.ll b/test/CodeGen/X86/fp-stack-ret-conv.ll index f220b24..3e26141 100644 --- a/test/CodeGen/X86/fp-stack-ret-conv.ll +++ b/test/CodeGen/X86/fp-stack-ret-conv.ll @@ -10,7 +10,7 @@ entry: %tmp13 = tail call double @foo() %tmp1314 = fptrunc double %tmp13 to float ; <float> [#uses=1] %tmp3940 = fpext float %tmp1314 to double ; <double> [#uses=1] - volatile store double %tmp3940, double* %b + store volatile double %tmp3940, double* %b ret void } diff --git a/test/CodeGen/X86/fsgsbase.ll b/test/CodeGen/X86/fsgsbase.ll new file mode 100644 index 0000000..0c22e3c --- /dev/null +++ b/test/CodeGen/X86/fsgsbase.ll @@ -0,0 +1,57 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin -march=x86-64 -mcpu=core-avx-i -mattr=fsgsbase | FileCheck %s + +define i32 @test_x86_rdfsbase_32() { + ; CHECK: rdfsbasel + %res = call i32 @llvm.x86.rdfsbase.32() + ret i32 %res +} +declare i32 @llvm.x86.rdfsbase.32() nounwind readnone + +define i32 @test_x86_rdgsbase_32() { + ; CHECK: rdgsbasel + %res = call i32 @llvm.x86.rdgsbase.32() + ret i32 %res +} +declare i32 @llvm.x86.rdgsbase.32() nounwind readnone + +define i64 @test_x86_rdfsbase_64() { + ; CHECK: rdfsbaseq + %res = call i64 @llvm.x86.rdfsbase.64() + ret i64 %res +} +declare i64 @llvm.x86.rdfsbase.64() nounwind readnone + +define i64 @test_x86_rdgsbase_64() { + ; CHECK: rdgsbaseq + %res = call i64 @llvm.x86.rdgsbase.64() + ret i64 %res +} +declare i64 @llvm.x86.rdgsbase.64() nounwind readnone + +define void @test_x86_wrfsbase_32(i32 %x) { + ; CHECK: wrfsbasel + call void @llvm.x86.wrfsbase.32(i32 %x) + ret void +} +declare void @llvm.x86.wrfsbase.32(i32) nounwind readnone + +define void @test_x86_wrgsbase_32(i32 %x) { + ; CHECK: wrgsbasel + call void @llvm.x86.wrgsbase.32(i32 %x) + ret void +} +declare void @llvm.x86.wrgsbase.32(i32) nounwind readnone + +define void @test_x86_wrfsbase_64(i64 %x) { + ; CHECK: wrfsbaseq + call void @llvm.x86.wrfsbase.64(i64 %x) + ret void +} +declare void @llvm.x86.wrfsbase.64(i64) nounwind readnone + +define void @test_x86_wrgsbase_64(i64 %x) { + ; CHECK: wrgsbaseq + call void @llvm.x86.wrgsbase.64(i64 %x) + ret void +} +declare void @llvm.x86.wrgsbase.64(i64) nounwind readnone diff --git a/test/CodeGen/X86/gcc_except_table.ll b/test/CodeGen/X86/gcc_except_table.ll new file mode 100644 index 0000000..d89e9dc --- /dev/null +++ b/test/CodeGen/X86/gcc_except_table.ll @@ -0,0 +1,27 @@ +; RUN: llc -mtriple x86_64-apple-darwin %s -o - | FileCheck %s +@_ZTIi = external constant i8* + +define i32 @main() uwtable optsize ssp { +entry: + invoke void @_Z1fv() optsize + to label %try.cont unwind label %lpad + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (i8** @_ZTIi to i8*) + br label %eh.resume + +try.cont: + ret i32 0 + +eh.resume: + resume { i8*, i32 } %0 +} + +declare void @_Z1fv() optsize + +declare i32 @__gxx_personality_v0(...) + +; CHECK: Leh_func_end0: +; CHECK: GCC_except_table0 +; CHECK: = Leh_func_end0- diff --git a/test/CodeGen/X86/haddsub.ll b/test/CodeGen/X86/haddsub.ll index 91758ea..5f1f4fd 100644 --- a/test/CodeGen/X86/haddsub.ll +++ b/test/CodeGen/X86/haddsub.ll @@ -192,3 +192,94 @@ define <4 x float> @hsubps4(<4 x float> %x) { %r = fsub <4 x float> %a, %b ret <4 x float> %r } + +; SSE3: vhaddps1: +; SSE3-NOT: vhaddps +; SSE3: haddps +; SSE3: haddps +; AVX: vhaddps1: +; AVX: vhaddps +define <8 x float> @vhaddps1(<8 x float> %x, <8 x float> %y) { + %a = shufflevector <8 x float> %x, <8 x float> %y, <8 x i32> <i32 0, i32 2, i32 8, i32 10, i32 4, i32 6, i32 12, i32 14> + %b = shufflevector <8 x float> %x, <8 x float> %y, <8 x i32> <i32 1, i32 3, i32 9, i32 11, i32 5, i32 7, i32 13, i32 15> + %r = fadd <8 x float> %a, %b + ret <8 x float> %r +} + +; SSE3: vhaddps2: +; SSE3-NOT: vhaddps +; SSE3: haddps +; SSE3: haddps +; AVX: vhaddps2: +; AVX: vhaddps +define <8 x float> @vhaddps2(<8 x float> %x, <8 x float> %y) { + %a = shufflevector <8 x float> %x, <8 x float> %y, <8 x i32> <i32 1, i32 2, i32 9, i32 10, i32 5, i32 6, i32 13, i32 14> + %b = shufflevector <8 x float> %y, <8 x float> %x, <8 x i32> <i32 8, i32 11, i32 0, i32 3, i32 12, i32 15, i32 4, i32 7> + %r = fadd <8 x float> %a, %b + ret <8 x float> %r +} + +; SSE3: vhaddps3: +; SSE3-NOT: vhaddps +; SSE3: haddps +; SSE3: haddps +; AVX: vhaddps3: +; AVX: vhaddps +define <8 x float> @vhaddps3(<8 x float> %x) { + %a = shufflevector <8 x float> %x, <8 x float> undef, <8 x i32> <i32 undef, i32 2, i32 8, i32 10, i32 4, i32 6, i32 undef, i32 14> + %b = shufflevector <8 x float> %x, <8 x float> undef, <8 x i32> <i32 1, i32 3, i32 9, i32 undef, i32 5, i32 7, i32 13, i32 15> + %r = fadd <8 x float> %a, %b + ret <8 x float> %r +} + +; SSE3: vhsubps1: +; SSE3-NOT: vhsubps +; SSE3: hsubps +; SSE3: hsubps +; AVX: vhsubps1: +; AVX: vhsubps +define <8 x float> @vhsubps1(<8 x float> %x, <8 x float> %y) { + %a = shufflevector <8 x float> %x, <8 x float> %y, <8 x i32> <i32 0, i32 2, i32 8, i32 10, i32 4, i32 6, i32 12, i32 14> + %b = shufflevector <8 x float> %x, <8 x float> %y, <8 x i32> <i32 1, i32 3, i32 9, i32 11, i32 5, i32 7, i32 13, i32 15> + %r = fsub <8 x float> %a, %b + ret <8 x float> %r +} + +; SSE3: vhsubps3: +; SSE3-NOT: vhsubps +; SSE3: hsubps +; SSE3: hsubps +; AVX: vhsubps3: +; AVX: vhsubps +define <8 x float> @vhsubps3(<8 x float> %x) { + %a = shufflevector <8 x float> %x, <8 x float> undef, <8 x i32> <i32 undef, i32 2, i32 8, i32 10, i32 4, i32 6, i32 undef, i32 14> + %b = shufflevector <8 x float> %x, <8 x float> undef, <8 x i32> <i32 1, i32 3, i32 9, i32 undef, i32 5, i32 7, i32 13, i32 15> + %r = fsub <8 x float> %a, %b + ret <8 x float> %r +} + +; SSE3: vhaddpd1: +; SSE3-NOT: vhaddpd +; SSE3: haddpd +; SSE3: haddpd +; AVX: vhaddpd1: +; AVX: vhaddpd +define <4 x double> @vhaddpd1(<4 x double> %x, <4 x double> %y) { + %a = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 0, i32 4, i32 2, i32 6> + %b = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 1, i32 5, i32 3, i32 7> + %r = fadd <4 x double> %a, %b + ret <4 x double> %r +} + +; SSE3: vhsubpd1: +; SSE3-NOT: vhsubpd +; SSE3: hsubpd +; SSE3: hsubpd +; AVX: vhsubpd1: +; AVX: vhsubpd +define <4 x double> @vhsubpd1(<4 x double> %x, <4 x double> %y) { + %a = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 0, i32 4, i32 2, i32 6> + %b = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 1, i32 5, i32 3, i32 7> + %r = fsub <4 x double> %a, %b + ret <4 x double> %r +} diff --git a/test/CodeGen/X86/hoist-invariant-load.ll b/test/CodeGen/X86/hoist-invariant-load.ll new file mode 100644 index 0000000..4289fa7 --- /dev/null +++ b/test/CodeGen/X86/hoist-invariant-load.ll @@ -0,0 +1,29 @@ +; RUN: llc < %s -stats -O2 |& grep "1 machine-licm" + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7.2" + +@"\01L_OBJC_METH_VAR_NAME_" = internal global [4 x i8] c"foo\00", section "__TEXT,__objc_methname,cstring_literals", align 1 +@"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([4 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" +@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip" +@llvm.used = appending global [3 x i8*] [i8* getelementptr inbounds ([4 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), i8* bitcast (i8** @"\01L_OBJC_SELECTOR_REFERENCES_" to i8*), i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*)], section "llvm.metadata" + +define void @test(i8* %x) uwtable ssp { +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %0 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load !0 + %call = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %x, i8* %0) + %inc = add i32 %i.01, 1 + %exitcond = icmp eq i32 %inc, 10000 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret void +} + +declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind + +!0 = metadata !{} diff --git a/test/CodeGen/X86/i128-sdiv.ll b/test/CodeGen/X86/i128-sdiv.ll new file mode 100644 index 0000000..ab5cdda --- /dev/null +++ b/test/CodeGen/X86/i128-sdiv.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s +; Make sure none of these crash, and that the power-of-two transformations +; trigger correctly. + +define i128 @test1(i128 %x) { + ; CHECK: test1: + ; CHECK-NOT: call + %tmp = sdiv i128 %x, 73786976294838206464 + ret i128 %tmp +} + +define i128 @test2(i128 %x) { + ; CHECK: test2: + ; CHECK-NOT: call + %tmp = sdiv i128 %x, -73786976294838206464 + ret i128 %tmp +} + +define i128 @test3(i128 %x) { + ; CHECK: test3: + ; CHECK: call + %tmp = sdiv i128 %x, -73786976294838206467 + ret i128 %tmp +} diff --git a/test/CodeGen/X86/inline-asm-fpstack.ll b/test/CodeGen/X86/inline-asm-fpstack.ll index c9a1c1c..2249618 100644 --- a/test/CodeGen/X86/inline-asm-fpstack.ll +++ b/test/CodeGen/X86/inline-asm-fpstack.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=i386-apple-darwin | FileCheck %s ; There should be no stack manipulations between the inline asm and ret. ; CHECK: test1 diff --git a/test/CodeGen/X86/inline-asm-q-regs.ll b/test/CodeGen/X86/inline-asm-q-regs.ll index 1c8e2f9..fca68ba 100644 --- a/test/CodeGen/X86/inline-asm-q-regs.ll +++ b/test/CodeGen/X86/inline-asm-q-regs.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 +; RUN: llc < %s -march=x86-64 -mattr=+avx ; rdar://7066579 %0 = type { i64, i64, i64, i64, i64 } ; type %0 @@ -20,3 +20,18 @@ define void @test3(double %tmp) nounwind { call void asm sideeffect "$0", "q"(double %tmp) nounwind ret void } + +; rdar://10392864 +define void @test4(i8 signext %val, i8 signext %a, i8 signext %b, i8 signext %c, i8 signext %d) nounwind { +entry: + %0 = tail call { i8, i8, i8, i8, i8 } asm "foo $1, $2, $3, $4, $1\0Axchgb ${0:b}, ${0:h}", "=q,={ax},={bx},={cx},={dx},0,1,2,3,4,~{dirflag},~{fpsr},~{flags}"(i8 %val, i8 %a, i8 %b, i8 %c, i8 %d) nounwind + ret void +} + +; rdar://10614894 +define <8 x float> @test5(<8 x float> %a, <8 x float> %b) nounwind { +entry: + %0 = tail call <8 x float> asm "vperm2f128 $3, $2, $1, $0", "=x,x,x,i,~{dirflag},~{fpsr},~{flags}"(<8 x float> %a, <8 x float> %b, i32 16) nounwind + ret <8 x float> %0 +} + diff --git a/test/CodeGen/X86/inline-asm-tied.ll b/test/CodeGen/X86/inline-asm-tied.ll index 79b6885..91576fb 100644 --- a/test/CodeGen/X86/inline-asm-tied.ll +++ b/test/CodeGen/X86/inline-asm-tied.ll @@ -1,6 +1,8 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin9 -O0 -regalloc=linearscan | grep {movl %edx, 4(%esp)} | count 2 +; RUN: llc < %s -mtriple=i386-apple-darwin9 -O0 -optimize-regalloc -regalloc=basic | FileCheck %s ; rdar://6992609 +; CHECK: movl [[EDX:%e..]], 4(%esp) +; CHECK: movl [[EDX]], 4(%esp) target triple = "i386-apple-darwin9.0" @llvm.used = appending global [1 x i8*] [i8* bitcast (i64 (i64)* @_OSSwapInt64 to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] diff --git a/test/CodeGen/X86/iv-users-in-other-loops.ll b/test/CodeGen/X86/iv-users-in-other-loops.ll deleted file mode 100644 index 8f79fb8..0000000 --- a/test/CodeGen/X86/iv-users-in-other-loops.ll +++ /dev/null @@ -1,300 +0,0 @@ -; RUN: llc < %s -march=x86-64 -enable-lsr-nested -o %t -; RUN: not grep inc %t -; RUN: grep dec %t | count 2 -; RUN: grep addq %t | count 12 -; RUN: not grep addb %t -; RUN: not grep leaq %t -; RUN: not grep leal %t -; RUN: not grep movq %t - -; IV users in each of the loops from other loops shouldn't cause LSR -; to insert new induction variables. Previously it would create a -; flood of new induction variables. -; Also, the loop reversal should kick in once. -; -; In this example, performing LSR on the entire loop nest, -; as opposed to only the inner loop can further reduce induction variables, -; and their related instructions and registers. - -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" -target triple = "x86_64-unknown-linux-gnu" - -define void @foo(float* %A, i32 %IA, float* %B, i32 %IB, float* nocapture %C, i32 %N) nounwind { -entry: - %0 = xor i32 %IA, 1 ; <i32> [#uses=1] - %1 = xor i32 %IB, 1 ; <i32> [#uses=1] - %2 = or i32 %1, %0 ; <i32> [#uses=1] - %3 = icmp eq i32 %2, 0 ; <i1> [#uses=1] - br i1 %3, label %bb2, label %bb13 - -bb: ; preds = %bb3 - %4 = load float* %A_addr.0, align 4 ; <float> [#uses=1] - %5 = load float* %B_addr.0, align 4 ; <float> [#uses=1] - %6 = fmul float %4, %5 ; <float> [#uses=1] - %7 = fadd float %6, %Sum0.0 ; <float> [#uses=1] - %indvar.next154 = add i64 %B_addr.0.rec, 1 ; <i64> [#uses=1] - br label %bb2 - -bb2: ; preds = %entry, %bb - %B_addr.0.rec = phi i64 [ %indvar.next154, %bb ], [ 0, %entry ] ; <i64> [#uses=14] - %Sum0.0 = phi float [ %7, %bb ], [ 0.000000e+00, %entry ] ; <float> [#uses=5] - %indvar146 = trunc i64 %B_addr.0.rec to i32 ; <i32> [#uses=1] - %N_addr.0 = sub i32 %N, %indvar146 ; <i32> [#uses=6] - %A_addr.0 = getelementptr float* %A, i64 %B_addr.0.rec ; <float*> [#uses=4] - %B_addr.0 = getelementptr float* %B, i64 %B_addr.0.rec ; <float*> [#uses=4] - %8 = icmp sgt i32 %N_addr.0, 0 ; <i1> [#uses=1] - br i1 %8, label %bb3, label %bb4 - -bb3: ; preds = %bb2 - %9 = ptrtoint float* %A_addr.0 to i64 ; <i64> [#uses=1] - %10 = and i64 %9, 15 ; <i64> [#uses=1] - %11 = icmp eq i64 %10, 0 ; <i1> [#uses=1] - br i1 %11, label %bb4, label %bb - -bb4: ; preds = %bb3, %bb2 - %12 = ptrtoint float* %B_addr.0 to i64 ; <i64> [#uses=1] - %13 = and i64 %12, 15 ; <i64> [#uses=1] - %14 = icmp eq i64 %13, 0 ; <i1> [#uses=1] - %15 = icmp sgt i32 %N_addr.0, 15 ; <i1> [#uses=2] - br i1 %14, label %bb6.preheader, label %bb10.preheader - -bb10.preheader: ; preds = %bb4 - br i1 %15, label %bb9, label %bb12.loopexit - -bb6.preheader: ; preds = %bb4 - br i1 %15, label %bb5, label %bb8.loopexit - -bb5: ; preds = %bb5, %bb6.preheader - %indvar143 = phi i64 [ 0, %bb6.preheader ], [ %indvar.next144, %bb5 ] ; <i64> [#uses=3] - %vSum0.072 = phi <4 x float> [ zeroinitializer, %bb6.preheader ], [ %21, %bb5 ] ; <<4 x float>> [#uses=1] - %vSum1.070 = phi <4 x float> [ zeroinitializer, %bb6.preheader ], [ %29, %bb5 ] ; <<4 x float>> [#uses=1] - %vSum2.069 = phi <4 x float> [ zeroinitializer, %bb6.preheader ], [ %37, %bb5 ] ; <<4 x float>> [#uses=1] - %vSum3.067 = phi <4 x float> [ zeroinitializer, %bb6.preheader ], [ %45, %bb5 ] ; <<4 x float>> [#uses=1] - %indvar145 = trunc i64 %indvar143 to i32 ; <i32> [#uses=1] - %tmp150 = mul i32 %indvar145, -16 ; <i32> [#uses=1] - %N_addr.268 = add i32 %tmp150, %N_addr.0 ; <i32> [#uses=1] - %A_addr.273.rec = shl i64 %indvar143, 4 ; <i64> [#uses=5] - %B_addr.0.sum180 = add i64 %B_addr.0.rec, %A_addr.273.rec ; <i64> [#uses=2] - %B_addr.271 = getelementptr float* %B, i64 %B_addr.0.sum180 ; <float*> [#uses=1] - %A_addr.273 = getelementptr float* %A, i64 %B_addr.0.sum180 ; <float*> [#uses=1] - tail call void asm sideeffect ";# foo", "~{dirflag},~{fpsr},~{flags}"() nounwind - %16 = bitcast float* %A_addr.273 to <4 x float>* ; <<4 x float>*> [#uses=1] - %17 = load <4 x float>* %16, align 16 ; <<4 x float>> [#uses=1] - %18 = bitcast float* %B_addr.271 to <4 x float>* ; <<4 x float>*> [#uses=1] - %19 = load <4 x float>* %18, align 16 ; <<4 x float>> [#uses=1] - %20 = fmul <4 x float> %17, %19 ; <<4 x float>> [#uses=1] - %21 = fadd <4 x float> %20, %vSum0.072 ; <<4 x float>> [#uses=2] - %A_addr.273.sum163 = or i64 %A_addr.273.rec, 4 ; <i64> [#uses=1] - %A_addr.0.sum175 = add i64 %B_addr.0.rec, %A_addr.273.sum163 ; <i64> [#uses=2] - %22 = getelementptr float* %A, i64 %A_addr.0.sum175 ; <float*> [#uses=1] - %23 = bitcast float* %22 to <4 x float>* ; <<4 x float>*> [#uses=1] - %24 = load <4 x float>* %23, align 16 ; <<4 x float>> [#uses=1] - %25 = getelementptr float* %B, i64 %A_addr.0.sum175 ; <float*> [#uses=1] - %26 = bitcast float* %25 to <4 x float>* ; <<4 x float>*> [#uses=1] - %27 = load <4 x float>* %26, align 16 ; <<4 x float>> [#uses=1] - %28 = fmul <4 x float> %24, %27 ; <<4 x float>> [#uses=1] - %29 = fadd <4 x float> %28, %vSum1.070 ; <<4 x float>> [#uses=2] - %A_addr.273.sum161 = or i64 %A_addr.273.rec, 8 ; <i64> [#uses=1] - %A_addr.0.sum174 = add i64 %B_addr.0.rec, %A_addr.273.sum161 ; <i64> [#uses=2] - %30 = getelementptr float* %A, i64 %A_addr.0.sum174 ; <float*> [#uses=1] - %31 = bitcast float* %30 to <4 x float>* ; <<4 x float>*> [#uses=1] - %32 = load <4 x float>* %31, align 16 ; <<4 x float>> [#uses=1] - %33 = getelementptr float* %B, i64 %A_addr.0.sum174 ; <float*> [#uses=1] - %34 = bitcast float* %33 to <4 x float>* ; <<4 x float>*> [#uses=1] - %35 = load <4 x float>* %34, align 16 ; <<4 x float>> [#uses=1] - %36 = fmul <4 x float> %32, %35 ; <<4 x float>> [#uses=1] - %37 = fadd <4 x float> %36, %vSum2.069 ; <<4 x float>> [#uses=2] - %A_addr.273.sum159 = or i64 %A_addr.273.rec, 12 ; <i64> [#uses=1] - %A_addr.0.sum173 = add i64 %B_addr.0.rec, %A_addr.273.sum159 ; <i64> [#uses=2] - %38 = getelementptr float* %A, i64 %A_addr.0.sum173 ; <float*> [#uses=1] - %39 = bitcast float* %38 to <4 x float>* ; <<4 x float>*> [#uses=1] - %40 = load <4 x float>* %39, align 16 ; <<4 x float>> [#uses=1] - %41 = getelementptr float* %B, i64 %A_addr.0.sum173 ; <float*> [#uses=1] - %42 = bitcast float* %41 to <4 x float>* ; <<4 x float>*> [#uses=1] - %43 = load <4 x float>* %42, align 16 ; <<4 x float>> [#uses=1] - %44 = fmul <4 x float> %40, %43 ; <<4 x float>> [#uses=1] - %45 = fadd <4 x float> %44, %vSum3.067 ; <<4 x float>> [#uses=2] - %.rec83 = add i64 %A_addr.273.rec, 16 ; <i64> [#uses=1] - %A_addr.0.sum172 = add i64 %B_addr.0.rec, %.rec83 ; <i64> [#uses=2] - %46 = getelementptr float* %A, i64 %A_addr.0.sum172 ; <float*> [#uses=1] - %47 = getelementptr float* %B, i64 %A_addr.0.sum172 ; <float*> [#uses=1] - %48 = add i32 %N_addr.268, -16 ; <i32> [#uses=2] - %49 = icmp sgt i32 %48, 15 ; <i1> [#uses=1] - %indvar.next144 = add i64 %indvar143, 1 ; <i64> [#uses=1] - br i1 %49, label %bb5, label %bb8.loopexit - -bb7: ; preds = %bb7, %bb8.loopexit - %indvar130 = phi i64 [ 0, %bb8.loopexit ], [ %indvar.next131, %bb7 ] ; <i64> [#uses=3] - %vSum0.260 = phi <4 x float> [ %vSum0.0.lcssa, %bb8.loopexit ], [ %55, %bb7 ] ; <<4 x float>> [#uses=1] - %indvar132 = trunc i64 %indvar130 to i32 ; <i32> [#uses=1] - %tmp133 = mul i32 %indvar132, -4 ; <i32> [#uses=1] - %N_addr.358 = add i32 %tmp133, %N_addr.2.lcssa ; <i32> [#uses=1] - %A_addr.361.rec = shl i64 %indvar130, 2 ; <i64> [#uses=3] - %B_addr.359 = getelementptr float* %B_addr.2.lcssa, i64 %A_addr.361.rec ; <float*> [#uses=1] - %A_addr.361 = getelementptr float* %A_addr.2.lcssa, i64 %A_addr.361.rec ; <float*> [#uses=1] - %50 = bitcast float* %A_addr.361 to <4 x float>* ; <<4 x float>*> [#uses=1] - %51 = load <4 x float>* %50, align 16 ; <<4 x float>> [#uses=1] - %52 = bitcast float* %B_addr.359 to <4 x float>* ; <<4 x float>*> [#uses=1] - %53 = load <4 x float>* %52, align 16 ; <<4 x float>> [#uses=1] - %54 = fmul <4 x float> %51, %53 ; <<4 x float>> [#uses=1] - %55 = fadd <4 x float> %54, %vSum0.260 ; <<4 x float>> [#uses=2] - %.rec85 = add i64 %A_addr.361.rec, 4 ; <i64> [#uses=2] - %56 = getelementptr float* %A_addr.2.lcssa, i64 %.rec85 ; <float*> [#uses=1] - %57 = getelementptr float* %B_addr.2.lcssa, i64 %.rec85 ; <float*> [#uses=1] - %58 = add i32 %N_addr.358, -4 ; <i32> [#uses=2] - %59 = icmp sgt i32 %58, 3 ; <i1> [#uses=1] - %indvar.next131 = add i64 %indvar130, 1 ; <i64> [#uses=1] - br i1 %59, label %bb7, label %bb13 - -bb8.loopexit: ; preds = %bb5, %bb6.preheader - %A_addr.2.lcssa = phi float* [ %A_addr.0, %bb6.preheader ], [ %46, %bb5 ] ; <float*> [#uses=3] - %vSum0.0.lcssa = phi <4 x float> [ zeroinitializer, %bb6.preheader ], [ %21, %bb5 ] ; <<4 x float>> [#uses=2] - %B_addr.2.lcssa = phi float* [ %B_addr.0, %bb6.preheader ], [ %47, %bb5 ] ; <float*> [#uses=3] - %vSum1.0.lcssa = phi <4 x float> [ zeroinitializer, %bb6.preheader ], [ %29, %bb5 ] ; <<4 x float>> [#uses=2] - %vSum2.0.lcssa = phi <4 x float> [ zeroinitializer, %bb6.preheader ], [ %37, %bb5 ] ; <<4 x float>> [#uses=2] - %N_addr.2.lcssa = phi i32 [ %N_addr.0, %bb6.preheader ], [ %48, %bb5 ] ; <i32> [#uses=3] - %vSum3.0.lcssa = phi <4 x float> [ zeroinitializer, %bb6.preheader ], [ %45, %bb5 ] ; <<4 x float>> [#uses=2] - %60 = icmp sgt i32 %N_addr.2.lcssa, 3 ; <i1> [#uses=1] - br i1 %60, label %bb7, label %bb13 - -bb9: ; preds = %bb9, %bb10.preheader - %indvar106 = phi i64 [ 0, %bb10.preheader ], [ %indvar.next107, %bb9 ] ; <i64> [#uses=3] - %vSum0.339 = phi <4 x float> [ zeroinitializer, %bb10.preheader ], [ %75, %bb9 ] ; <<4 x float>> [#uses=1] - %vSum1.237 = phi <4 x float> [ zeroinitializer, %bb10.preheader ], [ %80, %bb9 ] ; <<4 x float>> [#uses=1] - %vSum2.236 = phi <4 x float> [ zeroinitializer, %bb10.preheader ], [ %85, %bb9 ] ; <<4 x float>> [#uses=1] - %vSum3.234 = phi <4 x float> [ zeroinitializer, %bb10.preheader ], [ %90, %bb9 ] ; <<4 x float>> [#uses=1] - %indvar108 = trunc i64 %indvar106 to i32 ; <i32> [#uses=1] - %tmp113 = mul i32 %indvar108, -16 ; <i32> [#uses=1] - %N_addr.435 = add i32 %tmp113, %N_addr.0 ; <i32> [#uses=1] - %A_addr.440.rec = shl i64 %indvar106, 4 ; <i64> [#uses=5] - %B_addr.0.sum = add i64 %B_addr.0.rec, %A_addr.440.rec ; <i64> [#uses=2] - %B_addr.438 = getelementptr float* %B, i64 %B_addr.0.sum ; <float*> [#uses=1] - %A_addr.440 = getelementptr float* %A, i64 %B_addr.0.sum ; <float*> [#uses=1] - %61 = bitcast float* %B_addr.438 to <4 x float>* ; <i8*> [#uses=1] - %62 = load <4 x float>* %61, align 1 - %B_addr.438.sum169 = or i64 %A_addr.440.rec, 4 ; <i64> [#uses=1] - %B_addr.0.sum187 = add i64 %B_addr.0.rec, %B_addr.438.sum169 ; <i64> [#uses=2] - %63 = getelementptr float* %B, i64 %B_addr.0.sum187 ; <float*> [#uses=1] - %64 = bitcast float* %63 to <4 x float>* ; <i8*> [#uses=1] - %65 = load <4 x float>* %64, align 1 - %B_addr.438.sum168 = or i64 %A_addr.440.rec, 8 ; <i64> [#uses=1] - %B_addr.0.sum186 = add i64 %B_addr.0.rec, %B_addr.438.sum168 ; <i64> [#uses=2] - %66 = getelementptr float* %B, i64 %B_addr.0.sum186 ; <float*> [#uses=1] - %67 = bitcast float* %66 to <4 x float>* ; <i8*> [#uses=1] - %68 = load <4 x float>* %67, align 1 - %B_addr.438.sum167 = or i64 %A_addr.440.rec, 12 ; <i64> [#uses=1] - %B_addr.0.sum185 = add i64 %B_addr.0.rec, %B_addr.438.sum167 ; <i64> [#uses=2] - %69 = getelementptr float* %B, i64 %B_addr.0.sum185 ; <float*> [#uses=1] - %70 = bitcast float* %69 to <4 x float>* ; <i8*> [#uses=1] - %71 = load <4 x float>* %70, align 1 - %72 = bitcast float* %A_addr.440 to <4 x float>* ; <<4 x float>*> [#uses=1] - %73 = load <4 x float>* %72, align 16 ; <<4 x float>> [#uses=1] - %74 = fmul <4 x float> %73, %62 ; <<4 x float>> [#uses=1] - %75 = fadd <4 x float> %74, %vSum0.339 ; <<4 x float>> [#uses=2] - %76 = getelementptr float* %A, i64 %B_addr.0.sum187 ; <float*> [#uses=1] - %77 = bitcast float* %76 to <4 x float>* ; <<4 x float>*> [#uses=1] - %78 = load <4 x float>* %77, align 16 ; <<4 x float>> [#uses=1] - %79 = fmul <4 x float> %78, %65 ; <<4 x float>> [#uses=1] - %80 = fadd <4 x float> %79, %vSum1.237 ; <<4 x float>> [#uses=2] - %81 = getelementptr float* %A, i64 %B_addr.0.sum186 ; <float*> [#uses=1] - %82 = bitcast float* %81 to <4 x float>* ; <<4 x float>*> [#uses=1] - %83 = load <4 x float>* %82, align 16 ; <<4 x float>> [#uses=1] - %84 = fmul <4 x float> %83, %68 ; <<4 x float>> [#uses=1] - %85 = fadd <4 x float> %84, %vSum2.236 ; <<4 x float>> [#uses=2] - %86 = getelementptr float* %A, i64 %B_addr.0.sum185 ; <float*> [#uses=1] - %87 = bitcast float* %86 to <4 x float>* ; <<4 x float>*> [#uses=1] - %88 = load <4 x float>* %87, align 16 ; <<4 x float>> [#uses=1] - %89 = fmul <4 x float> %88, %71 ; <<4 x float>> [#uses=1] - %90 = fadd <4 x float> %89, %vSum3.234 ; <<4 x float>> [#uses=2] - %.rec89 = add i64 %A_addr.440.rec, 16 ; <i64> [#uses=1] - %A_addr.0.sum170 = add i64 %B_addr.0.rec, %.rec89 ; <i64> [#uses=2] - %91 = getelementptr float* %A, i64 %A_addr.0.sum170 ; <float*> [#uses=1] - %92 = getelementptr float* %B, i64 %A_addr.0.sum170 ; <float*> [#uses=1] - %93 = add i32 %N_addr.435, -16 ; <i32> [#uses=2] - %94 = icmp sgt i32 %93, 15 ; <i1> [#uses=1] - %indvar.next107 = add i64 %indvar106, 1 ; <i64> [#uses=1] - br i1 %94, label %bb9, label %bb12.loopexit - -bb11: ; preds = %bb11, %bb12.loopexit - %indvar = phi i64 [ 0, %bb12.loopexit ], [ %indvar.next, %bb11 ] ; <i64> [#uses=3] - %vSum0.428 = phi <4 x float> [ %vSum0.3.lcssa, %bb12.loopexit ], [ %100, %bb11 ] ; <<4 x float>> [#uses=1] - %indvar96 = trunc i64 %indvar to i32 ; <i32> [#uses=1] - %tmp = mul i32 %indvar96, -4 ; <i32> [#uses=1] - %N_addr.526 = add i32 %tmp, %N_addr.4.lcssa ; <i32> [#uses=1] - %A_addr.529.rec = shl i64 %indvar, 2 ; <i64> [#uses=3] - %B_addr.527 = getelementptr float* %B_addr.4.lcssa, i64 %A_addr.529.rec ; <float*> [#uses=1] - %A_addr.529 = getelementptr float* %A_addr.4.lcssa, i64 %A_addr.529.rec ; <float*> [#uses=1] - %95 = bitcast float* %B_addr.527 to <4 x float>* ; <i8*> [#uses=1] - %96 = load <4 x float>* %95, align 1 - %97 = bitcast float* %A_addr.529 to <4 x float>* ; <<4 x float>*> [#uses=1] - %98 = load <4 x float>* %97, align 16 ; <<4 x float>> [#uses=1] - %99 = fmul <4 x float> %98, %96 ; <<4 x float>> [#uses=1] - %100 = fadd <4 x float> %99, %vSum0.428 ; <<4 x float>> [#uses=2] - %.rec91 = add i64 %A_addr.529.rec, 4 ; <i64> [#uses=2] - %101 = getelementptr float* %A_addr.4.lcssa, i64 %.rec91 ; <float*> [#uses=1] - %102 = getelementptr float* %B_addr.4.lcssa, i64 %.rec91 ; <float*> [#uses=1] - %103 = add i32 %N_addr.526, -4 ; <i32> [#uses=2] - %104 = icmp sgt i32 %103, 3 ; <i1> [#uses=1] - %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1] - br i1 %104, label %bb11, label %bb13 - -bb12.loopexit: ; preds = %bb9, %bb10.preheader - %A_addr.4.lcssa = phi float* [ %A_addr.0, %bb10.preheader ], [ %91, %bb9 ] ; <float*> [#uses=3] - %vSum0.3.lcssa = phi <4 x float> [ zeroinitializer, %bb10.preheader ], [ %75, %bb9 ] ; <<4 x float>> [#uses=2] - %B_addr.4.lcssa = phi float* [ %B_addr.0, %bb10.preheader ], [ %92, %bb9 ] ; <float*> [#uses=3] - %vSum1.2.lcssa = phi <4 x float> [ zeroinitializer, %bb10.preheader ], [ %80, %bb9 ] ; <<4 x float>> [#uses=2] - %vSum2.2.lcssa = phi <4 x float> [ zeroinitializer, %bb10.preheader ], [ %85, %bb9 ] ; <<4 x float>> [#uses=2] - %N_addr.4.lcssa = phi i32 [ %N_addr.0, %bb10.preheader ], [ %93, %bb9 ] ; <i32> [#uses=3] - %vSum3.2.lcssa = phi <4 x float> [ zeroinitializer, %bb10.preheader ], [ %90, %bb9 ] ; <<4 x float>> [#uses=2] - %105 = icmp sgt i32 %N_addr.4.lcssa, 3 ; <i1> [#uses=1] - br i1 %105, label %bb11, label %bb13 - -bb13: ; preds = %bb12.loopexit, %bb11, %bb8.loopexit, %bb7, %entry - %Sum0.1 = phi float [ 0.000000e+00, %entry ], [ %Sum0.0, %bb7 ], [ %Sum0.0, %bb8.loopexit ], [ %Sum0.0, %bb11 ], [ %Sum0.0, %bb12.loopexit ] ; <float> [#uses=1] - %vSum3.1 = phi <4 x float> [ zeroinitializer, %entry ], [ %vSum3.0.lcssa, %bb7 ], [ %vSum3.0.lcssa, %bb8.loopexit ], [ %vSum3.2.lcssa, %bb11 ], [ %vSum3.2.lcssa, %bb12.loopexit ] ; <<4 x float>> [#uses=1] - %N_addr.1 = phi i32 [ %N, %entry ], [ %N_addr.2.lcssa, %bb8.loopexit ], [ %58, %bb7 ], [ %N_addr.4.lcssa, %bb12.loopexit ], [ %103, %bb11 ] ; <i32> [#uses=2] - %vSum2.1 = phi <4 x float> [ zeroinitializer, %entry ], [ %vSum2.0.lcssa, %bb7 ], [ %vSum2.0.lcssa, %bb8.loopexit ], [ %vSum2.2.lcssa, %bb11 ], [ %vSum2.2.lcssa, %bb12.loopexit ] ; <<4 x float>> [#uses=1] - %vSum1.1 = phi <4 x float> [ zeroinitializer, %entry ], [ %vSum1.0.lcssa, %bb7 ], [ %vSum1.0.lcssa, %bb8.loopexit ], [ %vSum1.2.lcssa, %bb11 ], [ %vSum1.2.lcssa, %bb12.loopexit ] ; <<4 x float>> [#uses=1] - %B_addr.1 = phi float* [ %B, %entry ], [ %B_addr.2.lcssa, %bb8.loopexit ], [ %57, %bb7 ], [ %B_addr.4.lcssa, %bb12.loopexit ], [ %102, %bb11 ] ; <float*> [#uses=1] - %vSum0.1 = phi <4 x float> [ zeroinitializer, %entry ], [ %vSum0.0.lcssa, %bb8.loopexit ], [ %55, %bb7 ], [ %vSum0.3.lcssa, %bb12.loopexit ], [ %100, %bb11 ] ; <<4 x float>> [#uses=1] - %A_addr.1 = phi float* [ %A, %entry ], [ %A_addr.2.lcssa, %bb8.loopexit ], [ %56, %bb7 ], [ %A_addr.4.lcssa, %bb12.loopexit ], [ %101, %bb11 ] ; <float*> [#uses=1] - %106 = fadd <4 x float> %vSum0.1, %vSum2.1 ; <<4 x float>> [#uses=1] - %107 = fadd <4 x float> %vSum1.1, %vSum3.1 ; <<4 x float>> [#uses=1] - %108 = fadd <4 x float> %106, %107 ; <<4 x float>> [#uses=4] - %tmp23 = extractelement <4 x float> %108, i32 0 ; <float> [#uses=1] - %tmp21 = extractelement <4 x float> %108, i32 1 ; <float> [#uses=1] - %109 = fadd float %tmp23, %tmp21 ; <float> [#uses=1] - %tmp19 = extractelement <4 x float> %108, i32 2 ; <float> [#uses=1] - %tmp17 = extractelement <4 x float> %108, i32 3 ; <float> [#uses=1] - %110 = fadd float %tmp19, %tmp17 ; <float> [#uses=1] - %111 = fadd float %109, %110 ; <float> [#uses=1] - %Sum0.254 = fadd float %111, %Sum0.1 ; <float> [#uses=2] - %112 = icmp sgt i32 %N_addr.1, 0 ; <i1> [#uses=1] - br i1 %112, label %bb.nph56, label %bb16 - -bb.nph56: ; preds = %bb13 - %tmp. = zext i32 %N_addr.1 to i64 ; <i64> [#uses=1] - br label %bb14 - -bb14: ; preds = %bb14, %bb.nph56 - %indvar117 = phi i64 [ 0, %bb.nph56 ], [ %indvar.next118, %bb14 ] ; <i64> [#uses=3] - %Sum0.255 = phi float [ %Sum0.254, %bb.nph56 ], [ %Sum0.2, %bb14 ] ; <float> [#uses=1] - %tmp.122 = sext i32 %IB to i64 ; <i64> [#uses=1] - %B_addr.652.rec = mul i64 %indvar117, %tmp.122 ; <i64> [#uses=1] - %tmp.124 = sext i32 %IA to i64 ; <i64> [#uses=1] - %A_addr.653.rec = mul i64 %indvar117, %tmp.124 ; <i64> [#uses=1] - %B_addr.652 = getelementptr float* %B_addr.1, i64 %B_addr.652.rec ; <float*> [#uses=1] - %A_addr.653 = getelementptr float* %A_addr.1, i64 %A_addr.653.rec ; <float*> [#uses=1] - %113 = load float* %A_addr.653, align 4 ; <float> [#uses=1] - %114 = load float* %B_addr.652, align 4 ; <float> [#uses=1] - %115 = fmul float %113, %114 ; <float> [#uses=1] - %Sum0.2 = fadd float %115, %Sum0.255 ; <float> [#uses=2] - %indvar.next118 = add i64 %indvar117, 1 ; <i64> [#uses=2] - %exitcond = icmp eq i64 %indvar.next118, %tmp. ; <i1> [#uses=1] - br i1 %exitcond, label %bb16, label %bb14 - -bb16: ; preds = %bb14, %bb13 - %Sum0.2.lcssa = phi float [ %Sum0.254, %bb13 ], [ %Sum0.2, %bb14 ] ; <float> [#uses=1] - store float %Sum0.2.lcssa, float* %C, align 4 - ret void -} diff --git a/test/CodeGen/X86/jump_sign.ll b/test/CodeGen/X86/jump_sign.ll index 5e8e162..dbd133c 100644 --- a/test/CodeGen/X86/jump_sign.ll +++ b/test/CodeGen/X86/jump_sign.ll @@ -1,7 +1,9 @@ -; RUN: llc < %s -march=x86 | grep jns +; RUN: llc < %s -march=x86 -mcpu=pentiumpro | FileCheck %s define i32 @f(i32 %X) { entry: +; CHECK: f: +; CHECK: jns %tmp1 = add i32 %X, 1 ; <i32> [#uses=1] %tmp = icmp slt i32 %tmp1, 0 ; <i1> [#uses=1] br i1 %tmp, label %cond_true, label %cond_next @@ -18,3 +20,15 @@ cond_next: ; preds = %cond_true, %entry declare i32 @bar(...) declare i32 @baz(...) + +; rdar://10633221 +define i32 @g(i32 %a, i32 %b) nounwind { +entry: +; CHECK: g: +; CHECK-NOT: test +; CHECK: cmovs + %sub = sub nsw i32 %a, %b + %cmp = icmp sgt i32 %sub, 0 + %cond = select i1 %cmp, i32 %sub, i32 0 + ret i32 %cond +} diff --git a/test/CodeGen/X86/legalize-libcalls.ll b/test/CodeGen/X86/legalize-libcalls.ll new file mode 100644 index 0000000..879dc98 --- /dev/null +++ b/test/CodeGen/X86/legalize-libcalls.ll @@ -0,0 +1,35 @@ +; RUN: llc -march=x86 < %s +; RUN: llc -march=x86-64 < %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128" + +define float @MakeSphere(float %theta.079) nounwind { +entry: + %add36 = fadd float %theta.079, undef + %call = call float @cosf(float %theta.079) nounwind readnone + %call45 = call float @sinf(float %theta.079) nounwind readnone + %call37 = call float @sinf(float %add36) nounwind readnone + store float %call, float* undef, align 8 + store float %call37, float* undef, align 8 + store float %call45, float* undef, align 8 + ret float %add36 +} + +define hidden fastcc void @unroll_loop(i64 %storemerge32129) nounwind { +entry: + call fastcc void @copy_rtx() nounwind + call fastcc void @copy_rtx() nounwind + %tmp225 = alloca i8, i64 %storemerge32129, align 8 ; [#uses=0 type=i8*] + %cmp651201 = icmp slt i64 %storemerge32129, 0 ; [#uses=1 type=i1] + br i1 %cmp651201, label %for.body653.lr.ph, label %if.end638.for.end659_crit_edge + +for.body653.lr.ph: ; preds = %entry + unreachable + +if.end638.for.end659_crit_edge: ; preds = %entry + unreachable +} + +declare float @cosf(float) nounwind readnone +declare float @sinf(float) nounwind readnone +declare hidden fastcc void @copy_rtx() nounwind diff --git a/test/CodeGen/X86/legalize-shift-64.ll b/test/CodeGen/X86/legalize-shift-64.ll new file mode 100644 index 0000000..c9f2fc2 --- /dev/null +++ b/test/CodeGen/X86/legalize-shift-64.ll @@ -0,0 +1,56 @@ +; RUN: llc -mcpu=generic -march=x86 < %s | FileCheck %s + +define i64 @test1(i32 %xx, i32 %test) nounwind { + %conv = zext i32 %xx to i64 + %and = and i32 %test, 7 + %sh_prom = zext i32 %and to i64 + %shl = shl i64 %conv, %sh_prom + ret i64 %shl +; CHECK: test1: +; CHECK: shll %cl, %eax +; CHECK: shrl %edx +; CHECK: xorb $31 +; CHECK: shrl %cl, %edx +} + +define i64 @test2(i64 %xx, i32 %test) nounwind { + %and = and i32 %test, 7 + %sh_prom = zext i32 %and to i64 + %shl = shl i64 %xx, %sh_prom + ret i64 %shl +; CHECK: test2: +; CHECK: shll %cl, %esi +; CHECK: shrl %edx +; CHECK: xorb $31 +; CHECK: shrl %cl, %edx +; CHECK: orl %esi, %edx +; CHECK: shll %cl, %eax +} + +define i64 @test3(i64 %xx, i32 %test) nounwind { + %and = and i32 %test, 7 + %sh_prom = zext i32 %and to i64 + %shr = lshr i64 %xx, %sh_prom + ret i64 %shr +; CHECK: test3: +; CHECK: shrl %cl, %esi +; CHECK: leal (%edx,%edx), %eax +; CHECK: xorb $31, %cl +; CHECK: shll %cl, %eax +; CHECK: orl %esi, %eax +; CHECK: shrl %cl, %edx +} + +define i64 @test4(i64 %xx, i32 %test) nounwind { + %and = and i32 %test, 7 + %sh_prom = zext i32 %and to i64 + %shr = ashr i64 %xx, %sh_prom + ret i64 %shr +; CHECK: test4: +; CHECK: shrl %cl, %esi +; CHECK: leal (%edx,%edx), %eax +; CHECK: xorb $31, %cl +; CHECK: shll %cl, %eax +; CHECK: orl %esi, %eax +; CHECK: sarl %cl, %edx +} diff --git a/test/CodeGen/X86/lit.local.cfg b/test/CodeGen/X86/lit.local.cfg new file mode 100644 index 0000000..a8ad0f1 --- /dev/null +++ b/test/CodeGen/X86/lit.local.cfg @@ -0,0 +1,6 @@ +config.suffixes = ['.ll', '.c', '.cpp'] + +targets = set(config.root.targets_to_build.split()) +if not 'X86' in targets: + config.unsupported = True + diff --git a/test/CodeGen/X86/log2_not_readnone.ll b/test/CodeGen/X86/log2_not_readnone.ll new file mode 100644 index 0000000..5620835 --- /dev/null +++ b/test/CodeGen/X86/log2_not_readnone.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=i386-linux-gnueabi %s -o - | FileCheck %s + +; Log2 and exp2 are string-matched to intrinsics. If they are not declared +; readnone, they can't be changed to intrinsics (because they can change errno). + +declare double @log2(double) +declare double @exp2(double) + +define void @f() { + ; CHECK: calll log2 + %1 = call double @log2(double 0.000000e+00) + ; CHECK: calll exp2 + %2 = call double @exp2(double 0.000000e+00) + ret void +} diff --git a/test/CodeGen/X86/loop-strength-reduce3.ll b/test/CodeGen/X86/loop-strength-reduce3.ll deleted file mode 100644 index d6c265f..0000000 --- a/test/CodeGen/X86/loop-strength-reduce3.ll +++ /dev/null @@ -1,37 +0,0 @@ -; RUN: llc < %s -march=x86 -enable-lsr-nested | grep cmp | grep 240 -; RUN: llc < %s -march=x86 -enable-lsr-nested | grep inc | count 1 - -define i32 @foo(i32 %A, i32 %B, i32 %C, i32 %D) nounwind { -entry: - %tmp2955 = icmp sgt i32 %C, 0 ; <i1> [#uses=1] - br i1 %tmp2955, label %bb26.outer.us, label %bb40.split - -bb26.outer.us: ; preds = %bb26.bb32_crit_edge.us, %entry - %i.044.0.ph.us = phi i32 [ 0, %entry ], [ %indvar.next57, %bb26.bb32_crit_edge.us ] ; <i32> [#uses=2] - %k.1.ph.us = phi i32 [ 0, %entry ], [ %k.0.us, %bb26.bb32_crit_edge.us ] ; <i32> [#uses=1] - %tmp3.us = mul i32 %i.044.0.ph.us, 6 ; <i32> [#uses=1] - br label %bb1.us - -bb1.us: ; preds = %bb1.us, %bb26.outer.us - %j.053.us = phi i32 [ 0, %bb26.outer.us ], [ %tmp25.us, %bb1.us ] ; <i32> [#uses=2] - %k.154.us = phi i32 [ %k.1.ph.us, %bb26.outer.us ], [ %k.0.us, %bb1.us ] ; <i32> [#uses=1] - %tmp5.us = add i32 %tmp3.us, %j.053.us ; <i32> [#uses=1] - %tmp7.us = shl i32 %D, %tmp5.us ; <i32> [#uses=2] - %tmp9.us = icmp eq i32 %tmp7.us, %B ; <i1> [#uses=1] - %tmp910.us = zext i1 %tmp9.us to i32 ; <i32> [#uses=1] - %tmp12.us = and i32 %tmp7.us, %A ; <i32> [#uses=1] - %tmp19.us = and i32 %tmp12.us, %tmp910.us ; <i32> [#uses=1] - %k.0.us = add i32 %tmp19.us, %k.154.us ; <i32> [#uses=3] - %tmp25.us = add i32 %j.053.us, 1 ; <i32> [#uses=2] - %tmp29.us = icmp slt i32 %tmp25.us, %C ; <i1> [#uses=1] - br i1 %tmp29.us, label %bb1.us, label %bb26.bb32_crit_edge.us - -bb26.bb32_crit_edge.us: ; preds = %bb1.us - %indvar.next57 = add i32 %i.044.0.ph.us, 1 ; <i32> [#uses=2] - %exitcond = icmp eq i32 %indvar.next57, 40 ; <i1> [#uses=1] - br i1 %exitcond, label %bb40.split, label %bb26.outer.us - -bb40.split: ; preds = %bb26.bb32_crit_edge.us, %entry - %k.1.lcssa.lcssa.us-lcssa = phi i32 [ %k.0.us, %bb26.bb32_crit_edge.us ], [ 0, %entry ] ; <i32> [#uses=1] - ret i32 %k.1.lcssa.lcssa.us-lcssa -} diff --git a/test/CodeGen/X86/loop-strength-reduce5.ll b/test/CodeGen/X86/loop-strength-reduce5.ll index b07eeb6..d50a668 100644 --- a/test/CodeGen/X86/loop-strength-reduce5.ll +++ b/test/CodeGen/X86/loop-strength-reduce5.ll @@ -11,9 +11,9 @@ entry: bb: ; preds = %bb, %entry %i.014.0 = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=2] %tmp1 = trunc i32 %i.014.0 to i16 ; <i16> [#uses=2] - volatile store i16 %tmp1, i16* @X, align 2 + store volatile i16 %tmp1, i16* @X, align 2 %tmp34 = shl i16 %tmp1, 2 ; <i16> [#uses=1] - volatile store i16 %tmp34, i16* @Y, align 2 + store volatile i16 %tmp34, i16* @Y, align 2 %indvar.next = add i32 %i.014.0, 1 ; <i32> [#uses=2] %exitcond = icmp eq i32 %indvar.next, %N ; <i1> [#uses=1] br i1 %exitcond, label %return, label %bb diff --git a/test/CodeGen/X86/lsr-loop-exit-cond.ll b/test/CodeGen/X86/lsr-loop-exit-cond.ll index 938023f..ebda9f2 100644 --- a/test/CodeGen/X86/lsr-loop-exit-cond.ll +++ b/test/CodeGen/X86/lsr-loop-exit-cond.ll @@ -1,6 +1,8 @@ -; RUN: llc -march=x86-64 < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-darwin < %s | FileCheck %s +; CHECK: t: ; CHECK: decq +; CHECK-NEXT: movl ( ; CHECK-NEXT: jne @Te0 = external global [256 x i32] ; <[256 x i32]*> [#uses=5] @@ -135,3 +137,44 @@ bb2: ; preds = %bb store i8 %92, i8* %93, align 1 ret void } + +; Check that DAGCombiner doesn't mess up the IV update when the exiting value +; is equal to the stride. +; It must not fold (cmp (add iv, 1), 1) --> (cmp iv, 0). + +; CHECK: f: +; CHECK: %for.body +; CHECK: incl [[IV:%e..]] +; CHECK: cmpl $1, [[IV]] +; CHECK: jne +; CHECK: ret + +define i32 @f(i32 %i, i32* nocapture %a) nounwind uwtable readonly ssp { +entry: + %cmp4 = icmp eq i32 %i, 1 + br i1 %cmp4, label %for.end, label %for.body.lr.ph + +for.body.lr.ph: ; preds = %entry + %0 = sext i32 %i to i64 + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.body + %indvars.iv = phi i64 [ %0, %for.body.lr.ph ], [ %indvars.iv.next, %for.body ] + %bi.06 = phi i32 [ 0, %for.body.lr.ph ], [ %i.addr.0.bi.0, %for.body ] + %b.05 = phi i32 [ 0, %for.body.lr.ph ], [ %.b.0, %for.body ] + %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv + %1 = load i32* %arrayidx, align 4 + %cmp1 = icmp ugt i32 %1, %b.05 + %.b.0 = select i1 %cmp1, i32 %1, i32 %b.05 + %2 = trunc i64 %indvars.iv to i32 + %i.addr.0.bi.0 = select i1 %cmp1, i32 %2, i32 %bi.06 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, 1 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %bi.0.lcssa = phi i32 [ 0, %entry ], [ %i.addr.0.bi.0, %for.body ] + ret i32 %bi.0.lcssa +} + diff --git a/test/CodeGen/X86/lsr-nonaffine.ll b/test/CodeGen/X86/lsr-nonaffine.ll index d0d2bbd..d825b5a 100644 --- a/test/CodeGen/X86/lsr-nonaffine.ll +++ b/test/CodeGen/X86/lsr-nonaffine.ll @@ -19,7 +19,7 @@ entry: loop: %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] - volatile store i64 %i, i64* %p + store volatile i64 %i, i64* %p %i.next = add i64 %i, %s %c = icmp slt i64 %i.next, %n br i1 %c, label %loop, label %exit diff --git a/test/CodeGen/X86/lsr-reuse.ll b/test/CodeGen/X86/lsr-reuse.ll index 527a5a6..1311a73 100644 --- a/test/CodeGen/X86/lsr-reuse.ll +++ b/test/CodeGen/X86/lsr-reuse.ll @@ -1,4 +1,5 @@ ; XFAIL: * +; ...should pass. See PR12324: misched bringup ; RUN: llc < %s -march=x86-64 -O3 -asm-verbose=false | FileCheck %s target datalayout = "e-p:64:64:64" target triple = "x86_64-unknown-unknown" diff --git a/test/CodeGen/X86/lsr-sort.ll b/test/CodeGen/X86/lsr-sort.ll index 1f3b59a..b85ddeb 100644 --- a/test/CodeGen/X86/lsr-sort.ll +++ b/test/CodeGen/X86/lsr-sort.ll @@ -12,7 +12,7 @@ entry: bb: ; preds = %bb, %entry %i.03 = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=2] %1 = trunc i32 %i.03 to i16 ; <i16> [#uses=1] - volatile store i16 %1, i16* @X, align 2 + store volatile i16 %1, i16* @X, align 2 %indvar.next = add i32 %i.03, 1 ; <i32> [#uses=2] %exitcond = icmp eq i32 %indvar.next, %N ; <i1> [#uses=1] br i1 %exitcond, label %return, label %bb diff --git a/test/CodeGen/X86/lzcnt.ll b/test/CodeGen/X86/lzcnt.ll index e5a55ab..2faa24a 100644 --- a/test/CodeGen/X86/lzcnt.ll +++ b/test/CodeGen/X86/lzcnt.ll @@ -1,38 +1,62 @@ ; RUN: llc < %s -march=x86-64 -mattr=+lzcnt | FileCheck %s -define i32 @t1(i32 %x) nounwind { - %tmp = tail call i32 @llvm.ctlz.i32( i32 %x ) - ret i32 %tmp +declare i8 @llvm.ctlz.i8(i8, i1) nounwind readnone +declare i16 @llvm.ctlz.i16(i16, i1) nounwind readnone +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone +declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone + +define i8 @t1(i8 %x) nounwind { + %tmp = tail call i8 @llvm.ctlz.i8( i8 %x, i1 false ) + ret i8 %tmp ; CHECK: t1: ; CHECK: lzcntl } -declare i32 @llvm.ctlz.i32(i32) nounwind readnone - define i16 @t2(i16 %x) nounwind { - %tmp = tail call i16 @llvm.ctlz.i16( i16 %x ) + %tmp = tail call i16 @llvm.ctlz.i16( i16 %x, i1 false ) ret i16 %tmp ; CHECK: t2: ; CHECK: lzcntw } -declare i16 @llvm.ctlz.i16(i16) nounwind readnone +define i32 @t3(i32 %x) nounwind { + %tmp = tail call i32 @llvm.ctlz.i32( i32 %x, i1 false ) + ret i32 %tmp +; CHECK: t3: +; CHECK: lzcntl +} -define i64 @t3(i64 %x) nounwind { - %tmp = tail call i64 @llvm.ctlz.i64( i64 %x ) +define i64 @t4(i64 %x) nounwind { + %tmp = tail call i64 @llvm.ctlz.i64( i64 %x, i1 false ) ret i64 %tmp -; CHECK: t3: +; CHECK: t4: ; CHECK: lzcntq } -declare i64 @llvm.ctlz.i64(i64) nounwind readnone - -define i8 @t4(i8 %x) nounwind { - %tmp = tail call i8 @llvm.ctlz.i8( i8 %x ) +define i8 @t5(i8 %x) nounwind { + %tmp = tail call i8 @llvm.ctlz.i8( i8 %x, i1 true ) ret i8 %tmp -; CHECK: t4: +; CHECK: t5: +; CHECK: lzcntl +} + +define i16 @t6(i16 %x) nounwind { + %tmp = tail call i16 @llvm.ctlz.i16( i16 %x, i1 true ) + ret i16 %tmp +; CHECK: t6: ; CHECK: lzcntw } -declare i8 @llvm.ctlz.i8(i8) nounwind readnone +define i32 @t7(i32 %x) nounwind { + %tmp = tail call i32 @llvm.ctlz.i32( i32 %x, i1 true ) + ret i32 %tmp +; CHECK: t7: +; CHECK: lzcntl +} +define i64 @t8(i64 %x) nounwind { + %tmp = tail call i64 @llvm.ctlz.i64( i64 %x, i1 true ) + ret i64 %tmp +; CHECK: t8: +; CHECK: lzcntq +} diff --git a/test/CodeGen/X86/machine-cp.ll b/test/CodeGen/X86/machine-cp.ll new file mode 100644 index 0000000..54fa01c --- /dev/null +++ b/test/CodeGen/X86/machine-cp.ll @@ -0,0 +1,36 @@ +; RUN: llc -mtriple=x86_64-apple-macosx -mcpu=nocona < %s | FileCheck %s + +; After tail duplication, two copies in an early exit BB can be cancelled out. +; rdar://10640363 +define i32 @t1(i32 %a, i32 %b) nounwind { +entry: +; CHECK: t1: +; CHECK: jne + %cmp1 = icmp eq i32 %b, 0 + br i1 %cmp1, label %while.end, label %while.body + +; CHECK: BB +; CHECK-NOT: mov +; CHECK: ret + +while.body: ; preds = %entry, %while.body + %a.addr.03 = phi i32 [ %b.addr.02, %while.body ], [ %a, %entry ] + %b.addr.02 = phi i32 [ %rem, %while.body ], [ %b, %entry ] + %rem = srem i32 %a.addr.03, %b.addr.02 + %cmp = icmp eq i32 %rem, 0 + br i1 %cmp, label %while.end, label %while.body + +while.end: ; preds = %while.body, %entry + %a.addr.0.lcssa = phi i32 [ %a, %entry ], [ %b.addr.02, %while.body ] + ret i32 %a.addr.0.lcssa +} + +; Two movdqa (from phi-elimination) in the entry BB cancels out. +; rdar://10428165 +define <8 x i16> @t2(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { +entry: +; CHECK: t2: +; CHECK-NOT: movdqa + %tmp8 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 undef, i32 undef, i32 7, i32 2, i32 8, i32 undef, i32 undef , i32 undef > + ret <8 x i16> %tmp8 +} diff --git a/test/CodeGen/X86/machine-cse.ll b/test/CodeGen/X86/machine-cse.ll index d819fc8..a757cde 100644 --- a/test/CodeGen/X86/machine-cse.ll +++ b/test/CodeGen/X86/machine-cse.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=x86_64-apple-darwin < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-apple-macosx < %s | FileCheck %s ; rdar://7610418 %ptr = type { i8* } @@ -77,3 +77,25 @@ bb.nph743.us: ; preds = %for.body53.us, %if. sw.bb307: ; preds = %sw.bb, %entry ret void } + +; CSE physical register defining instruction across MBB boundary. +; rdar://10660865 +define i32 @cross_mbb_phys_cse(i32 %a, i32 %b) nounwind ssp { +entry: +; CHECK: cross_mbb_phys_cse: +; CHECK: cmpl +; CHECK: ja + %cmp = icmp ugt i32 %a, %b + br i1 %cmp, label %return, label %if.end + +if.end: ; preds = %entry +; CHECK-NOT: cmpl +; CHECK: sbbl + %cmp1 = icmp ult i32 %a, %b + %. = sext i1 %cmp1 to i32 + br label %return + +return: ; preds = %if.end, %entry + %retval.0 = phi i32 [ 1, %entry ], [ %., %if.end ] + ret i32 %retval.0 +} diff --git a/test/CodeGen/X86/masked-iv-safe.ll b/test/CodeGen/X86/masked-iv-safe.ll index 0b4d73a..a7b036e 100644 --- a/test/CodeGen/X86/masked-iv-safe.ll +++ b/test/CodeGen/X86/masked-iv-safe.ll @@ -1,12 +1,12 @@ -; RUN: llc < %s -march=x86-64 > %t +; RUN: llc < %s -mcpu=generic -march=x86-64 > %t ; RUN: not grep and %t ; RUN: not grep movz %t ; RUN: not grep sar %t ; RUN: not grep shl %t -; RUN: grep add %t | count 2 +; RUN: grep add %t | count 1 ; RUN: grep inc %t | count 4 ; RUN: grep dec %t | count 2 -; RUN: grep lea %t | count 2 +; RUN: grep lea %t | count 3 ; Optimize away zext-inreg and sext-inreg on the loop induction ; variable using trip-count information. diff --git a/test/CodeGen/X86/mcinst-avx-lowering.ll b/test/CodeGen/X86/mcinst-avx-lowering.ll new file mode 100644 index 0000000..41f96e8 --- /dev/null +++ b/test/CodeGen/X86/mcinst-avx-lowering.ll @@ -0,0 +1,19 @@ +; RUN: llc -mtriple=x86_64-apple-macosx10 -mattr=avx -show-mc-encoding < %s | FileCheck %s + +define i64 @t1(double %d_ivar) nounwind uwtable ssp { +entry: +; CHECK: t1 + %0 = bitcast double %d_ivar to i64 +; CHECK: vmovd +; CHECK: encoding: [0xc4,0xe1,0xf9,0x7e,0xc0] + ret i64 %0 +} + +define double @t2(i64 %d_ivar) nounwind uwtable ssp { +entry: +; CHECK: t2 + %0 = bitcast i64 %d_ivar to double +; CHECK: vmovd +; CHECK: encoding: [0xc4,0xe1,0xf9,0x6e,0xc7] + ret double %0 +} diff --git a/test/CodeGen/X86/memcpy.ll b/test/CodeGen/X86/memcpy.ll index f43b0bf..86c6862 100644 --- a/test/CodeGen/X86/memcpy.ll +++ b/test/CodeGen/X86/memcpy.ll @@ -79,3 +79,16 @@ entry: ; LINUX movq } + +@.str = private unnamed_addr constant [30 x i8] c"\00aaaaaaaaaaaaaaaaaaaaaaaaaaaa\00", align 1 + +define void @test5(i8* nocapture %C) nounwind uwtable ssp { +entry: + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %C, i8* getelementptr inbounds ([30 x i8]* @.str, i64 0, i64 0), i64 16, i32 1, i1 false) + ret void + +; DARWIN: movabsq $7016996765293437281 +; DARWIN: movabsq $7016996765293437184 +} + + diff --git a/test/CodeGen/X86/misched-new.ll b/test/CodeGen/X86/misched-new.ll new file mode 100644 index 0000000..8f2f6f7 --- /dev/null +++ b/test/CodeGen/X86/misched-new.ll @@ -0,0 +1,27 @@ +; RUN: llc -march=x86-64 -mcpu=core2 -enable-misched -misched=shuffle -misched-bottomup < %s +; REQUIRES: asserts +; +; Interesting MachineScheduler cases. +; +; FIXME: There should be an assert in the coalescer that we're not rematting +; "not-quite-dead" copies, but that breaks a lot of tests <rdar://problem/11148682>. + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind + +; From oggenc. +; After coalescing, we have a dead superreg (RAX) definition. +; +; CHECK: xorl %esi, %esi +; CHECK: movl $32, %ecx +; CHECK: rep;movsl +define fastcc void @_preextrapolate_helper() nounwind uwtable ssp { +entry: + br i1 undef, label %for.cond.preheader, label %if.end + +for.cond.preheader: ; preds = %entry + call void @llvm.memcpy.p0i8.p0i8.i64(i8* undef, i8* null, i64 128, i32 4, i1 false) nounwind + unreachable + +if.end: ; preds = %entry + ret void +} diff --git a/test/CodeGen/X86/mmx-builtins.ll b/test/CodeGen/X86/mmx-builtins.ll index 3ac0e4e..8b7200d 100644 --- a/test/CodeGen/X86/mmx-builtins.ll +++ b/test/CodeGen/X86/mmx-builtins.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=x86 -mattr=+mmx,+ssse3 | FileCheck %s +; RUN: llc < %s -march=x86 -mattr=+avx | FileCheck %s declare x86_mmx @llvm.x86.ssse3.phadd.w(x86_mmx, x86_mmx) nounwind readnone diff --git a/test/CodeGen/X86/mmx-pinsrw.ll b/test/CodeGen/X86/mmx-pinsrw.ll index 6062b50..d9c7c67 100644 --- a/test/CodeGen/X86/mmx-pinsrw.ll +++ b/test/CodeGen/X86/mmx-pinsrw.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mattr=+mmx,+sse2 | grep pinsrw | count 1 +; RUN: llc < %s -mtriple=x86_64-linux -mcpu=corei7 | grep pinsr ; PR2562 external global i16 ; <i16*>:0 [#uses=1] diff --git a/test/CodeGen/X86/mmx-vzmovl-2.ll b/test/CodeGen/X86/mmx-vzmovl-2.ll deleted file mode 100644 index a7ce7d9..0000000 --- a/test/CodeGen/X86/mmx-vzmovl-2.ll +++ /dev/null @@ -1,29 +0,0 @@ -; RUN: llc < %s -march=x86-64 -mattr=+mmx,+sse2 | grep pxor -; RUN: llc < %s -march=x86-64 -mattr=+mmx,+sse2 | grep punpckldq - - %struct.vS1024 = type { [8 x <4 x i32>] } - %struct.vS512 = type { [4 x <4 x i32>] } - -declare x86_mmx @llvm.x86.mmx.psrli.q(x86_mmx, i32) nounwind readnone - -define void @t() nounwind { -entry: - br label %bb554 - -bb554: ; preds = %bb554, %entry - %sum.0.reg2mem.0 = phi <1 x i64> [ %tmp562, %bb554 ], [ zeroinitializer, %entry ] ; <<1 x i64>> [#uses=1] - %0 = load x86_mmx* null, align 8 ; <<1 x i64>> [#uses=2] - %1 = bitcast x86_mmx %0 to <2 x i32> ; <<2 x i32>> [#uses=1] - %tmp555 = and <2 x i32> %1, < i32 -1, i32 0 > ; <<2 x i32>> [#uses=1] - %2 = bitcast <2 x i32> %tmp555 to x86_mmx ; <<1 x i64>> [#uses=1] - %3 = call x86_mmx @llvm.x86.mmx.psrli.q(x86_mmx %0, i32 32) nounwind readnone ; <<1 x i64>> [#uses=1] - store <1 x i64> %sum.0.reg2mem.0, <1 x i64>* null - %tmp3 = bitcast x86_mmx %2 to <1 x i64> - %tmp558 = add <1 x i64> %sum.0.reg2mem.0, %tmp3 ; <<1 x i64>> [#uses=1] - %tmp5 = bitcast <1 x i64> %tmp558 to x86_mmx - %4 = call x86_mmx @llvm.x86.mmx.psrli.q(x86_mmx %tmp5, i32 32) nounwind readnone ; <<1 x i64>> [#uses=1] - %tmp6 = bitcast x86_mmx %4 to <1 x i64> - %tmp7 = bitcast x86_mmx %3 to <1 x i64> - %tmp562 = add <1 x i64> %tmp6, %tmp7 ; <<1 x i64>> [#uses=1] - br label %bb554 -} diff --git a/test/CodeGen/X86/mmx-vzmovl.ll b/test/CodeGen/X86/mmx-vzmovl.ll deleted file mode 100644 index 191e261..0000000 --- a/test/CodeGen/X86/mmx-vzmovl.ll +++ /dev/null @@ -1,15 +0,0 @@ -; RUN: llc < %s -march=x86-64 -mattr=+mmx,+sse2 | grep movq | count 2 -; There are no MMX operations here; this is promoted to XMM. - -define void @foo(<1 x i64>* %a, <1 x i64>* %b) nounwind { -entry: - %0 = load <1 x i64>* %a, align 8 ; <<1 x i64>> [#uses=1] - %1 = bitcast <1 x i64> %0 to <2 x i32> ; <<2 x i32>> [#uses=1] - %2 = and <2 x i32> %1, < i32 -1, i32 0 > ; <<2 x i32>> [#uses=1] - %3 = bitcast <2 x i32> %2 to <1 x i64> ; <<1 x i64>> [#uses=1] - store <1 x i64> %3, <1 x i64>* %b, align 8 - br label %bb2 - -bb2: ; preds = %entry - ret void -} diff --git a/test/CodeGen/X86/movmsk.ll b/test/CodeGen/X86/movmsk.ll index 2368548..928ad03 100644 --- a/test/CodeGen/X86/movmsk.ll +++ b/test/CodeGen/X86/movmsk.ll @@ -78,6 +78,22 @@ entry: ret i32 %shr.i } +; PR11570 +define void @float_call_signbit(double %n) { +entry: +; FIXME: This should also use movmskps; we don't form the FGETSIGN node +; in this case, though. +; CHECK: float_call_signbit: +; CHECK: movd %xmm0, %rdi +; FIXME + %t0 = bitcast double %n to i64 + %tobool.i.i.i.i = icmp slt i64 %t0, 0 + tail call void @float_call_signbit_callee(i1 zeroext %tobool.i.i.i.i) + ret void +} +declare void @float_call_signbit_callee(i1 zeroext) + + ; rdar://10247336 ; movmskp{s|d} only set low 4/2 bits, high bits are known zero diff --git a/test/CodeGen/X86/multiple-loop-post-inc.ll b/test/CodeGen/X86/multiple-loop-post-inc.ll index 51a0611..4f7e28a 100644 --- a/test/CodeGen/X86/multiple-loop-post-inc.ll +++ b/test/CodeGen/X86/multiple-loop-post-inc.ll @@ -1,6 +1,10 @@ ; RUN: llc -asm-verbose=false -disable-branch-fold -disable-code-place -disable-tail-duplicate -march=x86-64 < %s | FileCheck %s ; rdar://7236213 +; Xfailed now that scheduler 2-address hack is disabled a lea is generated. +; The code isn't any worse though. +; XFAIL: * + ; CodeGen shouldn't require any lea instructions inside the marked loop. ; It should properly set up post-increment uses and do coalescing for ; the induction variables. diff --git a/test/CodeGen/X86/nancvt.ll b/test/CodeGen/X86/nancvt.ll index 82b7331..8036710 100644 --- a/test/CodeGen/X86/nancvt.ll +++ b/test/CodeGen/X86/nancvt.ll @@ -52,8 +52,8 @@ bb: ; preds = %bb23 %tmp17 = ashr i64 %tmp16, %.cast ; <i64> [#uses=1] %tmp1718 = trunc i64 %tmp17 to i32 ; <i32> [#uses=1] %tmp19 = getelementptr [10 x i8]* @.str, i32 0, i32 0 ; <i8*> [#uses=1] - volatile store i32 %tmp1718, i32* @var - volatile store i32 %tmp13, i32* @var + store volatile i32 %tmp1718, i32* @var + store volatile i32 %tmp13, i32* @var %tmp21 = load i32* %i, align 4 ; <i32> [#uses=1] %tmp22 = add i32 %tmp21, 1 ; <i32> [#uses=1] store i32 %tmp22, i32* %i, align 4 @@ -86,7 +86,7 @@ bb28: ; preds = %bb46 %tmp3940 = bitcast float* %tmp39 to i32* ; <i32*> [#uses=1] %tmp41 = load i32* %tmp3940, align 4 ; <i32> [#uses=1] %tmp42 = getelementptr [6 x i8]* @.str1, i32 0, i32 0 ; <i8*> [#uses=1] - volatile store i32 %tmp41, i32* @var + store volatile i32 %tmp41, i32* @var %tmp44 = load i32* %i, align 4 ; <i32> [#uses=1] %tmp45 = add i32 %tmp44, 1 ; <i32> [#uses=1] store i32 %tmp45, i32* %i, align 4 @@ -127,8 +127,8 @@ bb52: ; preds = %bb78 %tmp72 = ashr i64 %tmp70, %.cast71 ; <i64> [#uses=1] %tmp7273 = trunc i64 %tmp72 to i32 ; <i32> [#uses=1] %tmp74 = getelementptr [10 x i8]* @.str, i32 0, i32 0 ; <i8*> [#uses=1] - volatile store i32 %tmp7273, i32* @var - volatile store i32 %tmp66, i32* @var + store volatile i32 %tmp7273, i32* @var + store volatile i32 %tmp66, i32* @var %tmp76 = load i32* %i, align 4 ; <i32> [#uses=1] %tmp77 = add i32 %tmp76, 1 ; <i32> [#uses=1] store i32 %tmp77, i32* %i, align 4 @@ -161,7 +161,7 @@ bb84: ; preds = %bb101 %tmp9495 = bitcast float* %tmp94 to i32* ; <i32*> [#uses=1] %tmp96 = load i32* %tmp9495, align 4 ; <i32> [#uses=1] %tmp97 = getelementptr [6 x i8]* @.str1, i32 0, i32 0 ; <i8*> [#uses=1] - volatile store i32 %tmp96, i32* @var + store volatile i32 %tmp96, i32* @var %tmp99 = load i32* %i, align 4 ; <i32> [#uses=1] %tmp100 = add i32 %tmp99, 1 ; <i32> [#uses=1] store i32 %tmp100, i32* %i, align 4 diff --git a/test/CodeGen/X86/narrow-shl-load.ll b/test/CodeGen/X86/narrow-shl-load.ll index ef27cbc..7822453 100644 --- a/test/CodeGen/X86/narrow-shl-load.ll +++ b/test/CodeGen/X86/narrow-shl-load.ll @@ -67,7 +67,7 @@ declare void @exit(i32) noreturn ; DAG Combiner can't fold this into a load of the 1'th byte. ; PR8757 define i32 @test3(i32 *%P) nounwind ssp { - volatile store i32 128, i32* %P + store volatile i32 128, i32* %P %tmp4.pre = load i32* %P %phitmp = trunc i32 %tmp4.pre to i16 %phitmp13 = shl i16 %phitmp, 8 diff --git a/test/CodeGen/X86/negate-add-zero.ll b/test/CodeGen/X86/negate-add-zero.ll index c3f412e..92850f2 100644 --- a/test/CodeGen/X86/negate-add-zero.ll +++ b/test/CodeGen/X86/negate-add-zero.ll @@ -486,10 +486,6 @@ declare void @_ZN7CDSListIP9HingeNodeEC1Eii(%"struct.CDSList<HingeNode*>"*, i32, declare i8* @_Znwm(i32) -declare i8* @llvm.eh.exception() nounwind - -declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind - declare i32 @llvm.eh.typeid.for.i32(i8*) nounwind declare void @_ZdlPv(i8*) nounwind diff --git a/test/CodeGen/X86/no-cfi.ll b/test/CodeGen/X86/no-cfi.ll index f9985d4..5bb9bb2 100644 --- a/test/CodeGen/X86/no-cfi.ll +++ b/test/CodeGen/X86/no-cfi.ll @@ -24,15 +24,11 @@ invoke.cont: ret void lpad: - %exn = call i8* @llvm.eh.exception() nounwind - %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) nounwind + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + catch i8* null ret void } declare i32 @foo() -declare i8* @llvm.eh.exception() nounwind readonly - declare i32 @__gxx_personality_v0(...) - -declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind diff --git a/test/CodeGen/X86/nontemporal.ll b/test/CodeGen/X86/nontemporal.ll index 1d09535..ae04435 100644 --- a/test/CodeGen/X86/nontemporal.ll +++ b/test/CodeGen/X86/nontemporal.ll @@ -3,13 +3,16 @@ define void @f(<4 x float> %A, i8* %B, <2 x double> %C, i32 %D, <2 x i64> %E) { ; CHECK: movntps %cast = bitcast i8* %B to <4 x float>* - store <4 x float> %A, <4 x float>* %cast, align 16, !nontemporal !0 + %A2 = fadd <4 x float> %A, <float 0x0, float 0x0, float 0x0, float 0x4200000000000000> + store <4 x float> %A2, <4 x float>* %cast, align 16, !nontemporal !0 ; CHECK: movntdq %cast1 = bitcast i8* %B to <2 x i64>* - store <2 x i64> %E, <2 x i64>* %cast1, align 16, !nontemporal !0 + %E2 = add <2 x i64> %E, <i64 1, i64 2> + store <2 x i64> %E2, <2 x i64>* %cast1, align 16, !nontemporal !0 ; CHECK: movntpd %cast2 = bitcast i8* %B to <2 x double>* - store <2 x double> %C, <2 x double>* %cast2, align 16, !nontemporal !0 + %C2 = fadd <2 x double> %C, <double 0x0, double 0x4200000000000000> + store <2 x double> %C2, <2 x double>* %cast2, align 16, !nontemporal !0 ; CHECK: movnti %cast3 = bitcast i8* %B to i32* store i32 %D, i32* %cast3, align 16, !nontemporal !0 diff --git a/test/CodeGen/X86/null-streamer.ll b/test/CodeGen/X86/null-streamer.ll new file mode 100644 index 0000000..7c0e82f --- /dev/null +++ b/test/CodeGen/X86/null-streamer.ll @@ -0,0 +1,11 @@ +; Check the MCNullStreamer operates correctly, at least on a minimal test case. +; +; RUN: llc -filetype=null -o %t -march=x86 %s + +define void @f0() { + ret void +} + +define void @f1() { + ret void +} diff --git a/test/CodeGen/X86/objc-gc-module-flags.ll b/test/CodeGen/X86/objc-gc-module-flags.ll new file mode 100644 index 0000000..8cb2c03 --- /dev/null +++ b/test/CodeGen/X86/objc-gc-module-flags.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s + +; CHECK: .section __DATA,__objc_imageinfo,regular,no_dead_strip +; CHECK-NEXT: L_OBJC_IMAGE_INFO: +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 + +!llvm.module.flags = !{!0, !1, !2, !3} + +!0 = metadata !{i32 1, metadata !"Objective-C Version", i32 2} +!1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0} +!2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"} +!3 = metadata !{i32 1, metadata !"Objective-C Garbage Collection", i32 2} diff --git a/test/CodeGen/X86/object-size.ll b/test/CodeGen/X86/object-size.ll index 0493edc..8f1eabd 100644 --- a/test/CodeGen/X86/object-size.ll +++ b/test/CodeGen/X86/object-size.ll @@ -1,4 +1,4 @@ -; RUN: llc -O0 -regalloc=linearscan < %s -march=x86-64 | FileCheck %s -check-prefix=X64 +; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s -check-prefix=X64 ; ModuleID = 'ts.c' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -12,8 +12,8 @@ entry: %tmp = load i8** @p ; <i8*> [#uses=1] %0 = call i64 @llvm.objectsize.i64(i8* %tmp, i1 0) ; <i64> [#uses=1] %cmp = icmp ne i64 %0, -1 ; <i1> [#uses=1] -; X64: movabsq $-1, %rax -; X64: cmpq $-1, %rax +; X64: movabsq $-1, [[RAX:%r..]] +; X64: cmpq $-1, [[RAX]] br i1 %cmp, label %cond.true, label %cond.false cond.true: ; preds = %entry diff --git a/test/CodeGen/X86/odr_comdat.ll b/test/CodeGen/X86/odr_comdat.ll new file mode 100644 index 0000000..547334c --- /dev/null +++ b/test/CodeGen/X86/odr_comdat.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s -check-prefix=X86LINUX + +; Checking that a comdat group gets generated correctly for a static member +; of instantiated C++ templates. +; see http://sourcery.mentor.com/public/cxx-abi/abi.html#vague-itemplate +; section 5.2.6 Instantiated templates +; "Any static member data object is emitted in a COMDAT identified by its mangled +; name, in any object file with a reference to its name symbol." + +; Case 1: variable is not explicitly initialized, and ends up in a .bss section +; X86LINUX: .section .bss._ZN1CIiE1iE,"aGw",@nobits,_ZN1CIiE1iE,comdat +@_ZN1CIiE1iE = weak_odr global i32 0, align 4 + +; Case 2: variable is explicitly initialized, and ends up in a .data section +; X86LINUX: .section .data._ZN1CIiE1jE,"aGw",@progbits,_ZN1CIiE1jE,comdat +@_ZN1CIiE1jE = weak_odr global i32 12, align 4 diff --git a/test/CodeGen/X86/optimize-max-3.ll b/test/CodeGen/X86/optimize-max-3.ll index e42aa9d..d092916 100644 --- a/test/CodeGen/X86/optimize-max-3.ll +++ b/test/CodeGen/X86/optimize-max-3.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mtriple=x86_64-linux -asm-verbose=false | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-win32 -asm-verbose=false | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -asm-verbose=false | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-win32 -asm-verbose=false | FileCheck %s ; LSR's OptimizeMax should eliminate the select (max). diff --git a/test/CodeGen/X86/overlap-shift.ll b/test/CodeGen/X86/overlap-shift.ll index c1fc041..d185af1 100644 --- a/test/CodeGen/X86/overlap-shift.ll +++ b/test/CodeGen/X86/overlap-shift.ll @@ -13,7 +13,7 @@ define i32 @test1(i32 %X) { %Z = shl i32 %X, 2 ; <i32> [#uses=1] - volatile store i32 %Z, i32* @G + store volatile i32 %Z, i32* @G ret i32 %X } diff --git a/test/CodeGen/X86/peep-test-3.ll b/test/CodeGen/X86/peep-test-3.ll index 528c4bc..a379980 100644 --- a/test/CodeGen/X86/peep-test-3.ll +++ b/test/CodeGen/X86/peep-test-3.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -post-RA-scheduler=false | FileCheck %s +; RUN: llc < %s -mcpu=generic -march=x86 -post-RA-scheduler=false | FileCheck %s ; rdar://7226797 ; LLVM should omit the testl and use the flags result from the orl. diff --git a/test/CodeGen/X86/peep-vector-extract-insert.ll b/test/CodeGen/X86/peep-vector-extract-insert.ll index 5e18044..d48a331 100644 --- a/test/CodeGen/X86/peep-vector-extract-insert.ll +++ b/test/CodeGen/X86/peep-vector-extract-insert.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 | grep {pxor %xmm0, %xmm0} | count 2 +; RUN: llc < %s -march=x86-64 | grep {xorps %xmm0, %xmm0} | count 2 define float @foo(<4 x float> %a) { %b = insertelement <4 x float> %a, float 0.0, i32 3 diff --git a/test/CodeGen/X86/personality_size.ll b/test/CodeGen/X86/personality_size.ll new file mode 100644 index 0000000..30a5d39 --- /dev/null +++ b/test/CodeGen/X86/personality_size.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -relocation-model=pic -disable-cfi -mtriple=x86_64-pc-solaris2.11 -disable-cgp-branch-opts | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -relocation-model=pic -disable-cfi -mtriple=i386-pc-solaris2.11 -disable-cgp-branch-opts | FileCheck %s -check-prefix=X32 +; PR1632 + +define void @_Z1fv() { +entry: + invoke void @_Z1gv() + to label %return unwind label %unwind + +unwind: ; preds = %entry + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup + ret void + +return: ; preds = %eh_then, %entry + ret void +} + +declare void @_Z1gv() + +declare i32 @__gxx_personality_v0(...) + +; X64: .size DW.ref.__gxx_personality_v0, 8 +; X64: .quad __gxx_personality_v0 + +; X32: .size DW.ref.__gxx_personality_v0, 4 +; X32: .long __gxx_personality_v0 + diff --git a/test/CodeGen/X86/phaddsub.ll b/test/CodeGen/X86/phaddsub.ll new file mode 100644 index 0000000..62d85f7 --- /dev/null +++ b/test/CodeGen/X86/phaddsub.ll @@ -0,0 +1,170 @@ +; RUN: llc < %s -march=x86-64 -mattr=+ssse3,-avx | FileCheck %s -check-prefix=SSSE3 +; RUN: llc < %s -march=x86-64 -mattr=-ssse3,+avx | FileCheck %s -check-prefix=AVX + +; SSSE3: phaddw1: +; SSSE3-NOT: vphaddw +; SSSE3: phaddw +; AVX: phaddw1: +; AVX: vphaddw +define <8 x i16> @phaddw1(<8 x i16> %x, <8 x i16> %y) { + %a = shufflevector <8 x i16> %x, <8 x i16> %y, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14> + %b = shufflevector <8 x i16> %x, <8 x i16> %y, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15> + %r = add <8 x i16> %a, %b + ret <8 x i16> %r +} + +; SSSE3: phaddw2: +; SSSE3-NOT: vphaddw +; SSSE3: phaddw +; AVX: phaddw2: +; AVX: vphaddw +define <8 x i16> @phaddw2(<8 x i16> %x, <8 x i16> %y) { + %a = shufflevector <8 x i16> %x, <8 x i16> %y, <8 x i32> <i32 1, i32 2, i32 5, i32 6, i32 9, i32 10, i32 13, i32 14> + %b = shufflevector <8 x i16> %y, <8 x i16> %x, <8 x i32> <i32 8, i32 11, i32 12, i32 15, i32 0, i32 3, i32 4, i32 7> + %r = add <8 x i16> %a, %b + ret <8 x i16> %r +} + +; SSSE3: phaddd1: +; SSSE3-NOT: vphaddd +; SSSE3: phaddd +; AVX: phaddd1: +; AVX: vphaddd +define <4 x i32> @phaddd1(<4 x i32> %x, <4 x i32> %y) { + %a = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 2, i32 4, i32 6> + %b = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 1, i32 3, i32 5, i32 7> + %r = add <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phaddd2: +; SSSE3-NOT: vphaddd +; SSSE3: phaddd +; AVX: phaddd2: +; AVX: vphaddd +define <4 x i32> @phaddd2(<4 x i32> %x, <4 x i32> %y) { + %a = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 1, i32 2, i32 5, i32 6> + %b = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 4, i32 7, i32 0, i32 3> + %r = add <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phaddd3: +; SSSE3-NOT: vphaddd +; SSSE3: phaddd +; AVX: phaddd3: +; AVX: vphaddd +define <4 x i32> @phaddd3(<4 x i32> %x) { + %a = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 2, i32 4, i32 6> + %b = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 3, i32 5, i32 7> + %r = add <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phaddd4: +; SSSE3-NOT: vphaddd +; SSSE3: phaddd +; AVX: phaddd4: +; AVX: vphaddd +define <4 x i32> @phaddd4(<4 x i32> %x) { + %a = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 undef, i32 undef> + %b = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 1, i32 3, i32 undef, i32 undef> + %r = add <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phaddd5: +; SSSE3-NOT: vphaddd +; SSSE3: phaddd +; AVX: phaddd5: +; AVX: vphaddd +define <4 x i32> @phaddd5(<4 x i32> %x) { + %a = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 3, i32 undef, i32 undef> + %b = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 undef, i32 undef> + %r = add <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phaddd6: +; SSSE3-NOT: vphaddd +; SSSE3: phaddd +; AVX: phaddd6: +; AVX: vphaddd +define <4 x i32> @phaddd6(<4 x i32> %x) { + %a = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef> + %b = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> + %r = add <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phaddd7: +; SSSE3-NOT: vphaddd +; SSSE3: phaddd +; AVX: phaddd7: +; AVX: vphaddd +define <4 x i32> @phaddd7(<4 x i32> %x) { + %a = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 3, i32 undef, i32 undef> + %b = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 2, i32 undef, i32 undef> + %r = add <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phsubw1: +; SSSE3-NOT: vphsubw +; SSSE3: phsubw +; AVX: phsubw1: +; AVX: vphsubw +define <8 x i16> @phsubw1(<8 x i16> %x, <8 x i16> %y) { + %a = shufflevector <8 x i16> %x, <8 x i16> %y, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14> + %b = shufflevector <8 x i16> %x, <8 x i16> %y, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15> + %r = sub <8 x i16> %a, %b + ret <8 x i16> %r +} + +; SSSE3: phsubd1: +; SSSE3-NOT: vphsubd +; SSSE3: phsubd +; AVX: phsubd1: +; AVX: vphsubd +define <4 x i32> @phsubd1(<4 x i32> %x, <4 x i32> %y) { + %a = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 2, i32 4, i32 6> + %b = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 1, i32 3, i32 5, i32 7> + %r = sub <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phsubd2: +; SSSE3-NOT: vphsubd +; SSSE3: phsubd +; AVX: phsubd2: +; AVX: vphsubd +define <4 x i32> @phsubd2(<4 x i32> %x) { + %a = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 2, i32 4, i32 6> + %b = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 undef, i32 3, i32 5, i32 7> + %r = sub <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phsubd3: +; SSSE3-NOT: vphsubd +; SSSE3: phsubd +; AVX: phsubd3: +; AVX: vphsubd +define <4 x i32> @phsubd3(<4 x i32> %x) { + %a = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 undef, i32 undef> + %b = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 1, i32 3, i32 undef, i32 undef> + %r = sub <4 x i32> %a, %b + ret <4 x i32> %r +} + +; SSSE3: phsubd4: +; SSSE3-NOT: vphsubd +; SSSE3: phsubd +; AVX: phsubd4: +; AVX: vphsubd +define <4 x i32> @phsubd4(<4 x i32> %x) { + %a = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef> + %b = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> + %r = sub <4 x i32> %a, %b + ret <4 x i32> %r +} diff --git a/test/CodeGen/X86/pic.ll b/test/CodeGen/X86/pic.ll index fb60ac2..fc06309 100644 --- a/test/CodeGen/X86/pic.ll +++ b/test/CodeGen/X86/pic.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=i686-pc-linux-gnu -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false | FileCheck %s -check-prefix=LINUX +; RUN: llc < %s -mcpu=generic -mtriple=i686-pc-linux-gnu -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false | FileCheck %s -check-prefix=LINUX @ptr = external global i32* @dst = external global i32 diff --git a/test/CodeGen/X86/pointer-vector.ll b/test/CodeGen/X86/pointer-vector.ll new file mode 100644 index 0000000..cc1df2f --- /dev/null +++ b/test/CodeGen/X86/pointer-vector.ll @@ -0,0 +1,138 @@ +; RUN: llc < %s -mtriple=i686-linux -mcpu=corei7 | FileCheck %s +; RUN: opt -instsimplify %s -disable-output + +;CHECK: SHUFF0 +define <8 x i32*> @SHUFF0(<4 x i32*> %ptrv) nounwind { +entry: + %G = shufflevector <4 x i32*> %ptrv, <4 x i32*> %ptrv, <8 x i32> <i32 2, i32 7, i32 1, i32 2, i32 4, i32 5, i32 1, i32 1> +;CHECK: pshufd + ret <8 x i32*> %G +;CHECK: ret +} + +;CHECK: SHUFF1 +define <4 x i32*> @SHUFF1(<4 x i32*> %ptrv) nounwind { +entry: + %G = shufflevector <4 x i32*> %ptrv, <4 x i32*> %ptrv, <4 x i32> <i32 2, i32 7, i32 7, i32 2> +;CHECK: pshufd + ret <4 x i32*> %G +;CHECK: ret +} + +;CHECK: SHUFF3 +define <4 x i8*> @SHUFF3(<4 x i8*> %ptrv) nounwind { +entry: + %G = shufflevector <4 x i8*> %ptrv, <4 x i8*> undef, <4 x i32> <i32 2, i32 7, i32 1, i32 2> +;CHECK: pshufd + ret <4 x i8*> %G +;CHECK: ret +} + +;CHECK: LOAD0 +define <4 x i8*> @LOAD0(<4 x i8*>* %p) nounwind { +entry: + %G = load <4 x i8*>* %p +;CHECK: movaps + ret <4 x i8*> %G +;CHECK: ret +} + +;CHECK: LOAD1 +define <4 x i8*> @LOAD1(<4 x i8*>* %p) nounwind { +entry: + %G = load <4 x i8*>* %p +;CHECK: movdqa +;CHECK: pshufd +;CHECK: movdqa + %T = shufflevector <4 x i8*> %G, <4 x i8*> %G, <4 x i32> <i32 7, i32 1, i32 4, i32 3> + store <4 x i8*> %T, <4 x i8*>* %p + ret <4 x i8*> %G +;CHECK: ret +} + +;CHECK: LOAD2 +define <4 x i8*> @LOAD2(<4 x i8*>* %p) nounwind { +entry: + %I = alloca <4 x i8*> +;CHECK: sub + %G = load <4 x i8*>* %p +;CHECK: movaps + store <4 x i8*> %G, <4 x i8*>* %I +;CHECK: movaps + %Z = load <4 x i8*>* %I + ret <4 x i8*> %Z +;CHECK: add +;CHECK: ret +} + +;CHECK: INT2PTR0 +define <4 x i32> @INT2PTR0(<4 x i8*>* %p) nounwind { +entry: + %G = load <4 x i8*>* %p +;CHECK: movl +;CHECK: movaps + %K = ptrtoint <4 x i8*> %G to <4 x i32> +;CHECK: ret + ret <4 x i32> %K +} + +;CHECK: INT2PTR1 +define <4 x i32*> @INT2PTR1(<4 x i8>* %p) nounwind { +entry: + %G = load <4 x i8>* %p +;CHECK: movl +;CHECK: movd +;CHECK: pshufb +;CHECK: pand + %K = inttoptr <4 x i8> %G to <4 x i32*> +;CHECK: ret + ret <4 x i32*> %K +} + +;CHECK: BITCAST0 +define <4 x i32*> @BITCAST0(<4 x i8*>* %p) nounwind { +entry: + %G = load <4 x i8*>* %p +;CHECK: movl + %T = bitcast <4 x i8*> %G to <4 x i32*> +;CHECK: movaps +;CHECK: ret + ret <4 x i32*> %T +} + +;CHECK: BITCAST1 +define <2 x i32*> @BITCAST1(<2 x i8*>* %p) nounwind { +entry: + %G = load <2 x i8*>* %p +;CHECK: movl +;CHECK: movd +;CHECK: pinsrd + %T = bitcast <2 x i8*> %G to <2 x i32*> +;CHECK: ret + ret <2 x i32*> %T +} + +;CHECK: ICMP0 +define <4 x i32> @ICMP0(<4 x i8*>* %p0, <4 x i8*>* %p1) nounwind { +entry: + %g0 = load <4 x i8*>* %p0 + %g1 = load <4 x i8*>* %p1 + %k = icmp sgt <4 x i8*> %g0, %g1 + ;CHECK: pcmpgtd + %j = select <4 x i1> %k, <4 x i32> <i32 0, i32 1, i32 2, i32 4>, <4 x i32> <i32 9, i32 8, i32 7, i32 6> + ret <4 x i32> %j + ;CHECK: ret +} + +;CHECK: ICMP1 +define <4 x i32> @ICMP1(<4 x i8*>* %p0, <4 x i8*>* %p1) nounwind { +entry: + %g0 = load <4 x i8*>* %p0 + %g1 = load <4 x i8*>* %p1 + %k = icmp eq <4 x i8*> %g0, %g1 + ;CHECK: pcmpeqd + %j = select <4 x i1> %k, <4 x i32> <i32 0, i32 1, i32 2, i32 4>, <4 x i32> <i32 9, i32 8, i32 7, i32 6> + ret <4 x i32> %j + ;CHECK: ret +} + diff --git a/test/CodeGen/X86/pr11202.ll b/test/CodeGen/X86/pr11202.ll new file mode 100644 index 0000000..13070d1 --- /dev/null +++ b/test/CodeGen/X86/pr11202.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s + +@bb = constant [1 x i8*] [i8* blockaddress(@main, %l2)] + +define void @main() { +entry: + br label %l1 + +l1: ; preds = %l2, %entry + %a = zext i1 false to i32 + br label %l2 + +l2: ; preds = %l1 + %b = zext i1 false to i32 + br label %l1 +} + +; CHECK: .Ltmp0: # Address of block that was removed by CodeGen +; CHECK: .quad .Ltmp0 diff --git a/test/CodeGen/X86/pr11415.ll b/test/CodeGen/X86/pr11415.ll new file mode 100644 index 0000000..e1fa032 --- /dev/null +++ b/test/CodeGen/X86/pr11415.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple=x86_64-pc-linux %s -o - -regalloc=fast | FileCheck %s + +; We used to consider the early clobber in the second asm statement as +; defining %0 before it was read. This caused us to omit the +; movq -8(%rsp), %rdx + +; CHECK: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: movq %rcx, %rax +; CHECK-NEXT: movq %rax, -8(%rsp) +; CHECK-NEXT: movq -8(%rsp), %rdx +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: movq %rdx, %rax +; CHECK-NEXT: movq %rdx, -8(%rsp) +; CHECK-NEXT: ret + +define i64 @foo() { +entry: + %0 = tail call i64 asm "", "={cx}"() nounwind + %1 = tail call i64 asm "", "=&r,0,r,~{rax}"(i64 %0, i64 %0) nounwind + ret i64 %1 +} diff --git a/test/CodeGen/X86/pr12360.ll b/test/CodeGen/X86/pr12360.ll new file mode 100644 index 0000000..f29e50e --- /dev/null +++ b/test/CodeGen/X86/pr12360.ll @@ -0,0 +1,46 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s + +define zeroext i1 @f1(i8* %x) { +; CHECK: f1: +; CHECK: movb (%rdi), %al +; CHECK-NEXT: ret + +entry: + %0 = load i8* %x, align 1, !range !0 + %tobool = trunc i8 %0 to i1 + ret i1 %tobool +} + +define zeroext i1 @f2(i8* %x) { +; CHECK: f2: +; CHECK: movb (%rdi), %al +; CHECK-NEXT: ret + +entry: + %0 = load i8* %x, align 1, !range !0 + %tobool = icmp ne i8 %0, 0 + ret i1 %tobool +} + +!0 = metadata !{i8 0, i8 2} + + +; check that we don't build a "trunc" from i1 to i1, which would assert. +define zeroext i1 @f3(i1 %x) { +; CHECK: f3: + +entry: + %tobool = icmp ne i1 %x, 0 + ret i1 %tobool +} + +; check that we don't build a trunc when other bits are needed +define zeroext i1 @f4(i32 %x) { +; CHECK: f4: +; CHECK: and + +entry: + %y = and i32 %x, 32768 + %z = icmp ne i32 %y, 0 + ret i1 %z +} diff --git a/test/CodeGen/X86/pr1505b.ll b/test/CodeGen/X86/pr1505b.ll index 945ec4c..9b0ef83 100644 --- a/test/CodeGen/X86/pr1505b.ll +++ b/test/CodeGen/X86/pr1505b.ll @@ -33,7 +33,7 @@ declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) define i32 @main() { entry: ; CHECK: flds - %tmp6 = volatile load float* @a ; <float> [#uses=1] + %tmp6 = load volatile float* @a ; <float> [#uses=1] ; CHECK: fstps (%esp) ; CHECK: tanf %tmp9 = tail call float @tanf( float %tmp6 ) ; <float> [#uses=1] @@ -41,7 +41,7 @@ entry: ; CHECK: fstp ; CHECK: fldl - %tmp12 = volatile load double* @b ; <double> [#uses=1] + %tmp12 = load volatile double* @b ; <double> [#uses=1] ; CHECK: fstpl (%esp) ; CHECK: tan %tmp13 = tail call double @tan( double %tmp12 ) ; <double> [#uses=1] diff --git a/test/CodeGen/X86/pr2182.ll b/test/CodeGen/X86/pr2182.ll index 2a8bb35..02a3605 100644 --- a/test/CodeGen/X86/pr2182.ll +++ b/test/CodeGen/X86/pr2182.ll @@ -15,17 +15,17 @@ define void @loop_2() nounwind { ; CHECK-NEXT: addl $3, (%{{.*}}) ; CHECK-NEXT: ret - %tmp = volatile load i32* @x, align 4 ; <i32> [#uses=1] + %tmp = load volatile i32* @x, align 4 ; <i32> [#uses=1] %tmp1 = add i32 %tmp, 3 ; <i32> [#uses=1] - volatile store i32 %tmp1, i32* @x, align 4 - %tmp.1 = volatile load i32* @x, align 4 ; <i32> [#uses=1] + store volatile i32 %tmp1, i32* @x, align 4 + %tmp.1 = load volatile i32* @x, align 4 ; <i32> [#uses=1] %tmp1.1 = add i32 %tmp.1, 3 ; <i32> [#uses=1] - volatile store i32 %tmp1.1, i32* @x, align 4 - %tmp.2 = volatile load i32* @x, align 4 ; <i32> [#uses=1] + store volatile i32 %tmp1.1, i32* @x, align 4 + %tmp.2 = load volatile i32* @x, align 4 ; <i32> [#uses=1] %tmp1.2 = add i32 %tmp.2, 3 ; <i32> [#uses=1] - volatile store i32 %tmp1.2, i32* @x, align 4 - %tmp.3 = volatile load i32* @x, align 4 ; <i32> [#uses=1] + store volatile i32 %tmp1.2, i32* @x, align 4 + %tmp.3 = load volatile i32* @x, align 4 ; <i32> [#uses=1] %tmp1.3 = add i32 %tmp.3, 3 ; <i32> [#uses=1] - volatile store i32 %tmp1.3, i32* @x, align 4 + store volatile i32 %tmp1.3, i32* @x, align 4 ret void } diff --git a/test/CodeGen/X86/pr3495-2.ll b/test/CodeGen/X86/pr3495-2.ll deleted file mode 100644 index a4204e5..0000000 --- a/test/CodeGen/X86/pr3495-2.ll +++ /dev/null @@ -1,54 +0,0 @@ -; RUN: llc < %s -march=x86 -relocation-model=pic -disable-fp-elim -stats -regalloc=linearscan |& grep {Number of loads added} | grep 1 -; PR3495 -; -; This test may not be testing what it was supposed to test. -; It used to have two spills and four reloads, but not it only has one spill and one reload. - -target datalayout = "e-p:32:32:32" -target triple = "i386-apple-darwin9.6" - %struct.constraintVCGType = type { i32, i32, i32, i32 } - %struct.nodeVCGType = type { %struct.constraintVCGType*, i32, i32, i32, %struct.constraintVCGType*, i32, i32, i32 } - -define fastcc void @SCC_DFSBelowVCG(%struct.nodeVCGType* %VCG, i32 %net, i32 %label) nounwind { -entry: - %0 = getelementptr %struct.nodeVCGType* %VCG, i32 %net, i32 5 ; <i32*> [#uses=2] - %1 = load i32* %0, align 4 ; <i32> [#uses=1] - %2 = icmp eq i32 %1, 0 ; <i1> [#uses=1] - br i1 %2, label %bb5, label %bb.nph3 - -bb.nph3: ; preds = %entry - %3 = getelementptr %struct.nodeVCGType* %VCG, i32 %net, i32 4 ; <%struct.constraintVCGType**> [#uses=1] - br label %bb - -bb: ; preds = %bb3, %bb.nph3 - %s.02 = phi i32 [ 0, %bb.nph3 ], [ %12, %bb3 ] ; <i32> [#uses=2] - %4 = load %struct.constraintVCGType** %3, align 4 ; <%struct.constraintVCGType*> [#uses=1] - %5 = icmp eq i32 0, 0 ; <i1> [#uses=1] - br i1 %5, label %bb1, label %bb3 - -bb1: ; preds = %bb - %6 = getelementptr %struct.constraintVCGType* %4, i32 %s.02, i32 0 ; <i32*> [#uses=1] - %7 = load i32* %6, align 4 ; <i32> [#uses=2] - %8 = getelementptr %struct.nodeVCGType* %VCG, i32 %7, i32 7 ; <i32*> [#uses=1] - %9 = load i32* %8, align 4 ; <i32> [#uses=1] - %10 = icmp eq i32 %9, 0 ; <i1> [#uses=1] - br i1 %10, label %bb2, label %bb3 - -bb2: ; preds = %bb1 - %11 = getelementptr %struct.nodeVCGType* %VCG, i32 %7, i32 4 ; <%struct.constraintVCGType**> [#uses=0] - br label %bb.i - -bb.i: ; preds = %bb.i, %bb2 - br label %bb.i - -bb3: ; preds = %bb1, %bb - %12 = add i32 %s.02, 1 ; <i32> [#uses=2] - %13 = load i32* %0, align 4 ; <i32> [#uses=1] - %14 = icmp ugt i32 %13, %12 ; <i1> [#uses=1] - br i1 %14, label %bb, label %bb5 - -bb5: ; preds = %bb3, %entry - %15 = getelementptr %struct.nodeVCGType* %VCG, i32 %net, i32 6 ; <i32*> [#uses=1] - store i32 %label, i32* %15, align 4 - ret void -} diff --git a/test/CodeGen/X86/pr3495.ll b/test/CodeGen/X86/pr3495.ll deleted file mode 100644 index 7efd35b..0000000 --- a/test/CodeGen/X86/pr3495.ll +++ /dev/null @@ -1,81 +0,0 @@ -; RUN: llc < %s -march=x86 -stats -regalloc=linearscan -enable-lsr-nested |& grep {Number of loads added} | grep 2 -; RUN: llc < %s -march=x86 -stats -regalloc=linearscan -enable-lsr-nested |& grep {Number of spill slots allocated} | grep 1 -; RUN: llc < %s -march=x86 -stats -regalloc=linearscan -enable-lsr-nested |& grep {Number of machine instrs printed} | grep 34 -; PR3495 -; -; Note: this should not spill at all with either good LSR or good regalloc. - -target triple = "i386-pc-linux-gnu" -@x = external global [8 x i32], align 32 ; <[8 x i32]*> [#uses=1] -@rows = external global [8 x i32], align 32 ; <[8 x i32]*> [#uses=2] -@up = external global [15 x i32], align 32 ; <[15 x i32]*> [#uses=2] -@down = external global [15 x i32], align 32 ; <[15 x i32]*> [#uses=1] - -define i32 @queens(i32 %c) nounwind { -entry: - %tmp91 = add i32 %c, 1 ; <i32> [#uses=3] - %tmp135 = getelementptr [8 x i32]* @x, i32 0, i32 %tmp91 ; <i32*> [#uses=1] - br label %bb - -bb: ; preds = %bb569, %entry - %r25.0.reg2mem.0 = phi i32 [ 0, %entry ], [ %indvar.next715, %bb569 ] ; <i32> [#uses=4] - %tmp27 = getelementptr [8 x i32]* @rows, i32 0, i32 %r25.0.reg2mem.0 ; <i32*> [#uses=1] - %tmp28 = load i32* %tmp27, align 4 ; <i32> [#uses=1] - %tmp29 = icmp eq i32 %tmp28, 0 ; <i1> [#uses=1] - br i1 %tmp29, label %bb569, label %bb31 - -bb31: ; preds = %bb - %tmp35 = sub i32 %r25.0.reg2mem.0, 0 ; <i32> [#uses=1] - %tmp36 = getelementptr [15 x i32]* @up, i32 0, i32 %tmp35 ; <i32*> [#uses=1] - %tmp37 = load i32* %tmp36, align 4 ; <i32> [#uses=1] - %tmp38 = icmp eq i32 %tmp37, 0 ; <i1> [#uses=1] - br i1 %tmp38, label %bb569, label %bb41 - -bb41: ; preds = %bb31 - %tmp54 = sub i32 %r25.0.reg2mem.0, %c ; <i32> [#uses=1] - %tmp55 = add i32 %tmp54, 7 ; <i32> [#uses=1] - %tmp62 = getelementptr [15 x i32]* @up, i32 0, i32 %tmp55 ; <i32*> [#uses=2] - store i32 0, i32* %tmp62, align 4 - br label %bb92 - -bb92: ; preds = %bb545, %bb41 - %r20.0.reg2mem.0 = phi i32 [ 0, %bb41 ], [ %indvar.next711, %bb545 ] ; <i32> [#uses=5] - %tmp94 = getelementptr [8 x i32]* @rows, i32 0, i32 %r20.0.reg2mem.0 ; <i32*> [#uses=1] - %tmp95 = load i32* %tmp94, align 4 ; <i32> [#uses=0] - %tmp112 = add i32 %r20.0.reg2mem.0, %tmp91 ; <i32> [#uses=1] - %tmp113 = getelementptr [15 x i32]* @down, i32 0, i32 %tmp112 ; <i32*> [#uses=2] - %tmp114 = load i32* %tmp113, align 4 ; <i32> [#uses=1] - %tmp115 = icmp eq i32 %tmp114, 0 ; <i1> [#uses=1] - br i1 %tmp115, label %bb545, label %bb118 - -bb118: ; preds = %bb92 - %tmp122 = sub i32 %r20.0.reg2mem.0, %tmp91 ; <i32> [#uses=0] - store i32 0, i32* %tmp113, align 4 - store i32 %r20.0.reg2mem.0, i32* %tmp135, align 4 - br label %bb142 - -bb142: ; preds = %bb142, %bb118 - %k18.0.reg2mem.0 = phi i32 [ 0, %bb118 ], [ %indvar.next709, %bb142 ] ; <i32> [#uses=1] - %indvar.next709 = add i32 %k18.0.reg2mem.0, 1 ; <i32> [#uses=2] - %exitcond710 = icmp eq i32 %indvar.next709, 8 ; <i1> [#uses=1] - br i1 %exitcond710, label %bb155, label %bb142 - -bb155: ; preds = %bb142 - %tmp156 = tail call i32 @putchar(i32 10) nounwind ; <i32> [#uses=0] - br label %bb545 - -bb545: ; preds = %bb155, %bb92 - %indvar.next711 = add i32 %r20.0.reg2mem.0, 1 ; <i32> [#uses=2] - %exitcond712 = icmp eq i32 %indvar.next711, 8 ; <i1> [#uses=1] - br i1 %exitcond712, label %bb553, label %bb92 - -bb553: ; preds = %bb545 - store i32 1, i32* %tmp62, align 4 - br label %bb569 - -bb569: ; preds = %bb553, %bb31, %bb - %indvar.next715 = add i32 %r25.0.reg2mem.0, 1 ; <i32> [#uses=1] - br label %bb -} - -declare i32 @putchar(i32) diff --git a/test/CodeGen/X86/prefetch.ll b/test/CodeGen/X86/prefetch.ll index ebe11a5..ec2f302 100644 --- a/test/CodeGen/X86/prefetch.ll +++ b/test/CodeGen/X86/prefetch.ll @@ -1,4 +1,7 @@ ; RUN: llc < %s -march=x86 -mattr=+sse | FileCheck %s +; RUN: llc < %s -march=x86 -mattr=+avx | FileCheck %s + +; rdar://10538297 define void @t(i8* %ptr) nounwind { entry: diff --git a/test/CodeGen/X86/promote.ll b/test/CodeGen/X86/promote.ll new file mode 100644 index 0000000..8b30dc7 --- /dev/null +++ b/test/CodeGen/X86/promote.ll @@ -0,0 +1,42 @@ +; RUN: llc < %s -march=x86-64 -mcpu=corei7 | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i8:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + + +; CHECK: mul_f +define i32 @mul_f(<4 x i8>* %A) { +entry: +; CHECK: pmul +; CHECK-NOT: mulb + %0 = load <4 x i8>* %A, align 8 + %mul = mul <4 x i8> %0, %0 + store <4 x i8> %mul, <4 x i8>* undef + ret i32 0 +; CHECK: ret +} + + +; CHECK: shuff_f +define i32 @shuff_f(<4 x i8>* %A) { +entry: +; CHECK: pshufb +; CHECK: paddd +; CHECK: pshufb + %0 = load <4 x i8>* %A, align 8 + %add = add <4 x i8> %0, %0 + store <4 x i8> %add, <4 x i8>* undef + ret i32 0 +; CHECK: ret +} + +; CHECK: bitcast_widen +define <2 x float> @bitcast_widen(<4 x i32> %in) nounwind readnone { +entry: +; CHECK-NOT: pshufd + %x = shufflevector <4 x i32> %in, <4 x i32> undef, <2 x i32> <i32 0, i32 1> + %y = bitcast <2 x i32> %x to <2 x float> + ret <2 x float> %y +; CHECK: ret +} + diff --git a/test/CodeGen/X86/rd-mod-wr-eflags.ll b/test/CodeGen/X86/rd-mod-wr-eflags.ll new file mode 100644 index 0000000..faca3d7 --- /dev/null +++ b/test/CodeGen/X86/rd-mod-wr-eflags.ll @@ -0,0 +1,179 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +%struct.obj = type { i64 } + +; CHECK: _Z7releaseP3obj +define void @_Z7releaseP3obj(%struct.obj* nocapture %o) nounwind uwtable ssp { +entry: +; CHECK: decq (%{{rdi|rcx}}) +; CHECK-NEXT: je + %refcnt = getelementptr inbounds %struct.obj* %o, i64 0, i32 0 + %0 = load i64* %refcnt, align 8, !tbaa !0 + %dec = add i64 %0, -1 + store i64 %dec, i64* %refcnt, align 8, !tbaa !0 + %tobool = icmp eq i64 %dec, 0 + br i1 %tobool, label %if.end, label %return + +if.end: ; preds = %entry + %1 = bitcast %struct.obj* %o to i8* + tail call void @free(i8* %1) + br label %return + +return: ; preds = %entry, %if.end + ret void +} + +@c = common global i64 0, align 8 +@a = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%ld\0A\00", align 1 +@b = common global i32 0, align 4 + +; CHECK: test +define i32 @test() nounwind uwtable ssp { +entry: +; CHECK: decq +; CHECK-NOT: decq +%0 = load i64* @c, align 8, !tbaa !0 +%dec.i = add nsw i64 %0, -1 +store i64 %dec.i, i64* @c, align 8, !tbaa !0 +%tobool.i = icmp ne i64 %dec.i, 0 +%lor.ext.i = zext i1 %tobool.i to i32 +store i32 %lor.ext.i, i32* @a, align 4, !tbaa !3 +%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i64 0, i64 0), i64 %dec.i) nounwind +ret i32 0 +} + +; CHECK: test2 +define i32 @test2() nounwind uwtable ssp { +entry: +; CHECK-NOT: decq ({{.*}}) +%0 = load i64* @c, align 8, !tbaa !0 +%dec.i = add nsw i64 %0, -1 +store i64 %dec.i, i64* @c, align 8, !tbaa !0 +%tobool.i = icmp ne i64 %0, 0 +%lor.ext.i = zext i1 %tobool.i to i32 +store i32 %lor.ext.i, i32* @a, align 4, !tbaa !3 +%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i64 0, i64 0), i64 %dec.i) nounwind +ret i32 0 +} + +declare i32 @printf(i8* nocapture, ...) nounwind + +declare void @free(i8* nocapture) nounwind + +!0 = metadata !{metadata !"long", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} +!3 = metadata !{metadata !"int", metadata !1} + +%struct.obj2 = type { i64, i32, i16, i8 } + +declare void @other(%struct.obj2* ) nounwind; + +; CHECK: example_dec +define void @example_dec(%struct.obj2* %o) nounwind uwtable ssp { +; 64 bit dec +entry: + %s64 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 0 +; CHECK-NOT: load + %0 = load i64* %s64, align 8 +; CHECK: decq ({{.*}}) + %dec = add i64 %0, -1 + store i64 %dec, i64* %s64, align 8 + %tobool = icmp eq i64 %dec, 0 + br i1 %tobool, label %if.end, label %return + +; 32 bit dec +if.end: + %s32 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 1 +; CHECK-NOT: load + %1 = load i32* %s32, align 4 +; CHECK: decl {{[0-9][0-9]*}}({{.*}}) + %dec1 = add i32 %1, -1 + store i32 %dec1, i32* %s32, align 4 + %tobool2 = icmp eq i32 %dec1, 0 + br i1 %tobool2, label %if.end1, label %return + +; 16 bit dec +if.end1: + %s16 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 2 +; CHECK-NOT: load + %2 = load i16* %s16, align 2 +; CHECK: decw {{[0-9][0-9]*}}({{.*}}) + %dec2 = add i16 %2, -1 + store i16 %dec2, i16* %s16, align 2 + %tobool3 = icmp eq i16 %dec2, 0 + br i1 %tobool3, label %if.end2, label %return + +; 8 bit dec +if.end2: + %s8 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 3 +; CHECK-NOT: load + %3 = load i8* %s8 +; CHECK: decb {{[0-9][0-9]*}}({{.*}}) + %dec3 = add i8 %3, -1 + store i8 %dec3, i8* %s8 + %tobool4 = icmp eq i8 %dec3, 0 + br i1 %tobool4, label %if.end4, label %return + +if.end4: + tail call void @other(%struct.obj2* %o) nounwind + br label %return + +return: ; preds = %if.end4, %if.end, %entry + ret void +} + +; CHECK: example_inc +define void @example_inc(%struct.obj2* %o) nounwind uwtable ssp { +; 64 bit inc +entry: + %s64 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 0 +; CHECK-NOT: load + %0 = load i64* %s64, align 8 +; CHECK: incq ({{.*}}) + %inc = add i64 %0, 1 + store i64 %inc, i64* %s64, align 8 + %tobool = icmp eq i64 %inc, 0 + br i1 %tobool, label %if.end, label %return + +; 32 bit inc +if.end: + %s32 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 1 +; CHECK-NOT: load + %1 = load i32* %s32, align 4 +; CHECK: incl {{[0-9][0-9]*}}({{.*}}) + %inc1 = add i32 %1, 1 + store i32 %inc1, i32* %s32, align 4 + %tobool2 = icmp eq i32 %inc1, 0 + br i1 %tobool2, label %if.end1, label %return + +; 16 bit inc +if.end1: + %s16 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 2 +; CHECK-NOT: load + %2 = load i16* %s16, align 2 +; CHECK: incw {{[0-9][0-9]*}}({{.*}}) + %inc2 = add i16 %2, 1 + store i16 %inc2, i16* %s16, align 2 + %tobool3 = icmp eq i16 %inc2, 0 + br i1 %tobool3, label %if.end2, label %return + +; 8 bit inc +if.end2: + %s8 = getelementptr inbounds %struct.obj2* %o, i64 0, i32 3 +; CHECK-NOT: load + %3 = load i8* %s8 +; CHECK: incb {{[0-9][0-9]*}}({{.*}}) + %inc3 = add i8 %3, 1 + store i8 %inc3, i8* %s8 + %tobool4 = icmp eq i8 %inc3, 0 + br i1 %tobool4, label %if.end4, label %return + +if.end4: + tail call void @other(%struct.obj2* %o) nounwind + br label %return + +return: + ret void +} diff --git a/test/CodeGen/X86/red-zone.ll b/test/CodeGen/X86/red-zone.ll index d936971..d99a7a4 100644 --- a/test/CodeGen/X86/red-zone.ll +++ b/test/CodeGen/X86/red-zone.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s ; First without noredzone. ; CHECK: f0: diff --git a/test/CodeGen/X86/red-zone2.ll b/test/CodeGen/X86/red-zone2.ll index 9557d17..f092163 100644 --- a/test/CodeGen/X86/red-zone2.ll +++ b/test/CodeGen/X86/red-zone2.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 > %t +; RUN: llc < %s -mcpu=generic -march=x86-64 > %t ; RUN: grep subq %t | count 1 ; RUN: grep addq %t | count 1 diff --git a/test/CodeGen/X86/reghinting.ll b/test/CodeGen/X86/reghinting.ll index 87f65ed..6759115 100644 --- a/test/CodeGen/X86/reghinting.ll +++ b/test/CodeGen/X86/reghinting.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-apple-macosx | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-apple-macosx | FileCheck %s ; PR10221 ;; The registers %x and %y must both spill across the finit call. diff --git a/test/CodeGen/X86/remat-scalar-zero.ll b/test/CodeGen/X86/remat-scalar-zero.ll index f6f0ed1..75f438d 100644 --- a/test/CodeGen/X86/remat-scalar-zero.ll +++ b/test/CodeGen/X86/remat-scalar-zero.ll @@ -1,4 +1,5 @@ ; XFAIL: * +; ...should pass. See PR12324: misched bringup ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu > %t ; RUN: not grep xor %t ; RUN: not grep movap %t diff --git a/test/CodeGen/X86/rounding-ops.ll b/test/CodeGen/X86/rounding-ops.ll new file mode 100644 index 0000000..0dd74ea --- /dev/null +++ b/test/CodeGen/X86/rounding-ops.ll @@ -0,0 +1,132 @@ +; RUN: llc < %s -march=x86-64 -mattr=+sse41 | FileCheck -check-prefix=CHECK-SSE %s +; RUN: llc < %s -march=x86-64 -mattr=+avx | FileCheck -check-prefix=CHECK-AVX %s + +define float @test1(float %x) nounwind { + %call = tail call float @floorf(float %x) nounwind readnone + ret float %call + +; CHECK-SSE: test1: +; CHECK-SSE: roundss $1 + +; CHECK-AVX: test1: +; CHECK-AVX: vroundss $1 +} + +declare float @floorf(float) nounwind readnone + +define double @test2(double %x) nounwind { + %call = tail call double @floor(double %x) nounwind readnone + ret double %call + +; CHECK-SSE: test2: +; CHECK-SSE: roundsd $1 + +; CHECK-AVX: test2: +; CHECK-AVX: vroundsd $1 +} + +declare double @floor(double) nounwind readnone + +define float @test3(float %x) nounwind { + %call = tail call float @nearbyintf(float %x) nounwind readnone + ret float %call + +; CHECK-SSE: test3: +; CHECK-SSE: roundss $12 + +; CHECK-AVX: test3: +; CHECK-AVX: vroundss $12 +} + +declare float @nearbyintf(float) nounwind readnone + +define double @test4(double %x) nounwind { + %call = tail call double @nearbyint(double %x) nounwind readnone + ret double %call + +; CHECK-SSE: test4: +; CHECK-SSE: roundsd $12 + +; CHECK-AVX: test4: +; CHECK-AVX: vroundsd $12 +} + +declare double @nearbyint(double) nounwind readnone + +define float @test5(float %x) nounwind { + %call = tail call float @ceilf(float %x) nounwind readnone + ret float %call + +; CHECK-SSE: test5: +; CHECK-SSE: roundss $2 + +; CHECK-AVX: test5: +; CHECK-AVX: vroundss $2 +} + +declare float @ceilf(float) nounwind readnone + +define double @test6(double %x) nounwind { + %call = tail call double @ceil(double %x) nounwind readnone + ret double %call + +; CHECK-SSE: test6: +; CHECK-SSE: roundsd $2 + +; CHECK-AVX: test6: +; CHECK-AVX: vroundsd $2 +} + +declare double @ceil(double) nounwind readnone + +define float @test7(float %x) nounwind { + %call = tail call float @rintf(float %x) nounwind readnone + ret float %call + +; CHECK-SSE: test7: +; CHECK-SSE: roundss $4 + +; CHECK-AVX: test7: +; CHECK-AVX: vroundss $4 +} + +declare float @rintf(float) nounwind readnone + +define double @test8(double %x) nounwind { + %call = tail call double @rint(double %x) nounwind readnone + ret double %call + +; CHECK-SSE: test8: +; CHECK-SSE: roundsd $4 + +; CHECK-AVX: test8: +; CHECK-AVX: vroundsd $4 +} + +declare double @rint(double) nounwind readnone + +define float @test9(float %x) nounwind { + %call = tail call float @truncf(float %x) nounwind readnone + ret float %call + +; CHECK-SSE: test9: +; CHECK-SSE: roundss $3 + +; CHECK-AVX: test9: +; CHECK-AVX: vroundss $3 +} + +declare float @truncf(float) nounwind readnone + +define double @test10(double %x) nounwind { + %call = tail call double @trunc(double %x) nounwind readnone + ret double %call + +; CHECK-SSE: test10: +; CHECK-SSE: roundsd $3 + +; CHECK-AVX: test10: +; CHECK-AVX: vroundsd $3 +} + +declare double @trunc(double) nounwind readnone diff --git a/test/CodeGen/X86/scalar_widen_div.ll b/test/CodeGen/X86/scalar_widen_div.ll index adc58ac..e99ea93 100644 --- a/test/CodeGen/X86/scalar_widen_div.ll +++ b/test/CodeGen/X86/scalar_widen_div.ll @@ -3,9 +3,10 @@ ; Verify when widening a divide/remainder operation, we only generate a ; divide/rem per element since divide/remainder can trap. +; CHECK: vectorDiv define void @vectorDiv (<2 x i32> addrspace(1)* %nsource, <2 x i32> addrspace(1)* %dsource, <2 x i32> addrspace(1)* %qdest) nounwind { -; CHECK: idivl -; CHECK: idivl +; CHECK: idivq +; CHECK: idivq ; CHECK-NOT: idivl ; CHECK: ret entry: @@ -32,6 +33,7 @@ entry: ret void } +; CHECK: test_char_div define <3 x i8> @test_char_div(<3 x i8> %num, <3 x i8> %div) { ; CHECK: idivb ; CHECK: idivb @@ -42,6 +44,7 @@ define <3 x i8> @test_char_div(<3 x i8> %num, <3 x i8> %div) { ret <3 x i8> %div.r } +; CHECK: test_uchar_div define <3 x i8> @test_uchar_div(<3 x i8> %num, <3 x i8> %div) { ; CHECK: divb ; CHECK: divb @@ -52,6 +55,7 @@ define <3 x i8> @test_uchar_div(<3 x i8> %num, <3 x i8> %div) { ret <3 x i8> %div.r } +; CHECK: test_short_div define <5 x i16> @test_short_div(<5 x i16> %num, <5 x i16> %div) { ; CHECK: idivw ; CHECK: idivw @@ -64,17 +68,19 @@ define <5 x i16> @test_short_div(<5 x i16> %num, <5 x i16> %div) { ret <5 x i16> %div.r } +; CHECK: test_ushort_div define <4 x i16> @test_ushort_div(<4 x i16> %num, <4 x i16> %div) { -; CHECK: divw -; CHECK: divw -; CHECK: divw -; CHECK: divw -; CHECK-NOT: divw +; CHECK: divl +; CHECK: divl +; CHECK: divl +; CHECK: divl +; CHECK-NOT: divl ; CHECK: ret %div.r = udiv <4 x i16> %num, %div ret <4 x i16> %div.r } +; CHECK: test_uint_div define <3 x i32> @test_uint_div(<3 x i32> %num, <3 x i32> %div) { ; CHECK: divl ; CHECK: divl @@ -85,6 +91,7 @@ define <3 x i32> @test_uint_div(<3 x i32> %num, <3 x i32> %div) { ret <3 x i32> %div.r } +; CHECK: test_long_div define <3 x i64> @test_long_div(<3 x i64> %num, <3 x i64> %div) { ; CHECK: idivq ; CHECK: idivq @@ -95,6 +102,7 @@ define <3 x i64> @test_long_div(<3 x i64> %num, <3 x i64> %div) { ret <3 x i64> %div.r } +; CHECK: test_ulong_div define <3 x i64> @test_ulong_div(<3 x i64> %num, <3 x i64> %div) { ; CHECK: divq ; CHECK: divq @@ -105,18 +113,19 @@ define <3 x i64> @test_ulong_div(<3 x i64> %num, <3 x i64> %div) { ret <3 x i64> %div.r } - +; CHECK: test_char_rem define <4 x i8> @test_char_rem(<4 x i8> %num, <4 x i8> %rem) { -; CHECK: idivb -; CHECK: idivb -; CHECK: idivb -; CHECK: idivb -; CHECK-NOT: idivb +; CHECK: idivl +; CHECK: idivl +; CHECK: idivl +; CHECK: idivl +; CHECK-NOT: idivl ; CHECK: ret %rem.r = srem <4 x i8> %num, %rem ret <4 x i8> %rem.r } +; CHECK: test_short_rem define <5 x i16> @test_short_rem(<5 x i16> %num, <5 x i16> %rem) { ; CHECK: idivw ; CHECK: idivw @@ -129,6 +138,7 @@ define <5 x i16> @test_short_rem(<5 x i16> %num, <5 x i16> %rem) { ret <5 x i16> %rem.r } +; CHECK: test_uint_rem define <4 x i32> @test_uint_rem(<4 x i32> %num, <4 x i32> %rem) { ; CHECK: idivl ; CHECK: idivl @@ -141,6 +151,7 @@ define <4 x i32> @test_uint_rem(<4 x i32> %num, <4 x i32> %rem) { } +; CHECK: test_ulong_rem define <5 x i64> @test_ulong_rem(<5 x i64> %num, <5 x i64> %rem) { ; CHECK: divq ; CHECK: divq @@ -153,6 +164,7 @@ define <5 x i64> @test_ulong_rem(<5 x i64> %num, <5 x i64> %rem) { ret <5 x i64> %rem.r } +; CHECK: test_int_div define void @test_int_div(<3 x i32>* %dest, <3 x i32>* %old, i32 %n) { ; CHECK: idivl ; CHECK: idivl diff --git a/test/CodeGen/X86/segmented-stacks-dynamic.ll b/test/CodeGen/X86/segmented-stacks-dynamic.ll new file mode 100644 index 0000000..5ce08aa --- /dev/null +++ b/test/CodeGen/X86/segmented-stacks-dynamic.ll @@ -0,0 +1,64 @@ +; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -filetype=obj +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -segmented-stacks -filetype=obj + +; Just to prevent the alloca from being optimized away +declare void @dummy_use(i32*, i32) + +define i32 @test_basic(i32 %l) { + %mem = alloca i32, i32 %l + call void @dummy_use (i32* %mem, i32 %l) + %terminate = icmp eq i32 %l, 0 + br i1 %terminate, label %true, label %false + +true: + ret i32 0 + +false: + %newlen = sub i32 %l, 1 + %retvalue = call i32 @test_basic(i32 %newlen) + ret i32 %retvalue + +; X32: test_basic: + +; X32: cmpl %gs:48, %esp +; X32-NEXT: ja .LBB0_2 + +; X32: pushl $4 +; X32-NEXT: pushl $12 +; X32-NEXT: calll __morestack +; X32-NEXT: ret + +; X32: movl %esp, %eax +; X32-NEXT: subl %ecx, %eax +; X32-NEXT: cmpl %eax, %gs:48 + +; X32: movl %eax, %esp + +; X32: subl $12, %esp +; X32-NEXT: pushl %ecx +; X32-NEXT: calll __morestack_allocate_stack_space +; X32-NEXT: addl $16, %esp + +; X64: test_basic: + +; X64: cmpq %fs:112, %rsp +; X64-NEXT: ja .LBB0_2 + +; X64: movabsq $24, %r10 +; X64-NEXT: movabsq $0, %r11 +; X64-NEXT: callq __morestack +; X64-NEXT: ret + +; X64: movq %rsp, %rdi +; X64-NEXT: subq %rax, %rdi +; X64-NEXT: cmpq %rdi, %fs:112 + +; X64: movq %rdi, %rsp + +; X64: movq %rax, %rdi +; X64-NEXT: callq __morestack_allocate_stack_space +; X64-NEXT: movq %rax, %rdi + +} diff --git a/test/CodeGen/X86/segmented-stacks.ll b/test/CodeGen/X86/segmented-stacks.ll index ecdb00d..5407b87 100644 --- a/test/CodeGen/X86/segmented-stacks.ll +++ b/test/CodeGen/X86/segmented-stacks.ll @@ -1,60 +1,97 @@ -; RUN: llc < %s -mtriple=i686-linux -segmented-stacks | FileCheck %s -check-prefix=X32 -; RUN: llc < %s -mtriple=x86_64-linux -segmented-stacks | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32-Linux +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux +; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32-Darwin +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-Darwin +; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32-MinGW +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-FreeBSD + +; We used to crash with filetype=obj +; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -filetype=obj +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -segmented-stacks -filetype=obj +; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -segmented-stacks -filetype=obj +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -segmented-stacks -filetype=obj +; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -segmented-stacks -filetype=obj +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -segmented-stacks -filetype=obj + +; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-solaris -segmented-stacks 2> %t.log +; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-Solaris +; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -segmented-stacks 2> %t.log +; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-MinGW +; RUN: not llc < %s -mcpu=generic -mtriple=i686-freebsd -segmented-stacks 2> %t.log +; RUN: FileCheck %s -input-file=%t.log -check-prefix=X32-FreeBSD + +; X64-Solaris: Segmented stacks not supported on this platform +; X64-MinGW: Segmented stacks not supported on this platform +; X32-FreeBSD: Segmented stacks not supported on FreeBSD i386 ; Just to prevent the alloca from being optimized away declare void @dummy_use(i32*, i32) -define i32 @test_basic(i32 %l) { - %mem = alloca i32, i32 %l - call void @dummy_use (i32* %mem, i32 %l) - %terminate = icmp eq i32 %l, 0 - br i1 %terminate, label %true, label %false +define void @test_basic() { + %mem = alloca i32, i32 10 + call void @dummy_use (i32* %mem, i32 10) + ret void + +; X32-Linux: test_basic: + +; X32-Linux: cmpl %gs:48, %esp +; X32-Linux-NEXT: ja .LBB0_2 -true: - ret i32 0 +; X32-Linux: pushl $0 +; X32-Linux-NEXT: pushl $60 +; X32-Linux-NEXT: calll __morestack +; X32-Linux-NEXT: ret -false: - %newlen = sub i32 %l, 1 - %retvalue = call i32 @test_basic(i32 %newlen) - ret i32 %retvalue +; X64-Linux: test_basic: -; X32: test_basic: +; X64-Linux: cmpq %fs:112, %rsp +; X64-Linux-NEXT: ja .LBB0_2 -; X32: leal -12(%esp), %ecx -; X32-NEXT: cmpl %gs:48, %ecx +; X64-Linux: movabsq $40, %r10 +; X64-Linux-NEXT: movabsq $0, %r11 +; X64-Linux-NEXT: callq __morestack +; X64-Linux-NEXT: ret -; X32: subl $8, %esp -; X32-NEXT: pushl $4 -; X32-NEXT: pushl $12 -; X32-NEXT: calll __morestack -; X32-NEXT: addl $8, %esp -; X32-NEXT: ret +; X32-Darwin: test_basic: -; X32: movl %eax, %esp +; X32-Darwin: movl $432, %ecx +; X32-Darwin-NEXT: cmpl %gs:(%ecx), %esp +; X32-Darwin-NEXT: ja LBB0_2 -; X32: subl $12, %esp -; X32-NEXT: pushl %ecx -; X32-NEXT: calll __morestack_allocate_stack_space -; X32-NEXT: addl $16, %esp +; X32-Darwin: pushl $0 +; X32-Darwin-NEXT: pushl $60 +; X32-Darwin-NEXT: calll ___morestack +; X32-Darwin-NEXT: ret -; X64: test_basic: +; X64-Darwin: test_basic: -; X64: leaq -24(%rsp), %r11 -; X64-NEXT: cmpq %fs:112, %r11 +; X64-Darwin: cmpq %gs:816, %rsp +; X64-Darwin-NEXT: ja LBB0_2 -; X64: movabsq $24, %r10 -; X64-NEXT: movabsq $0, %r11 -; X64-NEXT: callq __morestack -; X64-NEXT: ret +; X64-Darwin: movabsq $40, %r10 +; X64-Darwin-NEXT: movabsq $0, %r11 +; X64-Darwin-NEXT: callq ___morestack +; X64-Darwin-NEXT: ret -; X64: movq %rsp, %rax -; X64-NEXT: subq %rcx, %rax -; X64-NEXT: cmpq %rax, %fs:112 +; X32-MinGW: test_basic: -; X64: movq %rax, %rsp +; X32-MinGW: cmpl %fs:20, %esp +; X32-MinGW-NEXT: ja LBB0_2 -; X64: movq %rcx, %rdi -; X64-NEXT: callq __morestack_allocate_stack_space +; X32-MinGW: pushl $0 +; X32-MinGW-NEXT: pushl $48 +; X32-MinGW-NEXT: calll ___morestack +; X32-MinGW-NEXT: ret + +; X64-FreeBSD: test_basic: + +; X64-FreeBSD: cmpq %fs:24, %rsp +; X64-FreeBSD-NEXT: ja .LBB0_2 + +; X64-FreeBSD: movabsq $40, %r10 +; X64-FreeBSD-NEXT: movabsq $0, %r11 +; X64-FreeBSD-NEXT: callq __morestack +; X64-FreeBSD-NEXT: ret } @@ -63,25 +100,286 @@ define i32 @test_nested(i32 * nest %closure, i32 %other) { %result = add i32 %other, %addend ret i32 %result -; X32: leal (%esp), %edx -; X32-NEXT: cmpl %gs:48, %edx +; X32-Linux: cmpl %gs:48, %esp +; X32-Linux-NEXT: ja .LBB1_2 + +; X32-Linux: pushl $4 +; X32-Linux-NEXT: pushl $0 +; X32-Linux-NEXT: calll __morestack +; X32-Linux-NEXT: ret + +; X64-Linux: cmpq %fs:112, %rsp +; X64-Linux-NEXT: ja .LBB1_2 + +; X64-Linux: movq %r10, %rax +; X64-Linux-NEXT: movabsq $0, %r10 +; X64-Linux-NEXT: movabsq $0, %r11 +; X64-Linux-NEXT: callq __morestack +; X64-Linux-NEXT: ret +; X64-Linux-NEXT: movq %rax, %r10 + +; X32-Darwin: movl $432, %edx +; X32-Darwin-NEXT: cmpl %gs:(%edx), %esp +; X32-Darwin-NEXT: ja LBB1_2 + +; X32-Darwin: pushl $4 +; X32-Darwin-NEXT: pushl $0 +; X32-Darwin-NEXT: calll ___morestack +; X32-Darwin-NEXT: ret + +; X64-Darwin: cmpq %gs:816, %rsp +; X64-Darwin-NEXT: ja LBB1_2 + +; X64-Darwin: movq %r10, %rax +; X64-Darwin-NEXT: movabsq $0, %r10 +; X64-Darwin-NEXT: movabsq $0, %r11 +; X64-Darwin-NEXT: callq ___morestack +; X64-Darwin-NEXT: ret +; X64-Darwin-NEXT: movq %rax, %r10 + +; X32-MinGW: cmpl %fs:20, %esp +; X32-MinGW-NEXT: ja LBB1_2 + +; X32-MinGW: pushl $4 +; X32-MinGW-NEXT: pushl $0 +; X32-MinGW-NEXT: calll ___morestack +; X32-MinGW-NEXT: ret + +; X64-FreeBSD: cmpq %fs:24, %rsp +; X64-FreeBSD-NEXT: ja .LBB1_2 + +; X64-FreeBSD: movq %r10, %rax +; X64-FreeBSD-NEXT: movabsq $0, %r10 +; X64-FreeBSD-NEXT: movabsq $0, %r11 +; X64-FreeBSD-NEXT: callq __morestack +; X64-FreeBSD-NEXT: ret +; X64-FreeBSD-NEXT: movq %rax, %r10 + +} + +define void @test_large() { + %mem = alloca i32, i32 10000 + call void @dummy_use (i32* %mem, i32 0) + ret void + +; X32-Linux: leal -40012(%esp), %ecx +; X32-Linux-NEXT: cmpl %gs:48, %ecx +; X32-Linux-NEXT: ja .LBB2_2 + +; X32-Linux: pushl $0 +; X32-Linux-NEXT: pushl $40012 +; X32-Linux-NEXT: calll __morestack +; X32-Linux-NEXT: ret + +; X64-Linux: leaq -40008(%rsp), %r11 +; X64-Linux-NEXT: cmpq %fs:112, %r11 +; X64-Linux-NEXT: ja .LBB2_2 + +; X64-Linux: movabsq $40008, %r10 +; X64-Linux-NEXT: movabsq $0, %r11 +; X64-Linux-NEXT: callq __morestack +; X64-Linux-NEXT: ret + +; X32-Darwin: leal -40012(%esp), %ecx +; X32-Darwin-NEXT: movl $432, %eax +; X32-Darwin-NEXT: cmpl %gs:(%eax), %ecx +; X32-Darwin-NEXT: ja LBB2_2 + +; X32-Darwin: pushl $0 +; X32-Darwin-NEXT: pushl $40012 +; X32-Darwin-NEXT: calll ___morestack +; X32-Darwin-NEXT: ret + +; X64-Darwin: leaq -40008(%rsp), %r11 +; X64-Darwin-NEXT: cmpq %gs:816, %r11 +; X64-Darwin-NEXT: ja LBB2_2 + +; X64-Darwin: movabsq $40008, %r10 +; X64-Darwin-NEXT: movabsq $0, %r11 +; X64-Darwin-NEXT: callq ___morestack +; X64-Darwin-NEXT: ret + +; X32-MinGW: leal -40008(%esp), %ecx +; X32-MinGW-NEXT: cmpl %fs:20, %ecx +; X32-MinGW-NEXT: ja LBB2_2 + +; X32-MinGW: pushl $0 +; X32-MinGW-NEXT: pushl $40008 +; X32-MinGW-NEXT: calll ___morestack +; X32-MinGW-NEXT: ret + +; X64-FreeBSD: leaq -40008(%rsp), %r11 +; X64-FreeBSD-NEXT: cmpq %fs:24, %r11 +; X64-FreeBSD-NEXT: ja .LBB2_2 + +; X64-FreeBSD: movabsq $40008, %r10 +; X64-FreeBSD-NEXT: movabsq $0, %r11 +; X64-FreeBSD-NEXT: callq __morestack +; X64-FreeBSD-NEXT: ret + +} + +define fastcc void @test_fastcc() { + %mem = alloca i32, i32 10 + call void @dummy_use (i32* %mem, i32 10) + ret void + +; X32-Linux: test_fastcc: + +; X32-Linux: cmpl %gs:48, %esp +; X32-Linux-NEXT: ja .LBB3_2 + +; X32-Linux: pushl $0 +; X32-Linux-NEXT: pushl $60 +; X32-Linux-NEXT: calll __morestack +; X32-Linux-NEXT: ret + +; X64-Linux: test_fastcc: + +; X64-Linux: cmpq %fs:112, %rsp +; X64-Linux-NEXT: ja .LBB3_2 + +; X64-Linux: movabsq $40, %r10 +; X64-Linux-NEXT: movabsq $0, %r11 +; X64-Linux-NEXT: callq __morestack +; X64-Linux-NEXT: ret + +; X32-Darwin: test_fastcc: + +; X32-Darwin: movl $432, %eax +; X32-Darwin-NEXT: cmpl %gs:(%eax), %esp +; X32-Darwin-NEXT: ja LBB3_2 + +; X32-Darwin: pushl $0 +; X32-Darwin-NEXT: pushl $60 +; X32-Darwin-NEXT: calll ___morestack +; X32-Darwin-NEXT: ret + +; X64-Darwin: test_fastcc: + +; X64-Darwin: cmpq %gs:816, %rsp +; X64-Darwin-NEXT: ja LBB3_2 + +; X64-Darwin: movabsq $40, %r10 +; X64-Darwin-NEXT: movabsq $0, %r11 +; X64-Darwin-NEXT: callq ___morestack +; X64-Darwin-NEXT: ret + +; X32-MinGW: test_fastcc: + +; X32-MinGW: cmpl %fs:20, %esp +; X32-MinGW-NEXT: ja LBB3_2 + +; X32-MinGW: pushl $0 +; X32-MinGW-NEXT: pushl $48 +; X32-MinGW-NEXT: calll ___morestack +; X32-MinGW-NEXT: ret + +; X64-FreeBSD: test_fastcc: + +; X64-FreeBSD: cmpq %fs:24, %rsp +; X64-FreeBSD-NEXT: ja .LBB3_2 + +; X64-FreeBSD: movabsq $40, %r10 +; X64-FreeBSD-NEXT: movabsq $0, %r11 +; X64-FreeBSD-NEXT: callq __morestack +; X64-FreeBSD-NEXT: ret + +} + +define fastcc void @test_fastcc_large() { + %mem = alloca i32, i32 10000 + call void @dummy_use (i32* %mem, i32 0) + ret void + +; X32-Linux: test_fastcc_large: + +; X32-Linux: leal -40012(%esp), %eax +; X32-Linux-NEXT: cmpl %gs:48, %eax +; X32-Linux-NEXT: ja .LBB4_2 + +; X32-Linux: pushl $0 +; X32-Linux-NEXT: pushl $40012 +; X32-Linux-NEXT: calll __morestack +; X32-Linux-NEXT: ret + +; X64-Linux: test_fastcc_large: + +; X64-Linux: leaq -40008(%rsp), %r11 +; X64-Linux-NEXT: cmpq %fs:112, %r11 +; X64-Linux-NEXT: ja .LBB4_2 + +; X64-Linux: movabsq $40008, %r10 +; X64-Linux-NEXT: movabsq $0, %r11 +; X64-Linux-NEXT: callq __morestack +; X64-Linux-NEXT: ret + +; X32-Darwin: test_fastcc_large: + +; X32-Darwin: leal -40012(%esp), %eax +; X32-Darwin-NEXT: movl $432, %ecx +; X32-Darwin-NEXT: cmpl %gs:(%ecx), %eax +; X32-Darwin-NEXT: ja LBB4_2 + +; X32-Darwin: pushl $0 +; X32-Darwin-NEXT: pushl $40012 +; X32-Darwin-NEXT: calll ___morestack +; X32-Darwin-NEXT: ret + +; X64-Darwin: test_fastcc_large: + +; X64-Darwin: leaq -40008(%rsp), %r11 +; X64-Darwin-NEXT: cmpq %gs:816, %r11 +; X64-Darwin-NEXT: ja LBB4_2 + +; X64-Darwin: movabsq $40008, %r10 +; X64-Darwin-NEXT: movabsq $0, %r11 +; X64-Darwin-NEXT: callq ___morestack +; X64-Darwin-NEXT: ret + +; X32-MinGW: test_fastcc_large: + +; X32-MinGW: leal -40008(%esp), %eax +; X32-MinGW-NEXT: cmpl %fs:20, %eax +; X32-MinGW-NEXT: ja LBB4_2 + +; X32-MinGW: pushl $0 +; X32-MinGW-NEXT: pushl $40008 +; X32-MinGW-NEXT: calll ___morestack +; X32-MinGW-NEXT: ret + +; X64-FreeBSD: test_fastcc_large: + +; X64-FreeBSD: leaq -40008(%rsp), %r11 +; X64-FreeBSD-NEXT: cmpq %fs:24, %r11 +; X64-FreeBSD-NEXT: ja .LBB4_2 + +; X64-FreeBSD: movabsq $40008, %r10 +; X64-FreeBSD-NEXT: movabsq $0, %r11 +; X64-FreeBSD-NEXT: callq __morestack +; X64-FreeBSD-NEXT: ret + +} + +define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) { + %mem = alloca i32, i32 10000 + call void @dummy_use (i32* %mem, i32 %a) + ret void +; This is testing that the Mac implementation preserves ecx -; X32: subl $8, %esp -; X32-NEXT: pushl $4 -; X32-NEXT: pushl $0 -; X32-NEXT: calll __morestack -; X32-NEXT: addl $8, %esp -; X32-NEXT: ret +; X32-Darwin: test_fastcc_large_with_ecx_arg: -; X64: leaq (%rsp), %r11 -; X64-NEXT: cmpq %fs:112, %r11 +; X32-Darwin: leal -40012(%esp), %eax +; X32-Darwin-NEXT: pushl %ecx +; X32-Darwin-NEXT: movl $432, %ecx +; X32-Darwin-NEXT: cmpl %gs:(%ecx), %eax +; X32-Darwin-NEXT: popl %ecx +; X32-Darwin-NEXT: ja LBB5_2 -; X64: movq %r10, %rax -; X64-NEXT: movabsq $0, %r10 -; X64-NEXT: movabsq $0, %r11 -; X64-NEXT: callq __morestack -; X64-NEXT: ret -; X64: movq %rax, %r10 +; X32-Darwin: pushl $0 +; X32-Darwin-NEXT: pushl $40012 +; X32-Darwin-NEXT: calll ___morestack +; X32-Darwin-NEXT: ret } diff --git a/test/CodeGen/X86/sext-subreg.ll b/test/CodeGen/X86/sext-subreg.ll index b2b9f81..a128af9 100644 --- a/test/CodeGen/X86/sext-subreg.ll +++ b/test/CodeGen/X86/sext-subreg.ll @@ -8,10 +8,10 @@ define i64 @t(i64 %A, i64 %B, i32* %P, i64 *%P2) nounwind { ; CHECK: movl %eax %C = add i64 %A, %B %D = trunc i64 %C to i32 - volatile store i32 %D, i32* %P + store volatile i32 %D, i32* %P %E = shl i64 %C, 32 %F = ashr i64 %E, 32 - volatile store i64 %F, i64 *%P2 - volatile store i32 %D, i32* %P + store volatile i64 %F, i64 *%P2 + store volatile i32 %D, i32* %P ret i64 undef } diff --git a/test/CodeGen/X86/shift-and.ll b/test/CodeGen/X86/shift-and.ll index fd278c2..b747cc5 100644 --- a/test/CodeGen/X86/shift-and.ll +++ b/test/CodeGen/X86/shift-and.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 | grep and | count 1 +; RUN: llc < %s -march=x86 | grep and | count 2 ; RUN: llc < %s -march=x86-64 | not grep and define i32 @t1(i32 %t, i32 %val) nounwind { @@ -7,9 +7,15 @@ define i32 @t1(i32 %t, i32 %val) nounwind { ret i32 %res } +define i32 @t2(i32 %t, i32 %val) nounwind { + %shamt = and i32 %t, 63 + %res = shl i32 %val, %shamt + ret i32 %res +} + @X = internal global i16 0 -define void @t2(i16 %t) nounwind { +define void @t3(i16 %t) nounwind { %shamt = and i16 %t, 31 %tmp = load i16* @X %tmp1 = ashr i16 %tmp, %shamt @@ -17,8 +23,14 @@ define void @t2(i16 %t) nounwind { ret void } -define i64 @t3(i64 %t, i64 %val) nounwind { +define i64 @t4(i64 %t, i64 %val) nounwind { %shamt = and i64 %t, 63 %res = lshr i64 %val, %shamt ret i64 %res } + +define i64 @t5(i64 %t, i64 %val) nounwind { + %shamt = and i64 %t, 191 + %res = lshr i64 %val, %shamt + ret i64 %res +} diff --git a/test/CodeGen/X86/shift-combine.ll b/test/CodeGen/X86/shift-combine.ll index e443ac1..51f8303 100644 --- a/test/CodeGen/X86/shift-combine.ll +++ b/test/CodeGen/X86/shift-combine.ll @@ -1,15 +1,19 @@ -; RUN: llc < %s | not grep shrl +; RUN: llc -march=x86 < %s | FileCheck %s -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i686-apple-darwin8" -@array = weak global [4 x i32] zeroinitializer ; <[4 x i32]*> [#uses=1] +@array = weak global [4 x i32] zeroinitializer + +define i32 @test_lshr_and(i32 %x) { +; CHECK: test_lshr_and: +; CHECK-NOT: shrl +; CHECK: andl $12, +; CHECK: movl {{.*}}array{{.*}}, +; CHECK: ret -define i32 @foo(i32 %x) { entry: - %tmp2 = lshr i32 %x, 2 ; <i32> [#uses=1] - %tmp3 = and i32 %tmp2, 3 ; <i32> [#uses=1] - %tmp4 = getelementptr [4 x i32]* @array, i32 0, i32 %tmp3 ; <i32*> [#uses=1] - %tmp5 = load i32* %tmp4, align 4 ; <i32> [#uses=1] - ret i32 %tmp5 + %tmp2 = lshr i32 %x, 2 + %tmp3 = and i32 %tmp2, 3 + %tmp4 = getelementptr [4 x i32]* @array, i32 0, i32 %tmp3 + %tmp5 = load i32* %tmp4, align 4 + ret i32 %tmp5 } diff --git a/test/CodeGen/X86/shift-folding.ll b/test/CodeGen/X86/shift-folding.ll index d9c3061..3ea6011 100644 --- a/test/CodeGen/X86/shift-folding.ll +++ b/test/CodeGen/X86/shift-folding.ll @@ -1,28 +1,70 @@ -; RUN: llc < %s -march=x86 | \ -; RUN: grep {s\[ah\]\[rl\]l} | count 1 - -define i32* @test1(i32* %P, i32 %X) nounwind { - %Y = lshr i32 %X, 2 ; <i32> [#uses=1] - %gep.upgrd.1 = zext i32 %Y to i64 ; <i64> [#uses=1] - %P2 = getelementptr i32* %P, i64 %gep.upgrd.1 ; <i32*> [#uses=1] - ret i32* %P2 +; RUN: llc < %s -march=x86 | FileCheck %s + +define i32* @test1(i32* %P, i32 %X) { +; CHECK: test1: +; CHECK-NOT: shrl +; CHECK-NOT: shll +; CHECK: ret + +entry: + %Y = lshr i32 %X, 2 + %gep.upgrd.1 = zext i32 %Y to i64 + %P2 = getelementptr i32* %P, i64 %gep.upgrd.1 + ret i32* %P2 } -define i32* @test2(i32* %P, i32 %X) nounwind { - %Y = shl i32 %X, 2 ; <i32> [#uses=1] - %gep.upgrd.2 = zext i32 %Y to i64 ; <i64> [#uses=1] - %P2 = getelementptr i32* %P, i64 %gep.upgrd.2 ; <i32*> [#uses=1] - ret i32* %P2 +define i32* @test2(i32* %P, i32 %X) { +; CHECK: test2: +; CHECK: shll $4 +; CHECK-NOT: shll +; CHECK: ret + +entry: + %Y = shl i32 %X, 2 + %gep.upgrd.2 = zext i32 %Y to i64 + %P2 = getelementptr i32* %P, i64 %gep.upgrd.2 + ret i32* %P2 } -define i32* @test3(i32* %P, i32 %X) nounwind { - %Y = ashr i32 %X, 2 ; <i32> [#uses=1] - %P2 = getelementptr i32* %P, i32 %Y ; <i32*> [#uses=1] - ret i32* %P2 +define i32* @test3(i32* %P, i32 %X) { +; CHECK: test3: +; CHECK-NOT: shrl +; CHECK-NOT: shll +; CHECK: ret + +entry: + %Y = ashr i32 %X, 2 + %P2 = getelementptr i32* %P, i32 %Y + ret i32* %P2 } -define fastcc i32 @test4(i32* %d) nounwind { +define fastcc i32 @test4(i32* %d) { +; CHECK: test4: +; CHECK-NOT: shrl +; CHECK: ret + +entry: %tmp4 = load i32* %d %tmp512 = lshr i32 %tmp4, 24 ret i32 %tmp512 } + +define i64 @test5(i16 %i, i32* %arr) { +; Ensure that we don't fold away shifts which have multiple uses, as they are +; just re-introduced for the second use. +; CHECK: test5: +; CHECK-NOT: shrl +; CHECK: shrl $11 +; CHECK-NOT: shrl +; CHECK: ret + +entry: + %i.zext = zext i16 %i to i32 + %index = lshr i32 %i.zext, 11 + %index.zext = zext i32 %index to i64 + %val.ptr = getelementptr inbounds i32* %arr, i64 %index.zext + %val = load i32* %val.ptr + %val.zext = zext i32 %val to i64 + %sum = add i64 %val.zext, %index.zext + ret i64 %sum +} diff --git a/test/CodeGen/X86/shl-i64.ll b/test/CodeGen/X86/shl-i64.ll new file mode 100644 index 0000000..f00058a --- /dev/null +++ b/test/CodeGen/X86/shl-i64.ll @@ -0,0 +1,20 @@ +; RUN: llc -march=x86 -mattr=+sse2 < %s | FileCheck %s + +; Make sure that we don't generate an illegal i64 extract after LegalizeType. +; CHECK: shll + + +define void @test_cl(<4 x i64>* %dst, <4 x i64>* %src, i32 %idx) { +entry: + %arrayidx = getelementptr inbounds <4 x i64> * %src, i32 %idx + %0 = load <4 x i64> * %arrayidx, align 32 + %arrayidx1 = getelementptr inbounds <4 x i64> * %dst, i32 %idx + %1 = load <4 x i64> * %arrayidx1, align 32 + %2 = extractelement <4 x i64> %1, i32 0 + %and = and i64 %2, 63 + %3 = insertelement <4 x i64> undef, i64 %and, i32 0 + %splat = shufflevector <4 x i64> %3, <4 x i64> undef, <4 x i32> zeroinitializer + %shl = shl <4 x i64> %0, %splat + store <4 x i64> %shl, <4 x i64> * %arrayidx1, align 32 + ret void +} diff --git a/test/CodeGen/X86/sibcall-5.ll b/test/CodeGen/X86/sibcall-5.ll index 9d74121..937817e 100644 --- a/test/CodeGen/X86/sibcall-5.ll +++ b/test/CodeGen/X86/sibcall-5.ll @@ -1,5 +1,6 @@ ; RUN: llc < %s -mtriple=i386-apple-darwin8 -mattr=+sse2 | FileCheck %s --check-prefix=X32 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=+sse2 | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=-sse3 | FileCheck %s --check-prefix=X64_BAD ; Sibcall optimization of expanded libcalls. ; rdar://8707777 @@ -29,3 +30,31 @@ entry: declare float @sinf(float) nounwind readonly declare double @sin(double) nounwind readonly + +; rdar://10930395 +%0 = type opaque + +@"\01L_OBJC_SELECTOR_REFERENCES_2" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" + +define hidden { double, double } @foo2(%0* %self, i8* nocapture %_cmd) uwtable optsize ssp { +; X64_BAD: foo +; X64_BAD: call +; X64_BAD: call +; X64_BAD: call + %1 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2", align 8, !invariant.load !0 + %2 = bitcast %0* %self to i8* + %3 = tail call { double, double } bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to { double, double } (i8*, i8*)*)(i8* %2, i8* %1) optsize + %4 = extractvalue { double, double } %3, 0 + %5 = extractvalue { double, double } %3, 1 + %6 = tail call double @floor(double %4) optsize + %7 = tail call double @floor(double %5) optsize + %insert.i.i = insertvalue { double, double } undef, double %6, 0 + %insert5.i.i = insertvalue { double, double } %insert.i.i, double %7, 1 + ret { double, double } %insert5.i.i +} + +declare i8* @objc_msgSend(i8*, i8*, ...) + +declare double @floor(double) optsize + +!0 = metadata !{} diff --git a/test/CodeGen/X86/splat-scalar-load.ll b/test/CodeGen/X86/splat-scalar-load.ll index 2b13029..81a072f 100644 --- a/test/CodeGen/X86/splat-scalar-load.ll +++ b/test/CodeGen/X86/splat-scalar-load.ll @@ -1,7 +1,7 @@ ; RUN: llc < %s -mtriple=i386-apple-darwin -mattr=+sse2 | FileCheck %s ; rdar://7434544 -define <2 x i64> @t2() nounwind ssp { +define <2 x i64> @t2() nounwind { entry: ; CHECK: t2: ; CHECK: pshufd $85, (%esp), %xmm0 diff --git a/test/CodeGen/X86/sret.ll b/test/CodeGen/X86/sret.ll deleted file mode 100644 index b945530..0000000 --- a/test/CodeGen/X86/sret.ll +++ /dev/null @@ -1,23 +0,0 @@ -; RUN: llc < %s -march=x86 | grep ret | grep 4 - - %struct.foo = type { [4 x i32] } - -define void @bar(%struct.foo* noalias sret %agg.result) nounwind { -entry: - %tmp1 = getelementptr %struct.foo* %agg.result, i32 0, i32 0 - %tmp3 = getelementptr [4 x i32]* %tmp1, i32 0, i32 0 - store i32 1, i32* %tmp3, align 8 - ret void -} - -@dst = external global i32 - -define void @foo() nounwind { - %memtmp = alloca %struct.foo, align 4 - call void @bar( %struct.foo* sret %memtmp ) nounwind - %tmp4 = getelementptr %struct.foo* %memtmp, i32 0, i32 0 - %tmp5 = getelementptr [4 x i32]* %tmp4, i32 0, i32 0 - %tmp6 = load i32* %tmp5 - store i32 %tmp6, i32* @dst - ret void -} diff --git a/test/CodeGen/X86/sse-align-3.ll b/test/CodeGen/X86/sse-align-3.ll index 04f2161..b6b0471 100644 --- a/test/CodeGen/X86/sse-align-3.ll +++ b/test/CodeGen/X86/sse-align-3.ll @@ -1,8 +1,8 @@ ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s ; CHECK-NOT: movapd ; CHECK: movaps -; CHECK-NOT: movaps -; CHECK: movapd +; CHECK-NOT: movapd +; CHECK: movaps ; CHECK-NOT: movap define void @foo(<4 x float>* %p, <4 x float> %x) nounwind { diff --git a/test/CodeGen/X86/sse-domains.ll b/test/CodeGen/X86/sse-domains.ll new file mode 100644 index 0000000..d1e07c8 --- /dev/null +++ b/test/CodeGen/X86/sse-domains.ll @@ -0,0 +1,87 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7" + +; CHECK: f +; +; This function contains load / store / and operations that all can execute in +; any domain. The only domain-specific operation is the %add = shl... operation +; which is <4 x i32>. +; +; The paddd instruction can only influence the other operations through the loop +; back-edge. Check that everything is still moved into the integer domain. + +define void @f(<4 x i32>* nocapture %p, i32 %n) nounwind uwtable ssp { +entry: + br label %while.body + +; Materialize a zeroinitializer and a constant-pool load in the integer domain. +; The order is not important. +; CHECK: pxor +; CHECK: movdqa + +; The instructions in the loop must all be integer domain as well. +; CHECK: while.body +; CHECK: pand +; CHECK: movdqa +; CHECK: movdqa +; Finally, the controlling integer-only instruction. +; CHECK: paddd +while.body: + %p.addr.04 = phi <4 x i32>* [ %incdec.ptr, %while.body ], [ %p, %entry ] + %n.addr.03 = phi i32 [ %dec, %while.body ], [ %n, %entry ] + %x.02 = phi <4 x i32> [ %add, %while.body ], [ zeroinitializer, %entry ] + %dec = add nsw i32 %n.addr.03, -1 + %and = and <4 x i32> %x.02, <i32 127, i32 127, i32 127, i32 127> + %incdec.ptr = getelementptr inbounds <4 x i32>* %p.addr.04, i64 1 + store <4 x i32> %and, <4 x i32>* %p.addr.04, align 16 + %0 = load <4 x i32>* %incdec.ptr, align 16 + %add = shl <4 x i32> %0, <i32 1, i32 1, i32 1, i32 1> + %tobool = icmp eq i32 %dec, 0 + br i1 %tobool, label %while.end, label %while.body + +while.end: + ret void +} + +; CHECK: f2 +; CHECK: for.body +; +; This loop contains two cvtsi2ss instructions that update the same xmm +; register. Verify that the execution dependency fix pass breaks those +; dependencies by inserting xorps instructions. +; +; If the register allocator chooses different registers for the two cvtsi2ss +; instructions, they are still dependent on themselves. +; CHECK: xorps [[XMM1:%xmm[0-9]+]] +; CHECK: , [[XMM1]] +; CHECK: cvtsi2ss %{{.*}}, [[XMM1]] +; CHECK: xorps [[XMM2:%xmm[0-9]+]] +; CHECK: , [[XMM2]] +; CHECK: cvtsi2ss %{{.*}}, [[XMM2]] +; +define float @f2(i32 %m) nounwind uwtable readnone ssp { +entry: + %tobool3 = icmp eq i32 %m, 0 + br i1 %tobool3, label %for.end, label %for.body + +for.body: ; preds = %entry, %for.body + %m.addr.07 = phi i32 [ %dec, %for.body ], [ %m, %entry ] + %s1.06 = phi float [ %add, %for.body ], [ 0.000000e+00, %entry ] + %s2.05 = phi float [ %add2, %for.body ], [ 0.000000e+00, %entry ] + %n.04 = phi i32 [ %inc, %for.body ], [ 1, %entry ] + %conv = sitofp i32 %n.04 to float + %add = fadd float %s1.06, %conv + %conv1 = sitofp i32 %m.addr.07 to float + %add2 = fadd float %s2.05, %conv1 + %inc = add nsw i32 %n.04, 1 + %dec = add nsw i32 %m.addr.07, -1 + %tobool = icmp eq i32 %dec, 0 + br i1 %tobool, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %s1.0.lcssa = phi float [ 0.000000e+00, %entry ], [ %add, %for.body ] + %s2.0.lcssa = phi float [ 0.000000e+00, %entry ], [ %add2, %for.body ] + %sub = fsub float %s1.0.lcssa, %s2.0.lcssa + ret float %sub +} diff --git a/test/CodeGen/X86/sse-minmax.ll b/test/CodeGen/X86/sse-minmax.ll index af1a73b..1112440 100644 --- a/test/CodeGen/X86/sse-minmax.ll +++ b/test/CodeGen/X86/sse-minmax.ll @@ -140,15 +140,15 @@ define double @ole_inverse(double %x, double %y) nounwind { } ; CHECK: x_ogt: -; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; CHECK-NEXT: maxsd %xmm1, %xmm0 ; CHECK-NEXT: ret ; UNSAFE: x_ogt: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ogt: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: maxsd %xmm1, %xmm0 ; FINITE-NEXT: ret define double @x_ogt(double %x) nounwind { @@ -158,15 +158,15 @@ define double @x_ogt(double %x) nounwind { } ; CHECK: x_olt: -; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; CHECK-NEXT: minsd %xmm1, %xmm0 ; CHECK-NEXT: ret ; UNSAFE: x_olt: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_olt: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: minsd %xmm1, %xmm0 ; FINITE-NEXT: ret define double @x_olt(double %x) nounwind { @@ -176,17 +176,17 @@ define double @x_olt(double %x) nounwind { } ; CHECK: x_ogt_inverse: -; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; CHECK-NEXT: minsd %xmm0, %xmm1 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; CHECK-NEXT: ret ; UNSAFE: x_ogt_inverse: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ogt_inverse: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: minsd %xmm0, %xmm1 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; FINITE-NEXT: ret @@ -197,17 +197,17 @@ define double @x_ogt_inverse(double %x) nounwind { } ; CHECK: x_olt_inverse: -; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; CHECK-NEXT: maxsd %xmm0, %xmm1 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; CHECK-NEXT: ret ; UNSAFE: x_olt_inverse: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_olt_inverse: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: maxsd %xmm0, %xmm1 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; FINITE-NEXT: ret @@ -220,11 +220,11 @@ define double @x_olt_inverse(double %x) nounwind { ; CHECK: x_oge: ; CHECK: ucomisd %xmm1, %xmm0 ; UNSAFE: x_oge: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_oge: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: maxsd %xmm1, %xmm0 ; FINITE-NEXT: ret define double @x_oge(double %x) nounwind { @@ -236,11 +236,11 @@ define double @x_oge(double %x) nounwind { ; CHECK: x_ole: ; CHECK: ucomisd %xmm0, %xmm1 ; UNSAFE: x_ole: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ole: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: minsd %xmm1, %xmm0 ; FINITE-NEXT: ret define double @x_ole(double %x) nounwind { @@ -252,12 +252,12 @@ define double @x_ole(double %x) nounwind { ; CHECK: x_oge_inverse: ; CHECK: ucomisd %xmm1, %xmm0 ; UNSAFE: x_oge_inverse: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_oge_inverse: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: minsd %xmm0, %xmm1 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; FINITE-NEXT: ret @@ -270,12 +270,12 @@ define double @x_oge_inverse(double %x) nounwind { ; CHECK: x_ole_inverse: ; CHECK: ucomisd %xmm0, %xmm1 ; UNSAFE: x_ole_inverse: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ole_inverse: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: maxsd %xmm0, %xmm1 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; FINITE-NEXT: ret @@ -414,11 +414,11 @@ define double @ule_inverse(double %x, double %y) nounwind { ; CHECK: x_ugt: ; CHECK: ucomisd %xmm0, %xmm1 ; UNSAFE: x_ugt: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ugt: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: maxsd %xmm1, %xmm0 ; FINITE-NEXT: ret define double @x_ugt(double %x) nounwind { @@ -430,11 +430,11 @@ define double @x_ugt(double %x) nounwind { ; CHECK: x_ult: ; CHECK: ucomisd %xmm1, %xmm0 ; UNSAFE: x_ult: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ult: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: minsd %xmm1, %xmm0 ; FINITE-NEXT: ret define double @x_ult(double %x) nounwind { @@ -446,12 +446,12 @@ define double @x_ult(double %x) nounwind { ; CHECK: x_ugt_inverse: ; CHECK: ucomisd %xmm0, %xmm1 ; UNSAFE: x_ugt_inverse: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ugt_inverse: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: minsd %xmm0, %xmm1 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; FINITE-NEXT: ret @@ -464,12 +464,12 @@ define double @x_ugt_inverse(double %x) nounwind { ; CHECK: x_ult_inverse: ; CHECK: ucomisd %xmm1, %xmm0 ; UNSAFE: x_ult_inverse: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ult_inverse: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: maxsd %xmm0, %xmm1 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; FINITE-NEXT: ret @@ -480,16 +480,16 @@ define double @x_ult_inverse(double %x) nounwind { } ; CHECK: x_uge: -; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; CHECK-NEXT: maxsd %xmm0, %xmm1 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; CHECK-NEXT: ret ; UNSAFE: x_uge: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_uge: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: maxsd %xmm1, %xmm0 ; FINITE-NEXT: ret define double @x_uge(double %x) nounwind { @@ -499,16 +499,16 @@ define double @x_uge(double %x) nounwind { } ; CHECK: x_ule: -; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; CHECK-NEXT: minsd %xmm0, %xmm1 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; CHECK-NEXT: ret ; UNSAFE: x_ule: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: minsd %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ule: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: minsd %xmm1, %xmm0 ; FINITE-NEXT: ret define double @x_ule(double %x) nounwind { @@ -518,16 +518,16 @@ define double @x_ule(double %x) nounwind { } ; CHECK: x_uge_inverse: -; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; CHECK-NEXT: minsd %xmm1, %xmm0 ; CHECK-NEXT: ret ; UNSAFE: x_uge_inverse: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: minsd %xmm0, %xmm1 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_uge_inverse: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: minsd %xmm0, %xmm1 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; FINITE-NEXT: ret @@ -538,16 +538,16 @@ define double @x_uge_inverse(double %x) nounwind { } ; CHECK: x_ule_inverse: -; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; CHECK-NEXT: maxsd %xmm1, %xmm0 ; CHECK-NEXT: ret ; UNSAFE: x_ule_inverse: -; UNSAFE-NEXT: pxor %xmm1, %xmm1 +; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; UNSAFE-NEXT: ret ; FINITE: x_ule_inverse: -; FINITE-NEXT: pxor %xmm1, %xmm1 +; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1 ; FINITE-NEXT: maxsd %xmm0, %xmm1 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0 ; FINITE-NEXT: ret diff --git a/test/CodeGen/X86/sse2-blend.ll b/test/CodeGen/X86/sse2-blend.ll index 56b099e..2f4317b 100644 --- a/test/CodeGen/X86/sse2-blend.ll +++ b/test/CodeGen/X86/sse2-blend.ll @@ -1,8 +1,10 @@ -; RUN: llc < %s -march=x86 -mcpu=yonah -promote-elements -mattr=+sse2,-sse41 | FileCheck %s - - -; currently (xor v4i32) is defined as illegal, so we scalarize the code. +; RUN: llc < %s -march=x86 -mcpu=yonah -mattr=+sse2,-sse41 | FileCheck %s +; CHECK: vsel_float +; CHECK: pandn +; CHECK: pand +; CHECK: por +; CHECK: ret define void@vsel_float(<4 x float>* %v1, <4 x float>* %v2) { %A = load <4 x float>* %v1 %B = load <4 x float>* %v2 @@ -11,8 +13,11 @@ define void@vsel_float(<4 x float>* %v1, <4 x float>* %v2) { ret void } -; currently (xor v4i32) is defined as illegal, so we scalarize the code. - +; CHECK: vsel_i32 +; CHECK: pandn +; CHECK: pand +; CHECK: por +; CHECK: ret define void@vsel_i32(<4 x i32>* %v1, <4 x i32>* %v2) { %A = load <4 x i32>* %v1 %B = load <4 x i32>* %v2 @@ -21,9 +26,10 @@ define void@vsel_i32(<4 x i32>* %v1, <4 x i32>* %v2) { ret void } +; Without forcing instructions, fall back to the preferred PS domain. ; CHECK: vsel_i64 -; CHECK: pxor -; CHECK: pand +; CHECK: xorps +; CHECK: andps ; CHECK: andnps ; CHECK: orps ; CHECK: ret @@ -36,14 +42,14 @@ define void@vsel_i64(<4 x i64>* %v1, <4 x i64>* %v2) { ret void } +; Without forcing instructions, fall back to the preferred PS domain. ; CHECK: vsel_double -; CHECK: pxor -; CHECK: pand +; CHECK: xorps +; CHECK: andps ; CHECK: andnps ; CHECK: orps ; CHECK: ret - define void@vsel_double(<4 x double>* %v1, <4 x double>* %v2) { %A = load <4 x double>* %v1 %B = load <4 x double>* %v2 diff --git a/test/CodeGen/X86/sse2.ll b/test/CodeGen/X86/sse2.ll index 70e0a8a..36a0fd9 100644 --- a/test/CodeGen/X86/sse2.ll +++ b/test/CodeGen/X86/sse2.ll @@ -98,7 +98,7 @@ define void @test7() nounwind { ret void ; CHECK: test7: -; CHECK: pxor %xmm0, %xmm0 +; CHECK: xorps %xmm0, %xmm0 ; CHECK: movaps %xmm0, 0 } @@ -144,7 +144,7 @@ define <2 x double> @test11(double %a, double %b) nounwind { %tmp7 = insertelement <2 x double> %tmp, double %b, i32 1 ; <<2 x double>> [#uses=1] ret <2 x double> %tmp7 ; CHECK: test11: -; CHECK: movapd 4(%esp), %xmm0 +; CHECK: movaps 4(%esp), %xmm0 } define void @test12() nounwind { @@ -178,8 +178,8 @@ define <4 x float> @test14(<4 x float>* %x, <4 x float>* %y) nounwind { %tmp27 = shufflevector <4 x float> %tmp9, <4 x float> %tmp21, <4 x i32> < i32 0, i32 1, i32 4, i32 5 > ; <<4 x float>> [#uses=1] ret <4 x float> %tmp27 ; CHECK: test14: -; CHECK: addps [[X1:%xmm[0-9]+]], [[X0:%xmm[0-9]+]] -; CHECK: subps [[X1]], [[X2:%xmm[0-9]+]] +; CHECK: subps [[X1:%xmm[0-9]+]], [[X2:%xmm[0-9]+]] +; CHECK: addps [[X1]], [[X0:%xmm[0-9]+]] ; CHECK: movlhps [[X2]], [[X0]] } diff --git a/test/CodeGen/X86/sse3.ll b/test/CodeGen/X86/sse3.ll index 8b3a317..5ea1b4d 100644 --- a/test/CodeGen/X86/sse3.ll +++ b/test/CodeGen/X86/sse3.ll @@ -16,10 +16,8 @@ entry: ret void ; X64: t0: -; X64: movddup (%rsi), %xmm0 -; X64: pshuflw $0, %xmm0, %xmm0 -; X64: xorl %eax, %eax -; X64: pinsrw $0, %eax, %xmm0 +; X64: movdqa (%rsi), %xmm0 +; X64: pslldq $2, %xmm0 ; X64: movdqa %xmm0, (%rdi) ; X64: ret } @@ -31,9 +29,8 @@ define <8 x i16> @t1(<8 x i16>* %A, <8 x i16>* %B) nounwind { ret <8 x i16> %tmp3 ; X64: t1: -; X64: movl (%rsi), %eax ; X64: movdqa (%rdi), %xmm0 -; X64: pinsrw $0, %eax, %xmm0 +; X64: pinsrw $0, (%rsi), %xmm0 ; X64: ret } @@ -167,12 +164,12 @@ define internal void @t10() nounwind { store <4 x i16> %6, <4 x i16>* @g2, align 8 ret void ; X64: t10: -; X64: pextrw $4, [[X0:%xmm[0-9]+]], %eax -; X64: unpcklpd [[X1:%xmm[0-9]+]] -; X64: pshuflw $8, [[X1]], [[X2:%xmm[0-9]+]] -; X64: pinsrw $2, %eax, [[X2]] +; X64: pextrw $4, [[X0:%xmm[0-9]+]], %ecx ; X64: pextrw $6, [[X0]], %eax -; X64: pinsrw $3, %eax, [[X2]] +; X64: movlhps [[X0]], [[X0]] +; X64: pshuflw $8, [[X0]], [[X0]] +; X64: pinsrw $2, %ecx, [[X0]] +; X64: pinsrw $3, %eax, [[X0]] } @@ -229,7 +226,7 @@ entry: } - +; FIXME: t15 is worse off from disabling of scheduler 2-address hack. define <8 x i16> @t15(<8 x i16> %T0, <8 x i16> %T1) nounwind readnone { entry: %tmp8 = shufflevector <8 x i16> %T0, <8 x i16> %T1, <8 x i32> < i32 undef, i32 undef, i32 7, i32 2, i32 8, i32 undef, i32 undef , i32 undef > @@ -250,13 +247,11 @@ entry: %tmp9 = shufflevector <16 x i8> %tmp8, <16 x i8> %T0, <16 x i32> < i32 0, i32 1, i32 2, i32 17, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef , i32 undef > ret <16 x i8> %tmp9 ; X64: t16: -; X64: pinsrw $0, %eax, [[X1:%xmm[0-9]+]] -; X64: pextrw $8, [[X0:%xmm[0-9]+]], %eax -; X64: pinsrw $1, %eax, [[X1]] -; X64: pextrw $1, [[X1]], %ecx -; X64: movd [[X1]], %edx -; X64: pinsrw $0, %edx, %xmm -; X64: pinsrw $1, %eax, %xmm +; X64: pextrw $8, %xmm0, %eax +; X64: pslldq $2, %xmm0 +; X64: movd %xmm0, %ecx +; X64: pextrw $1, %xmm0, %edx +; X64: pinsrw $0, %ecx, %xmm0 ; X64: ret } diff --git a/test/CodeGen/X86/sse41.ll b/test/CodeGen/X86/sse41.ll index 2ac4cb4..54264b1 100644 --- a/test/CodeGen/X86/sse41.ll +++ b/test/CodeGen/X86/sse41.ll @@ -183,8 +183,8 @@ define <4 x float> @insertps_3(<4 x float> %t1, <4 x float> %t2) nounwind { ; X64: insertps $0, %xmm1, %xmm0 } -define i32 @ptestz_1(<4 x float> %t1, <4 x float> %t2) nounwind { - %tmp1 = call i32 @llvm.x86.sse41.ptestz(<4 x float> %t1, <4 x float> %t2) nounwind readnone +define i32 @ptestz_1(<2 x i64> %t1, <2 x i64> %t2) nounwind { + %tmp1 = call i32 @llvm.x86.sse41.ptestz(<2 x i64> %t1, <2 x i64> %t2) nounwind readnone ret i32 %tmp1 ; X32: _ptestz_1: ; X32: ptest %xmm1, %xmm0 @@ -195,8 +195,8 @@ define i32 @ptestz_1(<4 x float> %t1, <4 x float> %t2) nounwind { ; X64: sete %al } -define i32 @ptestz_2(<4 x float> %t1, <4 x float> %t2) nounwind { - %tmp1 = call i32 @llvm.x86.sse41.ptestc(<4 x float> %t1, <4 x float> %t2) nounwind readnone +define i32 @ptestz_2(<2 x i64> %t1, <2 x i64> %t2) nounwind { + %tmp1 = call i32 @llvm.x86.sse41.ptestc(<2 x i64> %t1, <2 x i64> %t2) nounwind readnone ret i32 %tmp1 ; X32: _ptestz_2: ; X32: ptest %xmm1, %xmm0 @@ -207,8 +207,8 @@ define i32 @ptestz_2(<4 x float> %t1, <4 x float> %t2) nounwind { ; X64: sbbl %eax } -define i32 @ptestz_3(<4 x float> %t1, <4 x float> %t2) nounwind { - %tmp1 = call i32 @llvm.x86.sse41.ptestnzc(<4 x float> %t1, <4 x float> %t2) nounwind readnone +define i32 @ptestz_3(<2 x i64> %t1, <2 x i64> %t2) nounwind { + %tmp1 = call i32 @llvm.x86.sse41.ptestnzc(<2 x i64> %t1, <2 x i64> %t2) nounwind readnone ret i32 %tmp1 ; X32: _ptestz_3: ; X32: ptest %xmm1, %xmm0 @@ -220,9 +220,9 @@ define i32 @ptestz_3(<4 x float> %t1, <4 x float> %t2) nounwind { } -declare i32 @llvm.x86.sse41.ptestz(<4 x float>, <4 x float>) nounwind readnone -declare i32 @llvm.x86.sse41.ptestc(<4 x float>, <4 x float>) nounwind readnone -declare i32 @llvm.x86.sse41.ptestnzc(<4 x float>, <4 x float>) nounwind readnone +declare i32 @llvm.x86.sse41.ptestz(<2 x i64>, <2 x i64>) nounwind readnone +declare i32 @llvm.x86.sse41.ptestc(<2 x i64>, <2 x i64>) nounwind readnone +declare i32 @llvm.x86.sse41.ptestnzc(<2 x i64>, <2 x i64>) nounwind readnone ; This used to compile to insertps $0 + insertps $16. insertps $0 is always ; pointless. diff --git a/test/CodeGen/X86/stack-align.ll b/test/CodeGen/X86/stack-align.ll index 793c026..f6c13ec 100644 --- a/test/CodeGen/X86/stack-align.ll +++ b/test/CodeGen/X86/stack-align.ll @@ -11,13 +11,13 @@ define void @test({ double, double }* byval %z, double* %P) nounwind { entry: %tmp3 = load double* @G, align 16 ; <double> [#uses=1] %tmp4 = tail call double @fabs( double %tmp3 ) ; <double> [#uses=1] - volatile store double %tmp4, double* %P + store volatile double %tmp4, double* %P %tmp = getelementptr { double, double }* %z, i32 0, i32 0 ; <double*> [#uses=1] - %tmp1 = volatile load double* %tmp, align 8 ; <double> [#uses=1] + %tmp1 = load volatile double* %tmp, align 8 ; <double> [#uses=1] %tmp2 = tail call double @fabs( double %tmp1 ) ; <double> [#uses=1] ; CHECK: andpd{{.*}}4(%esp), %xmm %tmp6 = fadd double %tmp4, %tmp2 ; <double> [#uses=1] - volatile store double %tmp6, double* %P, align 8 + store volatile double %tmp6, double* %P, align 8 ret void } diff --git a/test/CodeGen/X86/stack-align2.ll b/test/CodeGen/X86/stack-align2.ll new file mode 100644 index 0000000..18cce72 --- /dev/null +++ b/test/CodeGen/X86/stack-align2.ll @@ -0,0 +1,25 @@ +; RUN: llc < %s -mcpu=generic -mtriple=i386-linux | FileCheck %s -check-prefix=LINUX-I386 +; RUN: llc < %s -mcpu=generic -mtriple=i386-netbsd | FileCheck %s -check-prefix=NETBSD-I386 +; RUN: llc < %s -mcpu=generic -mtriple=i686-apple-darwin8 | FileCheck %s -check-prefix=DARWIN-I386 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s -check-prefix=LINUX-X86_64 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-netbsd | FileCheck %s -check-prefix=NETBSD-X86_64 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-apple-darwin8 | FileCheck %s -check-prefix=DARWIN-X86_64 + +define i32 @test() nounwind { +entry: + call void @test2() + ret i32 0 + +; LINUX-I386: subl $12, %esp +; DARWIN-I386: subl $12, %esp +; NETBSD-I386-NOT: subl {{.*}}, %esp + +; LINUX-X86_64: pushq %{{.*}} +; LINUX-X86_64-NOT: subq {{.*}}, %rsp +; DARWIN-X86_64: pushq %{{.*}} +; DARWIN-X86_64-NOT: subq {{.*}}, %rsp +; NETBSD-X86_64: pushq %{{.*}} +; NETBSD-X86_64-NOT: subq {{.*}}, %rsp +} + +declare void @test2() diff --git a/test/CodeGen/X86/store-empty-member.ll b/test/CodeGen/X86/store-empty-member.ll index 37f86c6..aea85b9 100644 --- a/test/CodeGen/X86/store-empty-member.ll +++ b/test/CodeGen/X86/store-empty-member.ll @@ -9,6 +9,6 @@ define void @foo() nounwind { %1 = alloca %testType - volatile store %testType {i32 1, [0 x i32] zeroinitializer, i32 2}, %testType* %1 + store volatile %testType {i32 1, [0 x i32] zeroinitializer, i32 2}, %testType* %1 ret void } diff --git a/test/CodeGen/X86/store_op_load_fold2.ll b/test/CodeGen/X86/store_op_load_fold2.ll index 1168622..8313166 100644 --- a/test/CodeGen/X86/store_op_load_fold2.ll +++ b/test/CodeGen/X86/store_op_load_fold2.ll @@ -1,4 +1,5 @@ -; RUN: llc < %s -mtriple=i686-linux -x86-asm-syntax=intel | FileCheck %s +; RUN: llc < %s -mtriple=i686-linux -x86-asm-syntax=att | FileCheck %s -check-prefix=ATT +; RUN: llc < %s -mtriple=i686-linux -x86-asm-syntax=intel | FileCheck %s -check-prefix=INTEL target datalayout = "e-p:32:32" %struct.Macroblock = type { i32, i32, i32, i32, i32, [8 x i32], %struct.Macroblock*, %struct.Macroblock*, i32, [2 x [4 x [4 x [2 x i32]]]], [16 x i8], [16 x i8], i32, i64, [4 x i32], [4 x i32], i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, double, i32, i32, i32, i32, i32, i32, i32, i32, i32 } @@ -16,9 +17,14 @@ cond_true2732.preheader: ; preds = %entry store i64 %tmp2676.us.us, i64* %tmp2666 ret i32 0 -; CHECK: and {{E..}}, DWORD PTR [360] -; CHECK: and DWORD PTR [356], {{E..}} -; CHECK: mov DWORD PTR [360], {{E..}} +; INTEL: and {{E..}}, DWORD PTR [360] +; INTEL: and DWORD PTR [356], {{E..}} +; FIXME: mov DWORD PTR [360], {{E..}} +; The above line comes out as 'mov 360, EAX', but when the register is ECX it works? + +; ATT: andl 360, %{{e..}} +; ATT: andl %{{e..}}, 356 +; ATT: movl %{{e..}}, 360 } diff --git a/test/CodeGen/X86/stride-reuse.ll b/test/CodeGen/X86/stride-reuse.ll index 1251a24..81de22c 100644 --- a/test/CodeGen/X86/stride-reuse.ll +++ b/test/CodeGen/X86/stride-reuse.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -march=x86 | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mcpu=generic -march=x86 | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s ; CHECK-NOT: lea @B = external global [1000 x float], align 32 diff --git a/test/CodeGen/X86/sub-with-overflow.ll b/test/CodeGen/X86/sub-with-overflow.ll index 4522e91..749b5db 100644 --- a/test/CodeGen/X86/sub-with-overflow.ll +++ b/test/CodeGen/X86/sub-with-overflow.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -mtriple=i686-linux | FileCheck %s @ok = internal constant [4 x i8] c"%d\0A\00" @no = internal constant [4 x i8] c"no\0A\00" diff --git a/test/CodeGen/X86/tail-dup-addr.ll b/test/CodeGen/X86/tail-dup-addr.ll index c5a105c..c68a8c6 100644 --- a/test/CodeGen/X86/tail-dup-addr.ll +++ b/test/CodeGen/X86/tail-dup-addr.ll @@ -2,8 +2,8 @@ ; Test that we don't drop a block that has its address taken. +; CHECK: Ltmp0: ## Block address taken ; CHECK: Ltmp1: ## Block address taken -; CHECK: Ltmp2: ## Block address taken @a = common global i32 0, align 4 @p = common global i8* null, align 8 diff --git a/test/CodeGen/X86/tail-opts.ll b/test/CodeGen/X86/tail-opts.ll index d6c16ca..f1b9f20 100644 --- a/test/CodeGen/X86/tail-opts.ll +++ b/test/CodeGen/X86/tail-opts.ll @@ -314,7 +314,7 @@ bby: ] bb7: - volatile store i32 0, i32* @XYZ + store volatile i32 0, i32* @XYZ unreachable bbx: @@ -323,7 +323,7 @@ bbx: ] bb12: - volatile store i32 0, i32* @XYZ + store volatile i32 0, i32* @XYZ unreachable return: @@ -352,8 +352,8 @@ bby: ] bb7: - volatile store i32 0, i32* @XYZ - volatile store i32 1, i32* @XYZ + store volatile i32 0, i32* @XYZ + store volatile i32 1, i32* @XYZ unreachable bbx: @@ -362,8 +362,8 @@ bbx: ] bb12: - volatile store i32 0, i32* @XYZ - volatile store i32 1, i32* @XYZ + store volatile i32 0, i32* @XYZ + store volatile i32 1, i32* @XYZ unreachable return: @@ -390,8 +390,8 @@ bby: ] bb7: - volatile store i32 0, i32* @XYZ - volatile store i32 1, i32* @XYZ + store volatile i32 0, i32* @XYZ + store volatile i32 1, i32* @XYZ unreachable bbx: @@ -400,8 +400,8 @@ bbx: ] bb12: - volatile store i32 0, i32* @XYZ - volatile store i32 1, i32* @XYZ + store volatile i32 0, i32* @XYZ + store volatile i32 1, i32* @XYZ unreachable return: diff --git a/test/CodeGen/X86/tailcall-disable.ll b/test/CodeGen/X86/tailcall-disable.ll new file mode 100644 index 0000000..b628f5e --- /dev/null +++ b/test/CodeGen/X86/tailcall-disable.ll @@ -0,0 +1,40 @@ +; RUN: llc -disable-tail-calls < %s | FileCheck --check-prefix=CALL %s +; RUN: llc < %s | FileCheck --check-prefix=JMP %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @helper() nounwind { +entry: + ret i32 7 +} + +define i32 @test1() nounwind { +entry: + %call = tail call i32 @helper() + ret i32 %call +} + +; CALL: test1: +; CALL-NOT: ret +; CALL: callq helper +; CALL: ret + +; JMP: test1: +; JMP-NOT: ret +; JMP: jmp helper # TAILCALL + +define i32 @test2() nounwind { +entry: + %call = tail call i32 @test2() + ret i32 %call +} + +; CALL: test2: +; CALL-NOT: ret +; CALL: callq test2 +; CALL: ret + +; JMP: test2: +; JMP-NOT: ret +; JMP: jmp test2 # TAILCALL diff --git a/test/CodeGen/X86/tailcallbyval64.ll b/test/CodeGen/X86/tailcallbyval64.ll index 7ecf379..7621602 100644 --- a/test/CodeGen/X86/tailcallbyval64.ll +++ b/test/CodeGen/X86/tailcallbyval64.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-linux -tailcallopt | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -tailcallopt | FileCheck %s ; FIXME: Win64 does not support byval. diff --git a/test/CodeGen/X86/tailcallstack64.ll b/test/CodeGen/X86/tailcallstack64.ll index c18c7aa..bff5f99 100644 --- a/test/CodeGen/X86/tailcallstack64.ll +++ b/test/CodeGen/X86/tailcallstack64.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -tailcallopt -mtriple=x86_64-linux -post-RA-scheduler=true | FileCheck %s -; RUN: llc < %s -tailcallopt -mtriple=x86_64-win32 -post-RA-scheduler=true | FileCheck %s +; RUN: llc < %s -tailcallopt -mcpu=generic -mtriple=x86_64-linux -post-RA-scheduler=true | FileCheck %s +; RUN: llc < %s -tailcallopt -mcpu=generic -mtriple=x86_64-win32 -post-RA-scheduler=true | FileCheck %s ; FIXME: Redundant unused stack allocation could be eliminated. ; CHECK: subq ${{24|72|80}}, %rsp diff --git a/test/CodeGen/X86/thiscall-struct-return.ll b/test/CodeGen/X86/thiscall-struct-return.ll new file mode 100644 index 0000000..a7be483 --- /dev/null +++ b/test/CodeGen/X86/thiscall-struct-return.ll @@ -0,0 +1,47 @@ +; RUN: llc < %s -mtriple=i386-PC-Win32 | FileCheck %s + +%class.C = type { i8 } +%struct.S = type { i32 } +%struct.M = type { i32, i32 } + +declare void @_ZN1CC1Ev(%class.C* %this) unnamed_addr nounwind align 2 +declare x86_thiscallcc void @_ZNK1C5SmallEv(%struct.S* noalias sret %agg.result, %class.C* %this) nounwind align 2 +declare x86_thiscallcc void @_ZNK1C6MediumEv(%struct.M* noalias sret %agg.result, %class.C* %this) nounwind align 2 + +define void @testv() nounwind { +; CHECK: testv: +; CHECK: leal +; CHECK-NEXT: movl %esi, (%esp) +; CHECK-NEXT: calll _ZN1CC1Ev +; CHECK: leal 8(%esp), %eax +; CHECK-NEXT: movl %esi, %ecx +; CHECK-NEXT: calll _ZNK1C5SmallEv +entry: + %c = alloca %class.C, align 1 + %tmp = alloca %struct.S, align 4 + call void @_ZN1CC1Ev(%class.C* %c) + ; This call should put the return structure as a pointer + ; into EAX instead of returning directly in EAX. The this + ; pointer should go into ECX + call x86_thiscallcc void @_ZNK1C5SmallEv(%struct.S* sret %tmp, %class.C* %c) + ret void +} + +define void @test2v() nounwind { +; CHECK: test2v: +; CHECK: leal +; CHECK-NEXT: movl %esi, (%esp) +; CHECK-NEXT: calll _ZN1CC1Ev +; CHECK: leal 8(%esp), %eax +; CHECK-NEXT: movl %esi, %ecx +; CHECK-NEXT: calll _ZNK1C6MediumEv +entry: + %c = alloca %class.C, align 1 + %tmp = alloca %struct.M, align 4 + call void @_ZN1CC1Ev(%class.C* %c) + ; This call should put the return structure as a pointer + ; into EAX instead of returning directly in EAX/EDX. The this + ; pointer should go into ECX + call x86_thiscallcc void @_ZNK1C6MediumEv(%struct.M* sret %tmp, %class.C* %c) + ret void +} diff --git a/test/CodeGen/X86/tls-pie.ll b/test/CodeGen/X86/tls-pie.ll new file mode 100644 index 0000000..e2e58a54 --- /dev/null +++ b/test/CodeGen/X86/tls-pie.ll @@ -0,0 +1,63 @@ +; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu -relocation-model=pic -enable-pie \ +; RUN: | FileCheck -check-prefix=X32 %s +; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu -relocation-model=pic -enable-pie \ +; RUN: | FileCheck -check-prefix=X64 %s + +@i = thread_local global i32 15 +@i2 = external thread_local global i32 + +define i32 @f1() { +; X32: f1: +; X32: movl %gs:i@NTPOFF, %eax +; X32-NEXT: ret +; X64: f1: +; X64: movl %fs:i@TPOFF, %eax +; X64-NEXT: ret + +entry: + %tmp1 = load i32* @i + ret i32 %tmp1 +} + +define i32* @f2() { +; X32: f2: +; X32: movl %gs:0, %eax +; X32-NEXT: leal i@NTPOFF(%eax), %eax +; X32-NEXT: ret +; X64: f2: +; X64: movq %fs:0, %rax +; X64-NEXT: leaq i@TPOFF(%rax), %rax +; X64-NEXT: ret + +entry: + ret i32* @i +} + +define i32 @f3() { +; X32: f3: +; X32: movl i2@INDNTPOFF, %eax +; X32-NEXT: movl %gs:(%eax), %eax +; X32-NEXT: ret +; X64: f3: +; X64: movq i2@GOTTPOFF(%rip), %rax +; X64-NEXT: movl %fs:(%rax), %eax +; X64-NEXT: ret + +entry: + %tmp1 = load i32* @i2 + ret i32 %tmp1 +} + +define i32* @f4() { +; X32: f4: +; X32: movl %gs:0, %eax +; X32-NEXT: addl i2@INDNTPOFF, %eax +; X32-NEXT: ret +; X64: f4: +; X64: movq %fs:0, %rax +; X64-NEXT: addq i2@GOTTPOFF(%rip), %rax +; X64-NEXT: ret + +entry: + ret i32* @i2 +} diff --git a/test/CodeGen/X86/tls.ll b/test/CodeGen/X86/tls.ll new file mode 100644 index 0000000..e8a79bf --- /dev/null +++ b/test/CodeGen/X86/tls.ll @@ -0,0 +1,329 @@ +; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu | FileCheck -check-prefix=X32_LINUX %s +; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64_LINUX %s +; RUN: llc < %s -march=x86 -mtriple=x86-pc-win32 | FileCheck -check-prefix=X32_WIN %s +; RUN: llc < %s -march=x86-64 -mtriple=x86_64-pc-win32 | FileCheck -check-prefix=X64_WIN %s + +@i1 = thread_local global i32 15 +@i2 = external thread_local global i32 +@i3 = internal thread_local global i32 15 +@i4 = hidden thread_local global i32 15 +@i5 = external hidden thread_local global i32 +@s1 = thread_local global i16 15 +@b1 = thread_local global i8 0 + +define i32 @f1() { +; X32_LINUX: f1: +; X32_LINUX: movl %gs:i1@NTPOFF, %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f1: +; X64_LINUX: movl %fs:i1@TPOFF, %eax +; X64_LINUX-NEXT: ret +; X32_WIN: f1: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: movl _i1@SECREL(%eax), %eax +; X32_WIN-NEXT: ret +; X64_WIN: f1: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: movl i1@SECREL(%rax), %eax +; X64_WIN-NEXT: ret + +entry: + %tmp1 = load i32* @i1 + ret i32 %tmp1 +} + +define i32* @f2() { +; X32_LINUX: f2: +; X32_LINUX: movl %gs:0, %eax +; X32_LINUX-NEXT: leal i1@NTPOFF(%eax), %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f2: +; X64_LINUX: movq %fs:0, %rax +; X64_LINUX-NEXT: leaq i1@TPOFF(%rax), %rax +; X64_LINUX-NEXT: ret +; X32_WIN: f2: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: leal _i1@SECREL(%eax), %eax +; X32_WIN-NEXT: ret +; X64_WIN: f2: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: leaq i1@SECREL(%rax), %rax +; X64_WIN-NEXT: ret + +entry: + ret i32* @i1 +} + +define i32 @f3() nounwind { +; X32_LINUX: f3: +; X32_LINUX: movl i2@INDNTPOFF, %eax +; X32_LINUX-NEXT: movl %gs:(%eax), %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f3: +; X64_LINUX: movq i2@GOTTPOFF(%rip), %rax +; X64_LINUX-NEXT: movl %fs:(%rax), %eax +; X64_LINUX-NEXT: ret +; X32_WIN: f3: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: movl _i2@SECREL(%eax), %eax +; X32_WIN-NEXT: ret +; X64_WIN: f3: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: movl i2@SECREL(%rax), %eax +; X64_WIN-NEXT: ret + +entry: + %tmp1 = load i32* @i2 + ret i32 %tmp1 +} + +define i32* @f4() { +; X32_LINUX: f4: +; X32_LINUX: movl %gs:0, %eax +; X32_LINUX-NEXT: addl i2@INDNTPOFF, %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f4: +; X64_LINUX: movq %fs:0, %rax +; X64_LINUX-NEXT: addq i2@GOTTPOFF(%rip), %rax +; X64_LINUX-NEXT: ret +; X32_WIN: f4: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: leal _i2@SECREL(%eax), %eax +; X32_WIN-NEXT: ret +; X64_WIN: f4: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: leaq i2@SECREL(%rax), %rax +; X64_WIN-NEXT: ret + +entry: + ret i32* @i2 +} + +define i32 @f5() nounwind { +; X32_LINUX: f5: +; X32_LINUX: movl %gs:i3@NTPOFF, %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f5: +; X64_LINUX: movl %fs:i3@TPOFF, %eax +; X64_LINUX-NEXT: ret +; X32_WIN: f5: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: movl _i3@SECREL(%eax), %eax +; X32_WIN-NEXT: ret +; X64_WIN: f5: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: movl i3@SECREL(%rax), %eax +; X64_WIN-NEXT: ret + +entry: + %tmp1 = load i32* @i3 + ret i32 %tmp1 +} + +define i32* @f6() { +; X32_LINUX: f6: +; X32_LINUX: movl %gs:0, %eax +; X32_LINUX-NEXT: leal i3@NTPOFF(%eax), %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f6: +; X64_LINUX: movq %fs:0, %rax +; X64_LINUX-NEXT: leaq i3@TPOFF(%rax), %rax +; X64_LINUX-NEXT: ret +; X32_WIN: f6: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: leal _i3@SECREL(%eax), %eax +; X32_WIN-NEXT: ret +; X64_WIN: f6: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: leaq i3@SECREL(%rax), %rax +; X64_WIN-NEXT: ret + +entry: + ret i32* @i3 +} + +define i32 @f7() { +; X32_LINUX: f7: +; X32_LINUX: movl %gs:i4@NTPOFF, %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f7: +; X64_LINUX: movl %fs:i4@TPOFF, %eax +; X64_LINUX-NEXT: ret + +entry: + %tmp1 = load i32* @i4 + ret i32 %tmp1 +} + +define i32* @f8() { +; X32_LINUX: f8: +; X32_LINUX: movl %gs:0, %eax +; X32_LINUX-NEXT: leal i4@NTPOFF(%eax), %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f8: +; X64_LINUX: movq %fs:0, %rax +; X64_LINUX-NEXT: leaq i4@TPOFF(%rax), %rax +; X64_LINUX-NEXT: ret + +entry: + ret i32* @i4 +} + +define i32 @f9() { +; X32_LINUX: f9: +; X32_LINUX: movl %gs:i5@NTPOFF, %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f9: +; X64_LINUX: movl %fs:i5@TPOFF, %eax +; X64_LINUX-NEXT: ret + +entry: + %tmp1 = load i32* @i5 + ret i32 %tmp1 +} + +define i32* @f10() { +; X32_LINUX: f10: +; X32_LINUX: movl %gs:0, %eax +; X32_LINUX-NEXT: leal i5@NTPOFF(%eax), %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f10: +; X64_LINUX: movq %fs:0, %rax +; X64_LINUX-NEXT: leaq i5@TPOFF(%rax), %rax +; X64_LINUX-NEXT: ret + +entry: + ret i32* @i5 +} + +define i16 @f11() { +; X32_LINUX: f11: +; X32_LINUX: movzwl %gs:s1@NTPOFF, %eax +; Why is this kill line here, but no where else? +; X32_LINUX-NEXT: # kill +; X32_LINUX-NEXT: ret +; X64_LINUX: f11: +; X64_LINUX: movzwl %fs:s1@TPOFF, %eax +; X64_LINUX-NEXT: # kill +; X64_LINUX-NEXT: ret +; X32_WIN: f11: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: movzwl _s1@SECREL(%eax), %eax +; X32_WIN-NEXT: # kill +; X32_WIN-NEXT: ret +; X64_WIN: f11: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: movzwl s1@SECREL(%rax), %eax +; X64_WIN-NEXT: # kill +; X64_WIN-NEXT: ret + +entry: + %tmp1 = load i16* @s1 + ret i16 %tmp1 +} + +define i32 @f12() { +; X32_LINUX: f12: +; X32_LINUX: movswl %gs:s1@NTPOFF, %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f12: +; X64_LINUX: movswl %fs:s1@TPOFF, %eax +; X64_LINUX-NEXT: ret +; X32_WIN: f12: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: movswl _s1@SECREL(%eax), %eax +; X32_WIN-NEXT: ret +; X64_WIN: f12: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: movswl s1@SECREL(%rax), %eax +; X64_WIN-NEXT: ret + +entry: + %tmp1 = load i16* @s1 + %tmp2 = sext i16 %tmp1 to i32 + ret i32 %tmp2 +} + +define i8 @f13() { +; X32_LINUX: f13: +; X32_LINUX: movb %gs:b1@NTPOFF, %al +; X32_LINUX-NEXT: ret +; X64_LINUX: f13: +; X64_LINUX: movb %fs:b1@TPOFF, %al +; X64_LINUX-NEXT: ret +; X32_WIN: f13: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: movb _b1@SECREL(%eax), %al +; X32_WIN-NEXT: ret +; X64_WIN: f13: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: movb b1@SECREL(%rax), %al +; X64_WIN-NEXT: ret + +entry: + %tmp1 = load i8* @b1 + ret i8 %tmp1 +} + +define i32 @f14() { +; X32_LINUX: f14: +; X32_LINUX: movsbl %gs:b1@NTPOFF, %eax +; X32_LINUX-NEXT: ret +; X64_LINUX: f14: +; X64_LINUX: movsbl %fs:b1@TPOFF, %eax +; X64_LINUX-NEXT: ret +; X32_WIN: f14: +; X32_WIN: movl __tls_index, %eax +; X32_WIN-NEXT: movl %fs:__tls_array, %ecx +; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax +; X32_WIN-NEXT: movsbl _b1@SECREL(%eax), %eax +; X32_WIN-NEXT: ret +; X64_WIN: f14: +; X64_WIN: movl _tls_index(%rip), %eax +; X64_WIN-NEXT: movq %gs:88, %rcx +; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax +; X64_WIN-NEXT: movsbl b1@SECREL(%rax), %eax +; X64_WIN-NEXT: ret + +entry: + %tmp1 = load i8* @b1 + %tmp2 = sext i8 %tmp1 to i32 + ret i32 %tmp2 +} + diff --git a/test/CodeGen/X86/tls1.ll b/test/CodeGen/X86/tls1.ll deleted file mode 100644 index 0cae5c4..0000000 --- a/test/CodeGen/X86/tls1.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:i@NTPOFF, %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movl %fs:i@TPOFF, %eax} %t2 - -@i = thread_local global i32 15 - -define i32 @f() nounwind { -entry: - %tmp1 = load i32* @i - ret i32 %tmp1 -} diff --git a/test/CodeGen/X86/tls10.ll b/test/CodeGen/X86/tls10.ll deleted file mode 100644 index fb61596..0000000 --- a/test/CodeGen/X86/tls10.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:0, %eax} %t -; RUN: grep {leal i@NTPOFF(%eax), %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movq %fs:0, %rax} %t2 -; RUN: grep {leaq i@TPOFF(%rax), %rax} %t2 - -@i = external hidden thread_local global i32 - -define i32* @f() { -entry: - ret i32* @i -} diff --git a/test/CodeGen/X86/tls11.ll b/test/CodeGen/X86/tls11.ll deleted file mode 100644 index 514a168..0000000 --- a/test/CodeGen/X86/tls11.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movzwl %gs:i@NTPOFF, %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movzwl %fs:i@TPOFF, %eax} %t2 - -@i = thread_local global i16 15 - -define i16 @f() { -entry: - %tmp1 = load i16* @i - ret i16 %tmp1 -} diff --git a/test/CodeGen/X86/tls12.ll b/test/CodeGen/X86/tls12.ll deleted file mode 100644 index c29f6ad..0000000 --- a/test/CodeGen/X86/tls12.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movb %gs:i@NTPOFF, %al} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movb %fs:i@TPOFF, %al} %t2 - -@i = thread_local global i8 15 - -define i8 @f() { -entry: - %tmp1 = load i8* @i - ret i8 %tmp1 -} diff --git a/test/CodeGen/X86/tls13.ll b/test/CodeGen/X86/tls13.ll deleted file mode 100644 index 08778ec..0000000 --- a/test/CodeGen/X86/tls13.ll +++ /dev/null @@ -1,24 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movswl %gs:i@NTPOFF, %eax} %t -; RUN: grep {movzwl %gs:j@NTPOFF, %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movswl %fs:i@TPOFF, %edi} %t2 -; RUN: grep {movzwl %fs:j@TPOFF, %edi} %t2 - -@i = thread_local global i16 0 -@j = thread_local global i16 0 - -define void @f() nounwind optsize { -entry: - %0 = load i16* @i, align 2 - %1 = sext i16 %0 to i32 - tail call void @g(i32 %1) nounwind - %2 = load i16* @j, align 2 - %3 = zext i16 %2 to i32 - tail call void @h(i32 %3) nounwind - ret void -} - -declare void @g(i32) - -declare void @h(i32) diff --git a/test/CodeGen/X86/tls14.ll b/test/CodeGen/X86/tls14.ll deleted file mode 100644 index 88426dd..0000000 --- a/test/CodeGen/X86/tls14.ll +++ /dev/null @@ -1,24 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movsbl %gs:i@NTPOFF, %eax} %t -; RUN: grep {movzbl %gs:j@NTPOFF, %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movsbl %fs:i@TPOFF, %edi} %t2 -; RUN: grep {movzbl %fs:j@TPOFF, %edi} %t2 - -@i = thread_local global i8 0 -@j = thread_local global i8 0 - -define void @f() nounwind optsize { -entry: - %0 = load i8* @i, align 2 - %1 = sext i8 %0 to i32 - tail call void @g(i32 %1) nounwind - %2 = load i8* @j, align 2 - %3 = zext i8 %2 to i32 - tail call void @h(i32 %3) nounwind - ret void -} - -declare void @g(i32) - -declare void @h(i32) diff --git a/test/CodeGen/X86/tls15.ll b/test/CodeGen/X86/tls15.ll deleted file mode 100644 index 7abf070..0000000 --- a/test/CodeGen/X86/tls15.ll +++ /dev/null @@ -1,18 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:0, %eax} %t | count 1 -; RUN: grep {leal i@NTPOFF(%eax), %ecx} %t -; RUN: grep {leal j@NTPOFF(%eax), %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movq %fs:0, %rax} %t2 | count 1 -; RUN: grep {leaq i@TPOFF(%rax), %rcx} %t2 -; RUN: grep {leaq j@TPOFF(%rax), %rax} %t2 - -@i = thread_local global i32 0 -@j = thread_local global i32 0 - -define void @f(i32** %a, i32** %b) { -entry: - store i32* @i, i32** %a, align 8 - store i32* @j, i32** %b, align 8 - ret void -} diff --git a/test/CodeGen/X86/tls2.ll b/test/CodeGen/X86/tls2.ll deleted file mode 100644 index 5a94296..0000000 --- a/test/CodeGen/X86/tls2.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:0, %eax} %t -; RUN: grep {leal i@NTPOFF(%eax), %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movq %fs:0, %rax} %t2 -; RUN: grep {leaq i@TPOFF(%rax), %rax} %t2 - -@i = thread_local global i32 15 - -define i32* @f() { -entry: - ret i32* @i -} diff --git a/test/CodeGen/X86/tls3.ll b/test/CodeGen/X86/tls3.ll deleted file mode 100644 index 7327cc4..0000000 --- a/test/CodeGen/X86/tls3.ll +++ /dev/null @@ -1,14 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl i@INDNTPOFF, %eax} %t -; RUN: grep {movl %gs:(%eax), %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movq i@GOTTPOFF(%rip), %rax} %t2 -; RUN: grep {movl %fs:(%rax), %eax} %t2 - -@i = external thread_local global i32 ; <i32*> [#uses=2] - -define i32 @f() nounwind { -entry: - %tmp1 = load i32* @i ; <i32> [#uses=1] - ret i32 %tmp1 -} diff --git a/test/CodeGen/X86/tls4.ll b/test/CodeGen/X86/tls4.ll deleted file mode 100644 index d2e40e3..0000000 --- a/test/CodeGen/X86/tls4.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:0, %eax} %t -; RUN: grep {addl i@INDNTPOFF, %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movq %fs:0, %rax} %t2 -; RUN: grep {addq i@GOTTPOFF(%rip), %rax} %t2 - -@i = external thread_local global i32 ; <i32*> [#uses=2] - -define i32* @f() { -entry: - ret i32* @i -} diff --git a/test/CodeGen/X86/tls5.ll b/test/CodeGen/X86/tls5.ll deleted file mode 100644 index 4d2cc02..0000000 --- a/test/CodeGen/X86/tls5.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:i@NTPOFF, %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movl %fs:i@TPOFF, %eax} %t2 - -@i = internal thread_local global i32 15 - -define i32 @f() { -entry: - %tmp1 = load i32* @i - ret i32 %tmp1 -} diff --git a/test/CodeGen/X86/tls6.ll b/test/CodeGen/X86/tls6.ll deleted file mode 100644 index 505106e..0000000 --- a/test/CodeGen/X86/tls6.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:0, %eax} %t -; RUN: grep {leal i@NTPOFF(%eax), %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movq %fs:0, %rax} %t2 -; RUN: grep {leaq i@TPOFF(%rax), %rax} %t2 - -@i = internal thread_local global i32 15 - -define i32* @f() { -entry: - ret i32* @i -} diff --git a/test/CodeGen/X86/tls7.ll b/test/CodeGen/X86/tls7.ll deleted file mode 100644 index e9116e7..0000000 --- a/test/CodeGen/X86/tls7.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:i@NTPOFF, %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movl %fs:i@TPOFF, %eax} %t2 - -@i = hidden thread_local global i32 15 - -define i32 @f() { -entry: - %tmp1 = load i32* @i - ret i32 %tmp1 -} diff --git a/test/CodeGen/X86/tls8.ll b/test/CodeGen/X86/tls8.ll deleted file mode 100644 index 375af94..0000000 --- a/test/CodeGen/X86/tls8.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:0, %eax} %t -; RUN: grep {leal i@NTPOFF(%eax), %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movq %fs:0, %rax} %t2 -; RUN: grep {leaq i@TPOFF(%rax), %rax} %t2 - -@i = hidden thread_local global i32 15 - -define i32* @f() { -entry: - ret i32* @i -} diff --git a/test/CodeGen/X86/tls9.ll b/test/CodeGen/X86/tls9.ll deleted file mode 100644 index 7d08df8..0000000 --- a/test/CodeGen/X86/tls9.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu > %t -; RUN: grep {movl %gs:i@NTPOFF, %eax} %t -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu > %t2 -; RUN: grep {movl %fs:i@TPOFF, %eax} %t2 - -@i = external hidden thread_local global i32 - -define i32 @f() nounwind { -entry: - %tmp1 = load i32* @i - ret i32 %tmp1 -} diff --git a/test/CodeGen/X86/twoaddr-lea.ll b/test/CodeGen/X86/twoaddr-lea.ll index a1d797f..9d58019 100644 --- a/test/CodeGen/X86/twoaddr-lea.ll +++ b/test/CodeGen/X86/twoaddr-lea.ll @@ -5,7 +5,7 @@ ;; allocator turns the shift into an LEA. This also occurs for ADD. ; Check that the shift gets turned into an LEA. -; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-apple-darwin | FileCheck %s @G = external global i32 @@ -14,7 +14,7 @@ define i32 @test1(i32 %X) nounwind { ; CHECK-NOT: mov ; CHECK: leal 1(%rdi) %Z = add i32 %X, 1 - volatile store i32 %Z, i32* @G + store volatile i32 %Z, i32* @G ret i32 %X } diff --git a/test/CodeGen/X86/uint64-to-float.ll b/test/CodeGen/X86/uint64-to-float.ll index 1dbbdcf..e853e77 100644 --- a/test/CodeGen/X86/uint64-to-float.ll +++ b/test/CodeGen/X86/uint64-to-float.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s +; RUN: llc < %s -mcpu=generic -march=x86-64 | FileCheck %s ; Verify that we are using the efficient uitofp --> sitofp lowering illustrated ; by the compiler_rt implementation of __floatundisf. ; <rdar://problem/8493982> @@ -6,37 +6,12 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.0.0" -; FIXME: This test could generate this code: -; -; ## BB#0: ## %entry -; testq %rdi, %rdi -; jns LBB0_2 -; ## BB#1: -; movq %rdi, %rax -; shrq %rax -; andq $1, %rdi -; orq %rax, %rdi -; cvtsi2ssq %rdi, %xmm0 -; addss %xmm0, %xmm0 -; ret -; LBB0_2: ## %entry -; cvtsi2ssq %rdi, %xmm0 -; ret -; -; The blocks come from lowering: -; -; %vreg7<def> = CMOV_FR32 %vreg6<kill>, %vreg5<kill>, 15, %EFLAGS<imp-use>; FR32:%vreg7,%vreg6,%vreg5 -; -; If the instruction had an EFLAGS<kill> flag, it wouldn't need to mark EFLAGS -; as live-in on the new blocks, and machine sinking would be able to sink -; everything below the test. - -; CHECK: shrq -; CHECK: andq -; CHECK-NEXT: orq ; CHECK: testq %rdi, %rdi ; CHECK-NEXT: jns LBB0_2 -; CHECK: cvtsi2ss +; CHECK: shrq +; CHECK-NEXT: andq +; CHECK-NEXT: orq +; CHECK-NEXT: cvtsi2ss ; CHECK: LBB0_2 ; CHECK-NEXT: cvtsi2ss define float @test(i64 %a) { diff --git a/test/CodeGen/X86/unreachable-stack-protector.ll b/test/CodeGen/X86/unreachable-stack-protector.ll index eeebcee..b066297 100644 --- a/test/CodeGen/X86/unreachable-stack-protector.ll +++ b/test/CodeGen/X86/unreachable-stack-protector.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s | FileCheck %s +; RUN: llc < %s -disable-cgp-delete-dead-blocks | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.0.0" diff --git a/test/CodeGen/X86/utf16-cfstrings.ll b/test/CodeGen/X86/utf16-cfstrings.ll new file mode 100644 index 0000000..af76a33 --- /dev/null +++ b/test/CodeGen/X86/utf16-cfstrings.ll @@ -0,0 +1,35 @@ +; RUN: llc < %s -mtriple x86_64-apple-macosx10 | FileCheck %s +; <rdar://problem/10655949> + +%0 = type opaque +%struct.NSConstantString = type { i32*, i32, i8*, i64 } + +@__CFConstantStringClassReference = external global [0 x i32] +@.str = internal unnamed_addr constant [5 x i16] [i16 252, i16 98, i16 101, i16 114, i16 0], align 2 +@_unnamed_cfstring_ = private constant %struct.NSConstantString { i32* getelementptr inbounds ([0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast ([5 x i16]* @.str to i8*), i64 4 }, section "__DATA,__cfstring" + +; CHECK: .section __TEXT,__ustring +; CHECK-NEXT: .align 1 +; CHECK-NEXT: _.str: +; CHECK-NEXT: .short 252 ## 0xfc +; CHECK-NEXT: .short 98 ## 0x62 +; CHECK-NEXT: .short 101 ## 0x65 +; CHECK-NEXT: .short 114 ## 0x72 +; CHECK-NEXT: .short 0 ## 0x0 + +define i32 @main() uwtable ssp { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval + call void (%0*, ...)* @NSLog(%0* bitcast (%struct.NSConstantString* @_unnamed_cfstring_ to %0*)) + ret i32 0 +} + +declare void @NSLog(%0*, ...) + +!llvm.module.flags = !{!0, !1, !2, !3} + +!0 = metadata !{i32 1, metadata !"Objective-C Version", i32 2} +!1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0} +!2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"} +!3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0} diff --git a/test/CodeGen/X86/utf8.ll b/test/CodeGen/X86/utf8.ll new file mode 100644 index 0000000..67bc5ae2 --- /dev/null +++ b/test/CodeGen/X86/utf8.ll @@ -0,0 +1,4 @@ +; RUN: llc < %s -march=x86 | FileCheck %s + +; CHECK: iΔ +@"i\CE\94" = common global i32 0, align 4 diff --git a/test/CodeGen/X86/v-binop-widen.ll b/test/CodeGen/X86/v-binop-widen.ll index 3bee700..8655c6c 100644 --- a/test/CodeGen/X86/v-binop-widen.ll +++ b/test/CodeGen/X86/v-binop-widen.ll @@ -1,4 +1,4 @@ -; RUN: llc -march=x86 -mattr=+sse < %s | FileCheck %s +; RUN: llc -mcpu=generic -march=x86 -mattr=+sse < %s | FileCheck %s ; CHECK: divss ; CHECK: divps ; CHECK: divps diff --git a/test/CodeGen/X86/vec_call.ll b/test/CodeGen/X86/vec_call.ll index b3efc7b..f2fc7e7 100644 --- a/test/CodeGen/X86/vec_call.ll +++ b/test/CodeGen/X86/vec_call.ll @@ -1,6 +1,6 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 -mtriple=i686-apple-darwin8 | \ +; RUN: llc < %s -mcpu=generic -march=x86 -mattr=+sse2 -mtriple=i686-apple-darwin8 | \ ; RUN: grep {subl.*60} -; RUN: llc < %s -march=x86 -mattr=+sse2 -mtriple=i686-apple-darwin8 | \ +; RUN: llc < %s -mcpu=generic -march=x86 -mattr=+sse2 -mtriple=i686-apple-darwin8 | \ ; RUN: grep {movaps.*32} diff --git a/test/CodeGen/X86/vec_compare-2.ll b/test/CodeGen/X86/vec_compare-2.ll index 04bb725..91777f7 100644 --- a/test/CodeGen/X86/vec_compare-2.ll +++ b/test/CodeGen/X86/vec_compare-2.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mcpu=penryn | FileCheck %s +; RUN: llc < %s -mtriple=i686-linux -mcpu=penryn | FileCheck %s declare <4 x float> @llvm.x86.sse41.blendvps(<4 x float>, <4 x float>, <4 x float>) nounwind readnone @@ -8,9 +8,12 @@ declare <4 x i32> @llvm.x86.sse41.pmaxsd(<4 x i32>, <4 x i32>) nounwind readnone define void @blackDespeckle_wrapper(i8** %args_list, i64* %gtid, i64 %xend) { entry: +; CHECK: cfi_def_cfa_offset ; CHECK-NOT: set -; CHECK: pcmpgt -; CHECK: blendvps +; CHECK: movzwl +; CHECK: movzwl +; CHECK: pshufd +; CHECK: pshufb %shr.i = ashr <4 x i32> zeroinitializer, <i32 3, i32 3, i32 3, i32 3> ; <<4 x i32>> [#uses=1] %cmp318.i = sext <4 x i1> zeroinitializer to <4 x i32> ; <<4 x i32>> [#uses=1] %sub322.i = sub <4 x i32> %shr.i, zeroinitializer ; <<4 x i32>> [#uses=1] diff --git a/test/CodeGen/X86/vec_ctbits.ll b/test/CodeGen/X86/vec_ctbits.ll index f0158d6..bddd535 100644 --- a/test/CodeGen/X86/vec_ctbits.ll +++ b/test/CodeGen/X86/vec_ctbits.ll @@ -1,15 +1,15 @@ ; RUN: llc < %s -march=x86-64 -declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>) -declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>) +declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1) +declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1) declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) define <2 x i64> @footz(<2 x i64> %a) nounwind { - %c = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a) + %c = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 true) ret <2 x i64> %c } define <2 x i64> @foolz(<2 x i64> %a) nounwind { - %c = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a) + %c = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a, i1 true) ret <2 x i64> %c } define <2 x i64> @foopop(<2 x i64> %a) nounwind { diff --git a/test/CodeGen/X86/vec_extract-sse4.ll b/test/CodeGen/X86/vec_extract-sse4.ll index f487654..42d7f27 100644 --- a/test/CodeGen/X86/vec_extract-sse4.ll +++ b/test/CodeGen/X86/vec_extract-sse4.ll @@ -2,7 +2,7 @@ ; RUN: not grep extractps %t ; RUN: not grep pextrd %t ; RUN: not grep pshufd %t -; RUN: grep movss %t | count 2 +; RUN: not grep movss %t define void @t1(float* %R, <4 x float>* %P1) nounwind { %X = load <4 x float>* %P1 diff --git a/test/CodeGen/X86/vec_fpext.ll b/test/CodeGen/X86/vec_fpext.ll new file mode 100644 index 0000000..05b263e --- /dev/null +++ b/test/CodeGen/X86/vec_fpext.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -march=x86 -mattr=+sse41,-avx | FileCheck %s + +; PR11674 +define void @fpext_frommem(<2 x float>* %in, <2 x double>* %out) { +entry: +; TODO: We should be able to generate cvtps2pd for the load. +; For now, just check that we generate something sane. +; CHECK: cvtss2sd +; CHECK: cvtss2sd + %0 = load <2 x float>* %in, align 8 + %1 = fpext <2 x float> %0 to <2 x double> + store <2 x double> %1, <2 x double>* %out, align 1 + ret void +} diff --git a/test/CodeGen/X86/vec_return.ll b/test/CodeGen/X86/vec_return.ll index 676be9b..2cf5dc6 100644 --- a/test/CodeGen/X86/vec_return.ll +++ b/test/CodeGen/X86/vec_return.ll @@ -1,12 +1,16 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 > %t -; RUN: grep pxor %t | count 1 -; RUN: grep movaps %t | count 1 -; RUN: not grep shuf %t +; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s +; Without any typed operations, always use the smaller xorps. +; CHECK: test +; CHECK: xorps define <2 x double> @test() { ret <2 x double> zeroinitializer } +; Prefer a constant pool load here. +; CHECK: test2 +; CHECK-NOT: shuf +; CHECK: movaps {{.*}}CPI define <4 x i32> @test2() nounwind { ret <4 x i32> < i32 0, i32 0, i32 1, i32 0 > } diff --git a/test/CodeGen/X86/vec_shuffle-20.ll b/test/CodeGen/X86/vec_shuffle-20.ll index fc06b95..b6b8ba6 100644 --- a/test/CodeGen/X86/vec_shuffle-20.ll +++ b/test/CodeGen/X86/vec_shuffle-20.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -o /dev/null -march=x86 -mattr=+sse2 -mtriple=i686-apple-darwin9 -stats -info-output-file - | grep asm-printer | grep 3 +; RUN: llc < %s -o /dev/null -march=x86 -mcpu=corei7 -mtriple=i686-apple-darwin9 -stats -info-output-file - | grep asm-printer | grep 2 define <4 x float> @func(<4 x float> %fp0, <4 x float> %fp1) nounwind { entry: diff --git a/test/CodeGen/X86/vec_shuffle-23.ll b/test/CodeGen/X86/vec_shuffle-23.ll index 05a3a1e..2468735 100644 --- a/test/CodeGen/X86/vec_shuffle-23.ll +++ b/test/CodeGen/X86/vec_shuffle-23.ll @@ -5,7 +5,7 @@ define i32 @t() nounwind { entry: %a = alloca <4 x i32> ; <<4 x i32>*> [#uses=2] %b = alloca <4 x i32> ; <<4 x i32>*> [#uses=5] - volatile store <4 x i32> < i32 0, i32 1, i32 2, i32 3 >, <4 x i32>* %a + store volatile <4 x i32> < i32 0, i32 1, i32 2, i32 3 >, <4 x i32>* %a %tmp = load <4 x i32>* %a ; <<4 x i32>> [#uses=1] store <4 x i32> %tmp, <4 x i32>* %b %tmp1 = load <4 x i32>* %b ; <<4 x i32>> [#uses=1] diff --git a/test/CodeGen/X86/vec_shuffle-24.ll b/test/CodeGen/X86/vec_shuffle-24.ll index 1b104de..d038daf 100644 --- a/test/CodeGen/X86/vec_shuffle-24.ll +++ b/test/CodeGen/X86/vec_shuffle-24.ll @@ -5,7 +5,7 @@ entry: ; CHECK: punpckldq %a = alloca <4 x i32> ; <<4 x i32>*> [#uses=2] %b = alloca <4 x i32> ; <<4 x i32>*> [#uses=5] - volatile store <4 x i32> < i32 0, i32 1, i32 2, i32 3 >, <4 x i32>* %a + store volatile <4 x i32> < i32 0, i32 1, i32 2, i32 3 >, <4 x i32>* %a %tmp = load <4 x i32>* %a ; <<4 x i32>> [#uses=1] store <4 x i32> %tmp, <4 x i32>* %b %tmp1 = load <4 x i32>* %b ; <<4 x i32>> [#uses=1] diff --git a/test/CodeGen/X86/vec_shuffle-37.ll b/test/CodeGen/X86/vec_shuffle-37.ll index 950040a..430aa04 100644 --- a/test/CodeGen/X86/vec_shuffle-37.ll +++ b/test/CodeGen/X86/vec_shuffle-37.ll @@ -4,10 +4,10 @@ define <4 x i32> @t00(<4 x i32>* %a0) nounwind ssp { entry: -; CHECK: movaps ({{%rdi|%rcx}}), %xmm0 -; CHECK: movaps %xmm0, %xmm1 -; CHECK-NEXT: movss %xmm2, %xmm1 -; CHECK-NEXT: shufps $36, %xmm1, %xmm0 +; CHECK: movaps ({{%rdi|%rcx}}), %[[XMM0:xmm[0-9]+]] +; CHECK: movaps %[[XMM0]], %[[XMM1:xmm[0-9]+]] +; CHECK-NEXT: movss %xmm{{[0-9]+}}, %[[XMM1]] +; CHECK-NEXT: shufps $36, %[[XMM1]], %[[XMM0]] %0 = load <4 x i32>* undef, align 16 %1 = load <4 x i32>* %a0, align 16 %2 = shufflevector <4 x i32> %1, <4 x i32> %0, <4 x i32> <i32 0, i32 1, i32 2, i32 4> @@ -26,10 +26,12 @@ entry: define void @t02(<8 x i32>* %source, <2 x i32>* %dest) nounwind noinline { entry: -; CHECK: movaps 32({{%rdi|%rcx}}), %xmm0 -; CHECK-NEXT: movaps 48({{%rdi|%rcx}}), %xmm1 -; CHECK-NEXT: movss %xmm1, %xmm0 -; CHECK-NEXT: movq %xmm0, ({{%rsi|%rdx}}) +; CHECK: t02 +; CHECK: movaps +; CHECK: shufps +; CHECK: pshufd +; CHECK: movq +; CHECK: ret %0 = bitcast <8 x i32>* %source to <4 x i32>* %arrayidx = getelementptr inbounds <4 x i32>* %0, i64 3 %tmp2 = load <4 x i32>* %arrayidx, align 16 diff --git a/test/CodeGen/X86/vec_shuffle-38.ll b/test/CodeGen/X86/vec_shuffle-38.ll index 69a2ede..96ef883 100644 --- a/test/CodeGen/X86/vec_shuffle-38.ll +++ b/test/CodeGen/X86/vec_shuffle-38.ll @@ -46,10 +46,9 @@ entry: ; rdar://10119696 ; CHECK: f -define <4 x float> @f(<4 x float> %x, double* nocapture %y) nounwind uwtable readonly ssp { +define <4 x float> @f(<4 x float> %x, double* nocapture %y) nounwind readonly ssp { entry: - ; CHECK: movsd (% - ; CHECK-NEXT: movsd %xmm + ; CHECK: movlps (%{{rdi|rdx}}), %xmm0 %u110.i = load double* %y, align 1 %tmp8.i = insertelement <2 x double> undef, double %u110.i, i32 0 %tmp9.i = bitcast <2 x double> %tmp8.i to <4 x float> @@ -57,3 +56,22 @@ entry: ret <4 x float> %shuffle.i } +define <4 x float> @loadhpi2(%struct.Float2* nocapture %vHiCoefPtr_0, %struct.Float2* nocapture %vLoCoefPtr_0, i32 %s) nounwind readonly ssp { +entry: +; CHECK: loadhpi2 +; CHECK: movhps ( +; CHECK-NOT: movlhps + %0 = bitcast %struct.Float2* %vHiCoefPtr_0 to <1 x i64>* + %idx.ext = sext i32 %s to i64 + %add.ptr = getelementptr inbounds <1 x i64>* %0, i64 %idx.ext + %add.ptr.val = load <1 x i64>* %add.ptr, align 1 + %1 = bitcast <1 x i64> %add.ptr.val to <2 x float> + %shuffle.i = shufflevector <2 x float> %1, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> + %2 = bitcast %struct.Float2* %vLoCoefPtr_0 to <1 x i64>* + %add.ptr2 = getelementptr inbounds <1 x i64>* %2, i64 %idx.ext + %add.ptr2.val = load <1 x i64>* %add.ptr2, align 1 + %3 = bitcast <1 x i64> %add.ptr2.val to <2 x float> + %shuffle.i4 = shufflevector <2 x float> %3, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> + %shuffle1.i5 = shufflevector <4 x float> %shuffle.i, <4 x float> %shuffle.i4, <4 x i32> <i32 0, i32 1, i32 4, i32 5> + ret <4 x float> %shuffle1.i5 +} diff --git a/test/CodeGen/X86/vec_shuffle-39.ll b/test/CodeGen/X86/vec_shuffle-39.ll new file mode 100644 index 0000000..55531e3 --- /dev/null +++ b/test/CodeGen/X86/vec_shuffle-39.ll @@ -0,0 +1,86 @@ +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; rdar://10050222, rdar://10134392 + +define <4 x float> @t1(<4 x float> %a, <1 x i64>* nocapture %p) nounwind { +entry: +; CHECK: t1: +; CHECK: movlps (%rdi), %xmm0 +; CHECK: ret + %p.val = load <1 x i64>* %p, align 1 + %0 = bitcast <1 x i64> %p.val to <2 x float> + %shuffle.i = shufflevector <2 x float> %0, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> + %shuffle1.i = shufflevector <4 x float> %a, <4 x float> %shuffle.i, <4 x i32> <i32 4, i32 5, i32 2, i32 3> + ret <4 x float> %shuffle1.i +} + +define <4 x float> @t1a(<4 x float> %a, <1 x i64>* nocapture %p) nounwind { +entry: +; CHECK: t1a: +; CHECK: movlps (%rdi), %xmm0 +; CHECK: ret + %0 = bitcast <1 x i64>* %p to double* + %1 = load double* %0 + %2 = insertelement <2 x double> undef, double %1, i32 0 + %3 = bitcast <2 x double> %2 to <4 x float> + %4 = shufflevector <4 x float> %a, <4 x float> %3, <4 x i32> <i32 4, i32 5, i32 2, i32 3> + ret <4 x float> %4 +} + +define void @t2(<1 x i64>* nocapture %p, <4 x float> %a) nounwind { +entry: +; CHECK: t2: +; CHECK: movlps %xmm0, (%rdi) +; CHECK: ret + %cast.i = bitcast <4 x float> %a to <2 x i64> + %extract.i = extractelement <2 x i64> %cast.i, i32 0 + %0 = getelementptr inbounds <1 x i64>* %p, i64 0, i64 0 + store i64 %extract.i, i64* %0, align 8 + ret void +} + +define void @t2a(<1 x i64>* nocapture %p, <4 x float> %a) nounwind { +entry: +; CHECK: t2a: +; CHECK: movlps %xmm0, (%rdi) +; CHECK: ret + %0 = bitcast <1 x i64>* %p to double* + %1 = bitcast <4 x float> %a to <2 x double> + %2 = extractelement <2 x double> %1, i32 0 + store double %2, double* %0 + ret void +} + +; rdar://10436044 +define <2 x double> @t3() nounwind readonly { +bb: +; CHECK: t3: +; CHECK: punpcklqdq %xmm1, %xmm0 +; CHECK: movq (%rax), %xmm1 +; CHECK: movsd %xmm1, %xmm0 + %tmp0 = load i128* null, align 1 + %tmp1 = load <2 x i32>* undef, align 8 + %tmp2 = bitcast i128 %tmp0 to <16 x i8> + %tmp3 = bitcast <2 x i32> %tmp1 to i64 + %tmp4 = insertelement <2 x i64> undef, i64 %tmp3, i32 0 + %tmp5 = bitcast <16 x i8> %tmp2 to <2 x double> + %tmp6 = bitcast <2 x i64> %tmp4 to <2 x double> + %tmp7 = shufflevector <2 x double> %tmp5, <2 x double> %tmp6, <2 x i32> <i32 2, i32 1> + ret <2 x double> %tmp7 +} + +; rdar://10450317 +define <2 x i64> @t4() nounwind readonly { +bb: +; CHECK: t4: +; CHECK: punpcklqdq %xmm0, %xmm1 +; CHECK: movq (%rax), %xmm0 +; CHECK: movsd %xmm1, %xmm0 + %tmp0 = load i128* null, align 1 + %tmp1 = load <2 x i32>* undef, align 8 + %tmp2 = bitcast i128 %tmp0 to <16 x i8> + %tmp3 = bitcast <2 x i32> %tmp1 to i64 + %tmp4 = insertelement <2 x i64> undef, i64 %tmp3, i32 0 + %tmp5 = bitcast <16 x i8> %tmp2 to <2 x i64> + %tmp6 = shufflevector <2 x i64> %tmp4, <2 x i64> %tmp5, <2 x i32> <i32 2, i32 1> + ret <2 x i64> %tmp6 +} diff --git a/test/CodeGen/X86/vec_shuffle.ll b/test/CodeGen/X86/vec_shuffle.ll index 2a48de2..6599598 100644 --- a/test/CodeGen/X86/vec_shuffle.ll +++ b/test/CodeGen/X86/vec_shuffle.ll @@ -1,9 +1,8 @@ -; RUN: llc < %s -march=x86 -mcpu=core2 -o %t -; RUN: grep movq %t | count 1 -; RUN: grep pshufd %t | count 1 -; RUN: grep movupd %t | count 1 -; RUN: grep pshufhw %t | count 1 +; RUN: llc < %s -mtriple=i686-linux -mcpu=core2 | FileCheck %s +; CHECK: test_v4sf +; CHECK: movq 8(%esp) +; CHECK: pshufd $80 define void @test_v4sf(<4 x float>* %P, float %X, float %Y) nounwind { %tmp = insertelement <4 x float> zeroinitializer, float %X, i32 0 ; <<4 x float>> [#uses=1] %tmp2 = insertelement <4 x float> %tmp, float %X, i32 1 ; <<4 x float>> [#uses=1] @@ -13,6 +12,9 @@ define void @test_v4sf(<4 x float>* %P, float %X, float %Y) nounwind { ret void } +; CHECK: test_v2sd +; CHECK: movups 8(%esp) +; CHECK: movaps define void @test_v2sd(<2 x double>* %P, double %X, double %Y) nounwind { %tmp = insertelement <2 x double> zeroinitializer, double %X, i32 0 ; <<2 x double>> [#uses=1] %tmp2 = insertelement <2 x double> %tmp, double %Y, i32 1 ; <<2 x double>> [#uses=1] @@ -20,6 +22,9 @@ define void @test_v2sd(<2 x double>* %P, double %X, double %Y) nounwind { ret void } +; CHECK: test_v8i16 +; CHECK: pshufhw $-58 +; CHECK: movdqa define void @test_v8i16(<2 x i64>* %res, <2 x i64>* %A) nounwind { %tmp = load <2 x i64>* %A ; <<2 x i64>> [#uses=1] %tmp.upgrd.1 = bitcast <2 x i64> %tmp to <8 x i16> ; <<8 x i16>> [#uses=8] diff --git a/test/CodeGen/X86/vec_udiv_to_shift.ll b/test/CodeGen/X86/vec_udiv_to_shift.ll new file mode 100644 index 0000000..6edfcc0 --- /dev/null +++ b/test/CodeGen/X86/vec_udiv_to_shift.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +define <8 x i16> @udiv_vec8x16(<8 x i16> %var) { +entry: +; CHECK: lshr <8 x i16> %var, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5> +%0 = udiv <8 x i16> %var, <i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32> +ret <8 x i16> %0 +} + +define <4 x i32> @udiv_vec4x32(<4 x i32> %var) { +entry: +; CHECK: lshr <4 x i32> %var, <i32 4, i32 4, i32 4, i32 4> +%0 = udiv <4 x i32> %var, <i32 16, i32 16, i32 16, i32 16> +ret <4 x i32> %0 +} diff --git a/test/CodeGen/X86/vec_zero.ll b/test/CodeGen/X86/vec_zero.ll index 4d1f056..682a0df 100644 --- a/test/CodeGen/X86/vec_zero.ll +++ b/test/CodeGen/X86/vec_zero.ll @@ -1,5 +1,6 @@ ; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s +; CHECK: foo ; CHECK: xorps define void @foo(<4 x float>* %P) { %T = load <4 x float>* %P ; <<4 x float>> [#uses=1] @@ -8,6 +9,7 @@ define void @foo(<4 x float>* %P) { ret void } +; CHECK: bar ; CHECK: pxor define void @bar(<4 x i32>* %P) { %T = load <4 x i32>* %P ; <<4 x i32>> [#uses=1] @@ -16,3 +18,13 @@ define void @bar(<4 x i32>* %P) { ret void } +; Without any type hints from operations, we fall back to the smaller xorps. +; The IR type <4 x i32> is ignored. +; CHECK: untyped_zero +; CHECK: xorps +; CHECK: movaps +define void @untyped_zero(<4 x i32>* %p) { +entry: + store <4 x i32> zeroinitializer, <4 x i32>* %p, align 16 + ret void +} diff --git a/test/CodeGen/X86/vec_zero_cse.ll b/test/CodeGen/X86/vec_zero_cse.ll index 8aa5094..41ea024 100644 --- a/test/CodeGen/X86/vec_zero_cse.ll +++ b/test/CodeGen/X86/vec_zero_cse.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -relocation-model=static -march=x86 -mcpu=yonah | grep pxor | count 1 +; RUN: llc < %s -relocation-model=static -march=x86 -mcpu=yonah | grep xorps | count 1 ; RUN: llc < %s -relocation-model=static -march=x86 -mcpu=yonah | grep pcmpeqd | count 1 ; 64-bit stores here do not use MMX. diff --git a/test/CodeGen/X86/vector-gep.ll b/test/CodeGen/X86/vector-gep.ll new file mode 100644 index 0000000..3476e36 --- /dev/null +++ b/test/CodeGen/X86/vector-gep.ll @@ -0,0 +1,88 @@ +; RUN: llc < %s -march=x86 -mcpu=corei7-avx | FileCheck %s +; RUN: opt -instsimplify %s -disable-output + +;CHECK: AGEP0: +define <4 x i32*> @AGEP0(i32* %ptr) nounwind { +entry: + %vecinit.i = insertelement <4 x i32*> undef, i32* %ptr, i32 0 + %vecinit2.i = insertelement <4 x i32*> %vecinit.i, i32* %ptr, i32 1 + %vecinit4.i = insertelement <4 x i32*> %vecinit2.i, i32* %ptr, i32 2 + %vecinit6.i = insertelement <4 x i32*> %vecinit4.i, i32* %ptr, i32 3 +;CHECK: pslld $2 +;CHECK: padd + %A2 = getelementptr <4 x i32*> %vecinit6.i, <4 x i32> <i32 1, i32 2, i32 3, i32 4> +;CHECK: pslld $2 +;CHECK: padd + %A3 = getelementptr <4 x i32*> %A2, <4 x i32> <i32 10, i32 14, i32 19, i32 233> + ret <4 x i32*> %A3 +;CHECK: ret +} + +;CHECK: AGEP1: +define i32 @AGEP1(<4 x i32*> %param) nounwind { +entry: +;CHECK: pslld $2 +;CHECK: padd + %A2 = getelementptr <4 x i32*> %param, <4 x i32> <i32 1, i32 2, i32 3, i32 4> + %k = extractelement <4 x i32*> %A2, i32 3 + %v = load i32* %k + ret i32 %v +;CHECK: ret +} + +;CHECK: AGEP2: +define i32 @AGEP2(<4 x i32*> %param, <4 x i32> %off) nounwind { +entry: +;CHECK: pslld $2 +;CHECK: padd + %A2 = getelementptr <4 x i32*> %param, <4 x i32> %off + %k = extractelement <4 x i32*> %A2, i32 3 + %v = load i32* %k + ret i32 %v +;CHECK: ret +} + +;CHECK: AGEP3: +define <4 x i32*> @AGEP3(<4 x i32*> %param, <4 x i32> %off) nounwind { +entry: +;CHECK: pslld $2 +;CHECK: padd + %A2 = getelementptr <4 x i32*> %param, <4 x i32> %off + %v = alloca i32 + %k = insertelement <4 x i32*> %A2, i32* %v, i32 3 + ret <4 x i32*> %k +;CHECK: ret +} + +;CHECK: AGEP4: +define <4 x i16*> @AGEP4(<4 x i16*> %param, <4 x i32> %off) nounwind { +entry: +; Multiply offset by two (add it to itself). +;CHECK: padd +; add the base to the offset +;CHECK: padd + %A = getelementptr <4 x i16*> %param, <4 x i32> %off + ret <4 x i16*> %A +;CHECK: ret +} + +;CHECK: AGEP5: +define <4 x i8*> @AGEP5(<4 x i8*> %param, <4 x i8> %off) nounwind { +entry: +;CHECK: paddd + %A = getelementptr <4 x i8*> %param, <4 x i8> %off + ret <4 x i8*> %A +;CHECK: ret +} + + +; The size of each element is 1 byte. No need to multiply by element size. +;CHECK: AGEP6: +define <4 x i8*> @AGEP6(<4 x i8*> %param, <4 x i32> %off) nounwind { +entry: +;CHECK-NOT: pslld + %A = getelementptr <4 x i8*> %param, <4 x i32> %off + ret <4 x i8*> %A +;CHECK: ret +} + diff --git a/test/CodeGen/X86/vector-variable-idx2.ll b/test/CodeGen/X86/vector-variable-idx2.ll new file mode 100644 index 0000000..d47df90 --- /dev/null +++ b/test/CodeGen/X86/vector-variable-idx2.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -march=x86-64 -mattr=+sse41 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin11.0.0" + +define i64 @__builtin_ia32_vec_ext_v2di(<2 x i64> %a, i32 %i) nounwind { + %1 = alloca <2 x i64>, align 16 + %2 = alloca i32, align 4 + store <2 x i64> %a, <2 x i64>* %1, align 16 + store i32 %i, i32* %2, align 4 + %3 = load <2 x i64>* %1, align 16 + %4 = load i32* %2, align 4 + %5 = extractelement <2 x i64> %3, i32 %4 + ret i64 %5 +} + +define <2 x i64> @__builtin_ia32_vec_int_v2di(<2 x i64> %a, i32 %i) nounwind { + %1 = alloca <2 x i64>, align 16 + %2 = alloca i32, align 4 + store <2 x i64> %a, <2 x i64>* %1, align 16 + store i32 %i, i32* %2, align 4 + %3 = load <2 x i64>* %1, align 16 + %4 = load i32* %2, align 4 + %5 = insertelement <2 x i64> %3, i64 1, i32 %4 + ret <2 x i64> %5 +} diff --git a/test/CodeGen/X86/volatile.ll b/test/CodeGen/X86/volatile.ll index 2e5742a..1a82014 100644 --- a/test/CodeGen/X86/volatile.ll +++ b/test/CodeGen/X86/volatile.ll @@ -4,14 +4,14 @@ @x = external global double define void @foo() nounwind { - %a = volatile load double* @x - volatile store double 0.0, double* @x - volatile store double 0.0, double* @x - %b = volatile load double* @x + %a = load volatile double* @x + store volatile double 0.0, double* @x + store volatile double 0.0, double* @x + %b = load volatile double* @x ret void } define void @bar() nounwind { - %c = volatile load double* @x + %c = load volatile double* @x ret void } diff --git a/test/CodeGen/X86/vsplit-and.ll b/test/CodeGen/X86/vsplit-and.ll index 97dacfd..ee98806 100644 --- a/test/CodeGen/X86/vsplit-and.ll +++ b/test/CodeGen/X86/vsplit-and.ll @@ -1,8 +1,9 @@ -; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s - -define void @t(<2 x i64>* %dst, <2 x i64> %src1, <2 x i64> %src2) nounwind readonly { -; CHECK: andb +define void @t0(<2 x i64>* %dst, <2 x i64> %src1, <2 x i64> %src2) nounwind readonly { +; CHECK: t0 +; CHECK: pand +; CHECK: ret %cmp1 = icmp ne <2 x i64> %src1, zeroinitializer %cmp2 = icmp ne <2 x i64> %src2, zeroinitializer %t1 = and <2 x i1> %cmp1, %cmp2 @@ -12,7 +13,9 @@ define void @t(<2 x i64>* %dst, <2 x i64> %src1, <2 x i64> %src2) nounwind reado } define void @t2(<3 x i64>* %dst, <3 x i64> %src1, <3 x i64> %src2) nounwind readonly { -; CHECK: andb +; CHECK: t2 +; CHECK-NOT: pand +; CHECK: ret %cmp1 = icmp ne <3 x i64> %src1, zeroinitializer %cmp2 = icmp ne <3 x i64> %src2, zeroinitializer %t1 = and <3 x i1> %cmp1, %cmp2 diff --git a/test/CodeGen/X86/widen_arith-1.ll b/test/CodeGen/X86/widen_arith-1.ll index 4b8016d..661cde8 100644 --- a/test/CodeGen/X86/widen_arith-1.ll +++ b/test/CodeGen/X86/widen_arith-1.ll @@ -1,12 +1,10 @@ -; RUN: llc < %s -march=x86 -mattr=+sse42 | FileCheck %s - -; Widen a v3i8 to v16i8 to use a vector add +; RUN: llc < %s -mcpu=generic -march=x86 -mattr=+sse42 | FileCheck %s define void @update(<3 x i8>* %dst, <3 x i8>* %src, i32 %n) nounwind { entry: ; CHECK-NOT: pextrw -; CHECK: paddb -; CHECK: pextrb +; CHECK: add + %dst.addr = alloca <3 x i8>* ; <<3 x i8>**> [#uses=2] %src.addr = alloca <3 x i8>* ; <<3 x i8>**> [#uses=2] %n.addr = alloca i32 ; <i32*> [#uses=2] diff --git a/test/CodeGen/X86/widen_arith-2.ll b/test/CodeGen/X86/widen_arith-2.ll index 03b3fea..d35abc3 100644 --- a/test/CodeGen/X86/widen_arith-2.ll +++ b/test/CodeGen/X86/widen_arith-2.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -march=x86 -mattr=+sse42 | FileCheck %s -; CHECK: paddb +; CHECK: padd ; CHECK: pand ; widen v8i8 to v16i8 (checks even power of 2 widening with add & and) diff --git a/test/CodeGen/X86/widen_arith-3.ll b/test/CodeGen/X86/widen_arith-3.ll index 0574923..f55b184 100644 --- a/test/CodeGen/X86/widen_arith-3.ll +++ b/test/CodeGen/X86/widen_arith-3.ll @@ -1,7 +1,8 @@ -; RUN: llc < %s -march=x86 -mattr=+sse42 -post-RA-scheduler=true | FileCheck %s -; CHECK: paddw -; CHECK: pextrw -; CHECK: movd +; RUN: llc < %s -mcpu=generic -march=x86 -mattr=+sse42 -post-RA-scheduler=true | FileCheck %s +; CHECK: incl +; CHECK: incl +; CHECK: incl +; CHECK: addl ; Widen a v3i16 to v8i16 to do a vector add diff --git a/test/CodeGen/X86/widen_cast-1.ll b/test/CodeGen/X86/widen_cast-1.ll index 1eace9e..4330aae 100644 --- a/test/CodeGen/X86/widen_cast-1.ll +++ b/test/CodeGen/X86/widen_cast-1.ll @@ -1,5 +1,5 @@ ; RUN: llc -march=x86 -mattr=+sse42 < %s | FileCheck %s -; CHECK: paddw +; CHECK: paddd ; CHECK: pextrd ; CHECK: movd diff --git a/test/CodeGen/X86/widen_cast-4.ll b/test/CodeGen/X86/widen_cast-4.ll index 8e1adf5..5ea5426 100644 --- a/test/CodeGen/X86/widen_cast-4.ll +++ b/test/CodeGen/X86/widen_cast-4.ll @@ -1,16 +1,6 @@ ; RUN: llc < %s -march=x86 -mattr=+sse42 | FileCheck %s -; CHECK: sarb -; CHECK: sarb -; CHECK: sarb -; CHECK: sarb -; CHECK: sarb -; CHECK: sarb -; CHECK: sarb -; CHECK: sarb - -; v8i8 that is widen to v16i8 then split -; FIXME: This is widen to v16i8 and split to 16 and we then rebuild the vector. -; Unfortunately, we don't split the store so we don't get the code we want. +; CHECK: psraw +; CHECK: psraw define void @update(i64* %dst_i, i64* %src_i, i32 %n) nounwind { entry: diff --git a/test/CodeGen/X86/widen_conv-1.ll b/test/CodeGen/X86/widen_conv-1.ll index f6810cd..51f1c88 100644 --- a/test/CodeGen/X86/widen_conv-1.ll +++ b/test/CodeGen/X86/widen_conv-1.ll @@ -1,6 +1,5 @@ ; RUN: llc < %s -march=x86 -mattr=+sse42 | FileCheck %s -; CHECK: pshufd -; CHECK: paddd +; CHECK: paddq ; truncate v2i64 to v2i32 diff --git a/test/CodeGen/X86/widen_conv-4.ll b/test/CodeGen/X86/widen_conv-4.ll index 80f3a49..affd796 100644 --- a/test/CodeGen/X86/widen_conv-4.ll +++ b/test/CodeGen/X86/widen_conv-4.ll @@ -1,5 +1,5 @@ ; RUN: llc < %s -march=x86 -mattr=+sse42 | FileCheck %s -; CHECK: cvtsi2ss +; CHECK-NOT: cvtsi2ss ; unsigned to float v7i16 to v7f32 diff --git a/test/CodeGen/X86/widen_load-0.ll b/test/CodeGen/X86/widen_load-0.ll index c91627c..4aeec91 100644 --- a/test/CodeGen/X86/widen_load-0.ll +++ b/test/CodeGen/X86/widen_load-0.ll @@ -1,18 +1,18 @@ -; RUN: llc < %s -o - -mtriple=x86_64-linux | FileCheck %s -; RUN: llc < %s -o - -mtriple=x86_64-win32 | FileCheck %s -check-prefix=WIN64 +; RUN: llc < %s -o - -mtriple=x86_64-linux -mcpu=corei7 | FileCheck %s +; RUN: llc < %s -o - -mtriple=x86_64-win32 -mcpu=corei7 | FileCheck %s -check-prefix=WIN64 ; PR4891 ; Both loads should happen before either store. -; CHECK: movl (%rdi), %[[R1:...]] -; CHECK: movl (%rsi), %[[R2:...]] -; CHECK: movl %[[R2]], (%rdi) -; CHECK: movl %[[R1]], (%rsi) +; CHECK: movd ({{.*}}), {{.*}} +; CHECK: movd ({{.*}}), {{.*}} +; CHECK: movd {{.*}}, ({{.*}}) +; CHECK: movd {{.*}}, ({{.*}}) -; WIN64: movl (%rcx), %[[R1:...]] -; WIN64: movl (%rdx), %[[R2:...]] -; WIN64: movl %[[R2]], (%rcx) -; WIN64: movl %[[R1]], (%rdx) +; WIN64: movd ({{.*}}), {{.*}} +; WIN64: movd ({{.*}}), {{.*}} +; WIN64: movd {{.*}}, ({{.*}}) +; WIN64: movd {{.*}}, ({{.*}}) define void @short2_int_swap(<2 x i16>* nocapture %b, i32* nocapture %c) nounwind { entry: diff --git a/test/CodeGen/X86/widen_load-1.ll b/test/CodeGen/X86/widen_load-1.ll index 639617f..9705d14 100644 --- a/test/CodeGen/X86/widen_load-1.ll +++ b/test/CodeGen/X86/widen_load-1.ll @@ -1,5 +1,6 @@ ; RUN: llc %s -o - -march=x86-64 -mtriple=x86_64-unknown-linux-gnu | FileCheck %s ; PR4891 +; PR5626 ; This load should be before the call, not after. diff --git a/test/CodeGen/X86/widen_load-2.ll b/test/CodeGen/X86/widen_load-2.ll index 6422063..79aa000 100644 --- a/test/CodeGen/X86/widen_load-2.ll +++ b/test/CodeGen/X86/widen_load-2.ll @@ -1,9 +1,10 @@ -; RUN: llc < %s -o - -march=x86-64 -mattr=+sse42 | FileCheck %s +; RUN: llc < %s -o - -mcpu=generic -march=x86-64 -mattr=+sse42 | FileCheck %s ; Test based on pr5626 to load/store ; %i32vec3 = type <3 x i32> +; CHECK: add3i32 define void @add3i32(%i32vec3* sret %ret, %i32vec3* %ap, %i32vec3* %bp) { ; CHECK: movdqa ; CHECK: paddd @@ -16,6 +17,7 @@ define void @add3i32(%i32vec3* sret %ret, %i32vec3* %ap, %i32vec3* %bp) { ret void } +; CHECK: add3i32_2 define void @add3i32_2(%i32vec3* sret %ret, %i32vec3* %ap, %i32vec3* %bp) { ; CHECK: movq ; CHECK: pinsrd @@ -32,6 +34,7 @@ define void @add3i32_2(%i32vec3* sret %ret, %i32vec3* %ap, %i32vec3* %bp) { } %i32vec7 = type <7 x i32> +; CHECK: add7i32 define void @add7i32(%i32vec7* sret %ret, %i32vec7* %ap, %i32vec7* %bp) { ; CHECK: movdqa ; CHECK: movdqa @@ -47,6 +50,7 @@ define void @add7i32(%i32vec7* sret %ret, %i32vec7* %ap, %i32vec7* %bp) { ret void } +; CHECK: add12i32 %i32vec12 = type <12 x i32> define void @add12i32(%i32vec12* sret %ret, %i32vec12* %ap, %i32vec12* %bp) { ; CHECK: movdqa @@ -66,12 +70,14 @@ define void @add12i32(%i32vec12* sret %ret, %i32vec12* %ap, %i32vec12* %bp) { } +; CHECK: add3i16 %i16vec3 = type <3 x i16> define void @add3i16(%i16vec3* nocapture sret %ret, %i16vec3* %ap, %i16vec3* %bp) nounwind { -; CHECK: movdqa -; CHECK: paddw -; CHECK: movd -; CHECK: pextrw +; CHECK: add3i16 +; CHECK: addl +; CHECK: addl +; CHECK: addl +; CHECK: ret %a = load %i16vec3* %ap, align 16 %b = load %i16vec3* %bp, align 16 %x = add %i16vec3 %a, %b @@ -79,10 +85,11 @@ define void @add3i16(%i16vec3* nocapture sret %ret, %i16vec3* %ap, %i16vec3* %bp ret void } +; CHECK: add4i16 %i16vec4 = type <4 x i16> define void @add4i16(%i16vec4* nocapture sret %ret, %i16vec4* %ap, %i16vec4* %bp) nounwind { -; CHECK: movdqa -; CHECK: paddw +; CHECK: add4i16 +; CHECK: paddd ; CHECK: movq %a = load %i16vec4* %ap, align 16 %b = load %i16vec4* %bp, align 16 @@ -91,6 +98,7 @@ define void @add4i16(%i16vec4* nocapture sret %ret, %i16vec4* %ap, %i16vec4* %bp ret void } +; CHECK: add12i16 %i16vec12 = type <12 x i16> define void @add12i16(%i16vec12* nocapture sret %ret, %i16vec12* %ap, %i16vec12* %bp) nounwind { ; CHECK: movdqa @@ -106,6 +114,7 @@ define void @add12i16(%i16vec12* nocapture sret %ret, %i16vec12* %ap, %i16vec12* ret void } +; CHECK: add18i16 %i16vec18 = type <18 x i16> define void @add18i16(%i16vec18* nocapture sret %ret, %i16vec18* %ap, %i16vec18* %bp) nounwind { ; CHECK: movdqa @@ -125,12 +134,13 @@ define void @add18i16(%i16vec18* nocapture sret %ret, %i16vec18* %ap, %i16vec18* } +; CHECK: add3i8 %i8vec3 = type <3 x i8> define void @add3i8(%i8vec3* nocapture sret %ret, %i8vec3* %ap, %i8vec3* %bp) nounwind { -; CHECK: movdqa -; CHECK: paddb -; CHECK: pextrb -; CHECK: movb +; CHECK: addb +; CHECK: addb +; CHECK: addb +; CHECK: ret %a = load %i8vec3* %ap, align 16 %b = load %i8vec3* %bp, align 16 %x = add %i8vec3 %a, %b @@ -138,6 +148,7 @@ define void @add3i8(%i8vec3* nocapture sret %ret, %i8vec3* %ap, %i8vec3* %bp) no ret void } +; CHECK: add31i8: %i8vec31 = type <31 x i8> define void @add31i8(%i8vec31* nocapture sret %ret, %i8vec31* %ap, %i8vec31* %bp) nounwind { ; CHECK: movdqa @@ -147,6 +158,7 @@ define void @add31i8(%i8vec31* nocapture sret %ret, %i8vec31* %ap, %i8vec31* %bp ; CHECK: movq ; CHECK: pextrb ; CHECK: pextrw +; CHECK: ret %a = load %i8vec31* %ap, align 16 %b = load %i8vec31* %bp, align 16 %x = add %i8vec31 %a, %b @@ -155,9 +167,10 @@ define void @add31i8(%i8vec31* nocapture sret %ret, %i8vec31* %ap, %i8vec31* %bp } +; CHECK: rot %i8vec3pack = type { <3 x i8>, i8 } define %i8vec3pack @rot() nounwind { -; CHECK: shrb +; CHECK: movd {{-?[0-9]+}}(%rsp), {{%xmm[0-9]}} entry: %X = alloca %i8vec3pack, align 4 %rot = alloca %i8vec3pack, align 4 diff --git a/test/CodeGen/X86/widen_shuffle-1.ll b/test/CodeGen/X86/widen_shuffle-1.ll index 8e951b7..7bebb27 100644 --- a/test/CodeGen/X86/widen_shuffle-1.ll +++ b/test/CodeGen/X86/widen_shuffle-1.ll @@ -10,6 +10,7 @@ entry: %val = fadd <3 x float> %x, %src2 store <3 x float> %val, <3 x float>* %dst.addr ret void +; CHECK: ret } @@ -23,6 +24,7 @@ entry: %val = fadd <3 x float> %x, %src2 store <3 x float> %val, <3 x float>* %dst.addr ret void +; CHECK: ret } ; Example of when widening a v3float operation causes the DAG to replace a node @@ -31,7 +33,7 @@ entry: define void @shuf3(<4 x float> %tmp10, <4 x float> %vecinit15, <4 x float>* %dst) nounwind { entry: ; CHECK: shuf3: -; CHECK: pshufd +; CHECK: shufps %shuffle.i.i.i12 = shufflevector <4 x float> %tmp10, <4 x float> %vecinit15, <4 x i32> <i32 0, i32 1, i32 4, i32 5> %tmp25.i.i = shufflevector <4 x float> %shuffle.i.i.i12, <4 x float> undef, <3 x i32> <i32 0, i32 1, i32 2> %tmp1.i.i = shufflevector <3 x float> %tmp25.i.i, <3 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3> @@ -45,12 +47,23 @@ entry: %shuffle.i.i.i21 = shufflevector <4 x float> %tmp2.i18, <4 x float> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3> store <4 x float> %shuffle.i.i.i21, <4 x float>* %dst ret void +; CHECK: ret } ; PR10421: make sure we correctly handle extreme widening with CONCAT_VECTORS define <8 x i8> @shuf4(<4 x i8> %a, <4 x i8> %b) nounwind readnone { ; CHECK: shuf4: -; CHECK: punpckldq +; CHECK-NOT: punpckldq %vshuf = shufflevector <4 x i8> %a, <4 x i8> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> ret <8 x i8> %vshuf +; CHECK: ret +} + +; PR11389: another CONCAT_VECTORS case +define void @shuf5(<8 x i8>* %p) nounwind { +; CHECK: shuf5: + %v = shufflevector <2 x i8> <i8 4, i8 33>, <2 x i8> undef, <8 x i32> <i32 1, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef> + store <8 x i8> %v, <8 x i8>* %p, align 8 + ret void +; CHECK: ret } diff --git a/test/CodeGen/X86/win32_sret.ll b/test/CodeGen/X86/win32_sret.ll new file mode 100644 index 0000000..878c6db --- /dev/null +++ b/test/CodeGen/X86/win32_sret.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32 +; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X32 +; RUN: llc < %s -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX +; RUN: llc < %s -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32 +; RUN: llc < %s -O0 -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X32 +; RUN: llc < %s -O0 -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX + +; The SysV ABI used by most Unixes and Mingw on x86 specifies that an sret pointer +; is callee-cleanup. However, in MSVC's cdecl calling convention, sret pointer +; arguments are caller-cleanup like normal arguments. + +define void @sret1(i8* sret) nounwind { +entry: +; WIN_X32: {{ret$}} +; MINGW_X32: ret $4 +; LINUX: ret $4 + ret void +} + +define void @sret2(i32* sret %x, i32 %y) nounwind { +entry: +; WIN_X32: {{ret$}} +; MINGW_X32: ret $4 +; LINUX: ret $4 + store i32 %y, i32* %x + ret void +} + diff --git a/test/CodeGen/X86/win64_alloca_dynalloca.ll b/test/CodeGen/X86/win64_alloca_dynalloca.ll index e39d007..a961c6a 100644 --- a/test/CodeGen/X86/win64_alloca_dynalloca.ll +++ b/test/CodeGen/X86/win64_alloca_dynalloca.ll @@ -1,6 +1,6 @@ -; RUN: llc < %s -join-physregs -mtriple=x86_64-mingw32 | FileCheck %s -check-prefix=M64 -; RUN: llc < %s -join-physregs -mtriple=x86_64-win32 | FileCheck %s -check-prefix=W64 -; RUN: llc < %s -join-physregs -mtriple=x86_64-win32-macho | FileCheck %s -check-prefix=EFI +; RUN: llc < %s -join-physregs -mcpu=generic -mtriple=x86_64-mingw32 | FileCheck %s -check-prefix=M64 +; RUN: llc < %s -join-physregs -mcpu=generic -mtriple=x86_64-win32 | FileCheck %s -check-prefix=W64 +; RUN: llc < %s -join-physregs -mcpu=generic -mtriple=x86_64-win32-macho | FileCheck %s -check-prefix=EFI ; PR8777 ; PR8778 diff --git a/test/CodeGen/X86/win64_vararg.ll b/test/CodeGen/X86/win64_vararg.ll index efe8bca..52bc509 100644 --- a/test/CodeGen/X86/win64_vararg.ll +++ b/test/CodeGen/X86/win64_vararg.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-pc-win32 | FileCheck %s ; Verify that the var arg parameters which are passed in registers are stored ; in home stack slots allocated by the caller and that AP is correctly diff --git a/test/CodeGen/X86/win_ftol2.ll b/test/CodeGen/X86/win_ftol2.ll new file mode 100644 index 0000000..596b426 --- /dev/null +++ b/test/CodeGen/X86/win_ftol2.ll @@ -0,0 +1,144 @@ +; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=FTOL +; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT +; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s -check-prefix=COMPILERRT +; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=COMPILERRT +; RUN: llc < %s -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT +; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s -check-prefix=COMPILERRT +; RUN: llc < %s -mattr=-sse -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=FTOL_2 + +; Win32 targets use the MSVCRT _ftol2 runtime function for fptoui to i64. This +; function has a nonstandard calling convention: the input value is expected on +; the x87 stack instead of the callstack. The input value is popped by the +; callee. Mingw32 uses normal cdecl compiler-rt functions. + +define i64 @double_ui64(double %x) nounwind { +entry: +; COMPILERRT: @double_ui64 +; COMPILERRT-NOT: calll __ftol2 +; FTOL: @double_ui64 +; FTOL: fldl +; FTOL: calll __ftol2 +; FTOL-NOT: fstp + %0 = fptoui double %x to i64 + ret i64 %0 +} + +define i64 @float_ui64(float %x) nounwind { +entry: +; COMPILERRT: @float_ui64 +; COMPILERRT-NOT: calll __ftol2 +; FTOL: @float_ui64 +; FTOL: flds +; FTOL: calll __ftol2 +; FTOL-NOT: fstp + %0 = fptoui float %x to i64 + ret i64 %0 +} + +define i64 @double_ui64_2(double %x, double %y, double %z) nounwind { +; COMPILERRT: @double_ui64_2 +; FTOL: @double_ui64_2 +; FTOL_2: @double_ui64_2 +;; stack is empty +; FTOL_2: fldl +;; stack is %z +; FTOL_2: fldl +;; stack is %y %z +; FTOL_2: fldl +;; stack is %x %y %z +; FTOL_2: fdiv %st(0), %st(1) +;; stack is %x %1 %z +; FTOL_2: fsubp %st(2) +;; stack is %1 %2 +; FTOL_2: fxch +; FTOL_2-NOT: fld +; FTOL_2-NOT: fst +;; stack is %2 %1 +; FTOL_2: calll __ftol2 +; FTOL_2-NOT: fxch +; FTOL_2-NOT: fld +; FTOL_2-NOT: fst +; FTOL_2: calll __ftol2 +;; stack is empty + + %1 = fdiv double %x, %y + %2 = fsub double %x, %z + %3 = fptoui double %1 to i64 + %4 = fptoui double %2 to i64 + %5 = sub i64 %3, %4 + ret i64 %5 +} + +define i64 @double_ui64_3(double %x, double %y, double %z) nounwind { +; COMPILERRT: @double_ui64_3 +; FTOL: @double_ui64_3 +; FTOL_2: @double_ui64_3 +;; stack is empty +; FTOL_2: fldl +;; stack is %z +; FTOL_2: fldl +;; stack is %y %z +; FTOL_2: fldl +;; stack is %x %y %z +; FTOL_2: fdiv %st(0), %st(1) +;; stack is %x %1 %z +; FTOL_2: fsubp %st(2) +;; stack is %1 %2 +; FTOL_2-NOT: fxch +; FTOL_2-NOT: fld +; FTOL_2-NOT: fst +;; stack is %1 %2 (still) +; FTOL_2: calll __ftol2 +; FTOL_2-NOT: fxch +; FTOL_2-NOT: fld +; FTOL_2-NOT: fst +; FTOL_2: calll __ftol2 +;; stack is empty + + %1 = fdiv double %x, %y + %2 = fsub double %x, %z + %3 = fptoui double %1 to i64 + %4 = fptoui double %2 to i64 + %5 = sub i64 %4, %3 + ret i64 %5 +} + +define {double, i64} @double_ui64_4(double %x, double %y) nounwind { +; COMPILERRT: @double_ui64_4 +; FTOL: @double_ui64_4 +; FTOL_2: @double_ui64_4 +;; stack is empty +; FTOL_2: fldl +;; stack is %y +; FTOL_2: fldl +;; stack is %x %y +; FTOL_2: fxch +;; stack is %y %x +; FTOL_2: calll __ftol2 +;; stack is %x +; FTOL_2: fld %st(0) +;; stack is %x %x +; FTOL_2: calll __ftol2 +;; stack is %x + + %1 = fptoui double %x to i64 + %2 = fptoui double %y to i64 + %3 = sub i64 %1, %2 + %4 = insertvalue {double, i64} undef, double %x, 0 + %5 = insertvalue {double, i64} %4, i64 %3, 1 + ret {double, i64} %5 +} + +define i32 @double_ui32_5(double %X) { +; FTOL: @double_ui32_5 +; FTOL: calll __ftol2 + %tmp.1 = fptoui double %X to i32 + ret i32 %tmp.1 +} + +define i64 @double_ui64_5(double %X) { +; FTOL: @double_ui64_5 +; FTOL: calll __ftol2 + %tmp.1 = fptoui double %X to i64 + ret i64 %tmp.1 +} diff --git a/test/CodeGen/X86/x86-shifts.ll b/test/CodeGen/X86/x86-shifts.ll index fdf68f9..20bccab 100644 --- a/test/CodeGen/X86/x86-shifts.ll +++ b/test/CodeGen/X86/x86-shifts.ll @@ -6,8 +6,9 @@ define <4 x i32> @shl4(<4 x i32> %A) nounwind { entry: ; CHECK: shl4 +; CHECK: padd ; CHECK: pslld -; CHECK-NEXT: pslld +; CHECK: ret %B = shl <4 x i32> %A, < i32 2, i32 2, i32 2, i32 2> %C = shl <4 x i32> %A, < i32 1, i32 1, i32 1, i32 1> %K = xor <4 x i32> %B, %C @@ -19,6 +20,7 @@ entry: ; CHECK: shr4 ; CHECK: psrld ; CHECK-NEXT: psrld +; CHECK: ret %B = lshr <4 x i32> %A, < i32 2, i32 2, i32 2, i32 2> %C = lshr <4 x i32> %A, < i32 1, i32 1, i32 1, i32 1> %K = xor <4 x i32> %B, %C @@ -30,6 +32,7 @@ entry: ; CHECK: sra4 ; CHECK: psrad ; CHECK-NEXT: psrad +; CHECK: ret %B = ashr <4 x i32> %A, < i32 2, i32 2, i32 2, i32 2> %C = ashr <4 x i32> %A, < i32 1, i32 1, i32 1, i32 1> %K = xor <4 x i32> %B, %C @@ -41,6 +44,7 @@ entry: ; CHECK: shl2 ; CHECK: psllq ; CHECK-NEXT: psllq +; CHECK: ret %B = shl <2 x i64> %A, < i64 2, i64 2> %C = shl <2 x i64> %A, < i64 9, i64 9> %K = xor <2 x i64> %B, %C @@ -52,6 +56,7 @@ entry: ; CHECK: shr2 ; CHECK: psrlq ; CHECK-NEXT: psrlq +; CHECK: ret %B = lshr <2 x i64> %A, < i64 8, i64 8> %C = lshr <2 x i64> %A, < i64 1, i64 1> %K = xor <2 x i64> %B, %C @@ -62,8 +67,9 @@ entry: define <8 x i16> @shl8(<8 x i16> %A) nounwind { entry: ; CHECK: shl8 +; CHECK: padd ; CHECK: psllw -; CHECK-NEXT: psllw +; CHECK: ret %B = shl <8 x i16> %A, < i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2> %C = shl <8 x i16> %A, < i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> %K = xor <8 x i16> %B, %C @@ -75,6 +81,7 @@ entry: ; CHECK: shr8 ; CHECK: psrlw ; CHECK-NEXT: psrlw +; CHECK: ret %B = lshr <8 x i16> %A, < i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2> %C = lshr <8 x i16> %A, < i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> %K = xor <8 x i16> %B, %C @@ -86,6 +93,7 @@ entry: ; CHECK: sra8 ; CHECK: psraw ; CHECK-NEXT: psraw +; CHECK: ret %B = ashr <8 x i16> %A, < i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2, i16 2> %C = ashr <8 x i16> %A, < i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1> %K = xor <8 x i16> %B, %C @@ -100,6 +108,7 @@ entry: ; CHECK: sll8_nosplat ; CHECK-NOT: psll ; CHECK-NOT: psll +; CHECK: ret %B = shl <8 x i16> %A, < i16 1, i16 2, i16 3, i16 6, i16 2, i16 2, i16 2, i16 2> %C = shl <8 x i16> %A, < i16 9, i16 7, i16 5, i16 1, i16 4, i16 1, i16 1, i16 1> %K = xor <8 x i16> %B, %C @@ -112,6 +121,7 @@ entry: ; CHECK: shr2_nosplat ; CHECK-NOT: psrlq ; CHECK-NOT: psrlq +; CHECK: ret %B = lshr <2 x i64> %A, < i64 8, i64 1> %C = lshr <2 x i64> %A, < i64 1, i64 0> %K = xor <2 x i64> %B, %C @@ -124,7 +134,8 @@ entry: define <2 x i32> @shl2_other(<2 x i32> %A) nounwind { entry: ; CHECK: shl2_other -; CHECK-not: psllq +; CHECK: psllq +; CHECK: ret %B = shl <2 x i32> %A, < i32 2, i32 2> %C = shl <2 x i32> %A, < i32 9, i32 9> %K = xor <2 x i32> %B, %C @@ -134,9 +145,48 @@ entry: define <2 x i32> @shr2_other(<2 x i32> %A) nounwind { entry: ; CHECK: shr2_other -; CHECK-NOT: psrlq +; CHECK: psrlq +; CHECK: ret %B = lshr <2 x i32> %A, < i32 8, i32 8> %C = lshr <2 x i32> %A, < i32 1, i32 1> %K = xor <2 x i32> %B, %C ret <2 x i32> %K } + +define <16 x i8> @shl9(<16 x i8> %A) nounwind { + %B = shl <16 x i8> %A, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3> + ret <16 x i8> %B +; CHECK: shl9: +; CHECK: psllw $3 +; CHECK: pand +; CHECK: ret +} + +define <16 x i8> @shr9(<16 x i8> %A) nounwind { + %B = lshr <16 x i8> %A, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3> + ret <16 x i8> %B +; CHECK: shr9: +; CHECK: psrlw $3 +; CHECK: pand +; CHECK: ret +} + +define <16 x i8> @sra_v16i8_7(<16 x i8> %A) nounwind { + %B = ashr <16 x i8> %A, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7> + ret <16 x i8> %B +; CHECK: sra_v16i8_7: +; CHECK: pxor +; CHECK: pcmpgtb +; CHECK: ret +} + +define <16 x i8> @sra_v16i8(<16 x i8> %A) nounwind { + %B = ashr <16 x i8> %A, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3> + ret <16 x i8> %B +; CHECK: sra_v16i8: +; CHECK: psrlw $3 +; CHECK: pand +; CHECK: pxor +; CHECK: psubb +; CHECK: ret +} diff --git a/test/CodeGen/X86/xop-intrinsics-x86_64.ll b/test/CodeGen/X86/xop-intrinsics-x86_64.ll new file mode 100644 index 0000000..a2521b0 --- /dev/null +++ b/test/CodeGen/X86/xop-intrinsics-x86_64.ll @@ -0,0 +1,969 @@ +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -march=x86-64 -mattr=+avx,+fma4,+xop | FileCheck %s + +define <2 x double> @test_int_x86_xop_vpermil2pd(<2 x double> %a0, <2 x double> %a1, <2 x double> %a2) { + ; CHECK: vpermil2pd + %res = call <2 x double> @llvm.x86.xop.vpermil2pd(<2 x double> %a0, <2 x double> %a1, <2 x double> %a2, i8 1) ; [#uses=1] + ret <2 x double> %res +} +define <2 x double> @test_int_x86_xop_vpermil2pd_mr(<2 x double> %a0, <2 x double>* %a1, <2 x double> %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpermil2pd + %vec = load <2 x double>* %a1 + %res = call <2 x double> @llvm.x86.xop.vpermil2pd(<2 x double> %a0, <2 x double> %vec, <2 x double> %a2, i8 1) ; [#uses=1] + ret <2 x double> %res +} +define <2 x double> @test_int_x86_xop_vpermil2pd_rm(<2 x double> %a0, <2 x double> %a1, <2 x double>* %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpermil2pd + %vec = load <2 x double>* %a2 + %res = call <2 x double> @llvm.x86.xop.vpermil2pd(<2 x double> %a0, <2 x double> %a1, <2 x double> %vec, i8 1) ; [#uses=1] + ret <2 x double> %res +} +declare <2 x double> @llvm.x86.xop.vpermil2pd(<2 x double>, <2 x double>, <2 x double>, i8) nounwind readnone + +define <4 x double> @test_int_x86_xop_vpermil2pd_256(<4 x double> %a0, <4 x double> %a1, <4 x double> %a2) { + ; CHECK: vpermil2pd + ; CHECK: ymm + %res = call <4 x double> @llvm.x86.xop.vpermil2pd.256(<4 x double> %a0, <4 x double> %a1, <4 x double> %a2, i8 2) ; + ret <4 x double> %res +} +define <4 x double> @test_int_x86_xop_vpermil2pd_256_mr(<4 x double> %a0, <4 x double>* %a1, <4 x double> %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpermil2pd + ; CHECK: ymm + %vec = load <4 x double>* %a1 + %res = call <4 x double> @llvm.x86.xop.vpermil2pd.256(<4 x double> %a0, <4 x double> %vec, <4 x double> %a2, i8 2) ; + ret <4 x double> %res +} +define <4 x double> @test_int_x86_xop_vpermil2pd_256_rm(<4 x double> %a0, <4 x double> %a1, <4 x double>* %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpermil2pd + ; CHECK: ymm + %vec = load <4 x double>* %a2 + %res = call <4 x double> @llvm.x86.xop.vpermil2pd.256(<4 x double> %a0, <4 x double> %a1, <4 x double> %vec, i8 2) ; + ret <4 x double> %res +} +declare <4 x double> @llvm.x86.xop.vpermil2pd.256(<4 x double>, <4 x double>, <4 x double>, i8) nounwind readnone + +define <4 x float> @test_int_x86_xop_vpermil2ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { + ; CHECK: vpermil2ps + %res = call <4 x float> @llvm.x86.xop.vpermil2ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2, i8 3) ; + ret <4 x float> %res +} +declare <4 x float> @llvm.x86.xop.vpermil2ps(<4 x float>, <4 x float>, <4 x float>, i8) nounwind readnone + +define <8 x float> @test_int_x86_xop_vpermil2ps_256(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { + ; CHECK: vpermil2ps + ; CHECK: ymm + %res = call <8 x float> @llvm.x86.xop.vpermil2ps.256(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2, i8 4) ; + ret <8 x float> %res +} +declare <8 x float> @llvm.x86.xop.vpermil2ps.256(<8 x float>, <8 x float>, <8 x float>, i8) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcmov(<2 x i64> %a0, <2 x i64> %a1, <2 x i64> %a2) { + ; CHECK: vpcmov + %res = call <2 x i64> @llvm.x86.xop.vpcmov(<2 x i64> %a0, <2 x i64> %a1, <2 x i64> %a2) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcmov(<2 x i64>, <2 x i64>, <2 x i64>) nounwind readnone + +define <4 x i64> @test_int_x86_xop_vpcmov_256(<4 x i64> %a0, <4 x i64> %a1, <4 x i64> %a2) { + ; CHECK: vpcmov + ; CHECK: ymm + %res = call <4 x i64> @llvm.x86.xop.vpcmov.256(<4 x i64> %a0, <4 x i64> %a1, <4 x i64> %a2) ; + ret <4 x i64> %res +} +define <4 x i64> @test_int_x86_xop_vpcmov_256_mr(<4 x i64> %a0, <4 x i64>* %a1, <4 x i64> %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpcmov + ; CHECK: ymm + %vec = load <4 x i64>* %a1 + %res = call <4 x i64> @llvm.x86.xop.vpcmov.256(<4 x i64> %a0, <4 x i64> %vec, <4 x i64> %a2) ; + ret <4 x i64> %res +} +define <4 x i64> @test_int_x86_xop_vpcmov_256_rm(<4 x i64> %a0, <4 x i64> %a1, <4 x i64>* %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpcmov + ; CHECK: ymm + %vec = load <4 x i64>* %a2 + %res = call <4 x i64> @llvm.x86.xop.vpcmov.256(<4 x i64> %a0, <4 x i64> %a1, <4 x i64> %vec) ; + ret <4 x i64> %res +} +declare <4 x i64> @llvm.x86.xop.vpcmov.256(<4 x i64>, <4 x i64>, <4 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomeqb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK:vpcomb + %res = call <16 x i8> @llvm.x86.xop.vpcomeqb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +define <16 x i8> @test_int_x86_xop_vpcomeqb_mem(<16 x i8> %a0, <16 x i8>* %a1) { + ; CHECK-NOT: vmovaps + ; CHECK:vpcomb + %vec = load <16 x i8>* %a1 + %res = call <16 x i8> @llvm.x86.xop.vpcomeqb(<16 x i8> %a0, <16 x i8> %vec) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomeqb(<16 x i8>, <16 x i8>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomeqw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomw + %res = call <8 x i16> @llvm.x86.xop.vpcomeqw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomeqw(<8 x i16>, <8 x i16>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomeqd(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomd + %res = call <4 x i32> @llvm.x86.xop.vpcomeqd(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomeqd(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomeqq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomq + %res = call <2 x i64> @llvm.x86.xop.vpcomeqq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomeqq(<2 x i64>, <2 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomequb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomub + %res = call <16 x i8> @llvm.x86.xop.vpcomequb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomequb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomequd(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomud + %res = call <4 x i32> @llvm.x86.xop.vpcomequd(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomequd(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomequq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomuq + %res = call <2 x i64> @llvm.x86.xop.vpcomequq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomequq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomequw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomuw + %res = call <8 x i16> @llvm.x86.xop.vpcomequw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomequw(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomfalseb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomb + %res = call <16 x i8> @llvm.x86.xop.vpcomfalseb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomfalseb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomfalsed(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomd + %res = call <4 x i32> @llvm.x86.xop.vpcomfalsed(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomfalsed(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomfalseq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomq + %res = call <2 x i64> @llvm.x86.xop.vpcomfalseq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomfalseq(<2 x i64>, <2 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomfalseub(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomub + %res = call <16 x i8> @llvm.x86.xop.vpcomfalseub(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomfalseub(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomfalseud(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomud + %res = call <4 x i32> @llvm.x86.xop.vpcomfalseud(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomfalseud(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomfalseuq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomuq + %res = call <2 x i64> @llvm.x86.xop.vpcomfalseuq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomfalseuq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomfalseuw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomuw + %res = call <8 x i16> @llvm.x86.xop.vpcomfalseuw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomfalseuw(<8 x i16>, <8 x i16>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomfalsew(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomw + %res = call <8 x i16> @llvm.x86.xop.vpcomfalsew(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomfalsew(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomgeb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomb + %res = call <16 x i8> @llvm.x86.xop.vpcomgeb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomgeb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomged(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomd + %res = call <4 x i32> @llvm.x86.xop.vpcomged(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomged(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomgeq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomq + %res = call <2 x i64> @llvm.x86.xop.vpcomgeq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomgeq(<2 x i64>, <2 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomgeub(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomub + %res = call <16 x i8> @llvm.x86.xop.vpcomgeub(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomgeub(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomgeud(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomud + %res = call <4 x i32> @llvm.x86.xop.vpcomgeud(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomgeud(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomgeuq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomuq + %res = call <2 x i64> @llvm.x86.xop.vpcomgeuq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomgeuq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomgeuw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomuw + %res = call <8 x i16> @llvm.x86.xop.vpcomgeuw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomgeuw(<8 x i16>, <8 x i16>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomgew(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomw + %res = call <8 x i16> @llvm.x86.xop.vpcomgew(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomgew(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomgtb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomb + %res = call <16 x i8> @llvm.x86.xop.vpcomgtb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomgtb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomgtd(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomd + %res = call <4 x i32> @llvm.x86.xop.vpcomgtd(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomgtd(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomgtq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomq + %res = call <2 x i64> @llvm.x86.xop.vpcomgtq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomgtq(<2 x i64>, <2 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomgtub(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomub + %res = call <16 x i8> @llvm.x86.xop.vpcomgtub(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomgtub(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomgtud(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomud + %res = call <4 x i32> @llvm.x86.xop.vpcomgtud(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomgtud(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomgtuq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomuq + %res = call <2 x i64> @llvm.x86.xop.vpcomgtuq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomgtuq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomgtuw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomuw + %res = call <8 x i16> @llvm.x86.xop.vpcomgtuw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomgtuw(<8 x i16>, <8 x i16>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomgtw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomw + %res = call <8 x i16> @llvm.x86.xop.vpcomgtw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomgtw(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomleb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomb + %res = call <16 x i8> @llvm.x86.xop.vpcomleb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomleb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomled(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomd + %res = call <4 x i32> @llvm.x86.xop.vpcomled(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomled(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomleq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomq + %res = call <2 x i64> @llvm.x86.xop.vpcomleq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomleq(<2 x i64>, <2 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomleub(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomub + %res = call <16 x i8> @llvm.x86.xop.vpcomleub(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomleub(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomleud(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomud + %res = call <4 x i32> @llvm.x86.xop.vpcomleud(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomleud(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomleuq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomuq + %res = call <2 x i64> @llvm.x86.xop.vpcomleuq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomleuq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomleuw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomuw + %res = call <8 x i16> @llvm.x86.xop.vpcomleuw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomleuw(<8 x i16>, <8 x i16>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomlew(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomw + %res = call <8 x i16> @llvm.x86.xop.vpcomlew(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomlew(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomltb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomb + %res = call <16 x i8> @llvm.x86.xop.vpcomltb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomltb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomltd(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomd + %res = call <4 x i32> @llvm.x86.xop.vpcomltd(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomltd(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomltq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomq + %res = call <2 x i64> @llvm.x86.xop.vpcomltq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomltq(<2 x i64>, <2 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomltub(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomub + %res = call <16 x i8> @llvm.x86.xop.vpcomltub(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomltub(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomltud(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomud + %res = call <4 x i32> @llvm.x86.xop.vpcomltud(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomltud(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomltuq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomuq + %res = call <2 x i64> @llvm.x86.xop.vpcomltuq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomltuq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomltuw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomuw + %res = call <8 x i16> @llvm.x86.xop.vpcomltuw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomltuw(<8 x i16>, <8 x i16>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomltw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomw + %res = call <8 x i16> @llvm.x86.xop.vpcomltw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomltw(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomneb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomb + %res = call <16 x i8> @llvm.x86.xop.vpcomneb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomneb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomned(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomd + %res = call <4 x i32> @llvm.x86.xop.vpcomned(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomned(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomneq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomq + %res = call <2 x i64> @llvm.x86.xop.vpcomneq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomneq(<2 x i64>, <2 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomneub(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomub + %res = call <16 x i8> @llvm.x86.xop.vpcomneub(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomneub(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomneud(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomud + %res = call <4 x i32> @llvm.x86.xop.vpcomneud(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomneud(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomneuq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomuq + %res = call <2 x i64> @llvm.x86.xop.vpcomneuq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomneuq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomneuw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomuw + %res = call <8 x i16> @llvm.x86.xop.vpcomneuw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomneuw(<8 x i16>, <8 x i16>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomnew(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomw + %res = call <8 x i16> @llvm.x86.xop.vpcomnew(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomnew(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomtrueb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomb + %res = call <16 x i8> @llvm.x86.xop.vpcomtrueb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomtrueb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomtrued(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomd + %res = call <4 x i32> @llvm.x86.xop.vpcomtrued(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomtrued(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomtrueq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomq + %res = call <2 x i64> @llvm.x86.xop.vpcomtrueq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomtrueq(<2 x i64>, <2 x i64>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpcomtrueub(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpcomub + %res = call <16 x i8> @llvm.x86.xop.vpcomtrueub(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpcomtrueub(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpcomtrueud(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpcomud + %res = call <4 x i32> @llvm.x86.xop.vpcomtrueud(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpcomtrueud(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpcomtrueuq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpcomuq + %res = call <2 x i64> @llvm.x86.xop.vpcomtrueuq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpcomtrueuq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomtrueuw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomuw + %res = call <8 x i16> @llvm.x86.xop.vpcomtrueuw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomtrueuw(<8 x i16>, <8 x i16>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpcomtruew(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpcomw + %res = call <8 x i16> @llvm.x86.xop.vpcomtruew(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpcomtruew(<8 x i16>, <8 x i16>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vphaddbd(<16 x i8> %a0) { + ; CHECK: vphaddbd + %res = call <4 x i32> @llvm.x86.xop.vphaddbd(<16 x i8> %a0) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vphaddbd(<16 x i8>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vphaddbq(<16 x i8> %a0) { + ; CHECK: vphaddbq + %res = call <2 x i64> @llvm.x86.xop.vphaddbq(<16 x i8> %a0) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vphaddbq(<16 x i8>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vphaddbw(<16 x i8> %a0) { + ; CHECK: vphaddbw + %res = call <8 x i16> @llvm.x86.xop.vphaddbw(<16 x i8> %a0) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vphaddbw(<16 x i8>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vphadddq(<4 x i32> %a0) { + ; CHECK: vphadddq + %res = call <2 x i64> @llvm.x86.xop.vphadddq(<4 x i32> %a0) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vphadddq(<4 x i32>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vphaddubd(<16 x i8> %a0) { + ; CHECK: vphaddubd + %res = call <4 x i32> @llvm.x86.xop.vphaddubd(<16 x i8> %a0) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vphaddubd(<16 x i8>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vphaddubq(<16 x i8> %a0) { + ; CHECK: vphaddubq + %res = call <2 x i64> @llvm.x86.xop.vphaddubq(<16 x i8> %a0) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vphaddubq(<16 x i8>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vphaddubw(<16 x i8> %a0) { + ; CHECK: vphaddubw + %res = call <8 x i16> @llvm.x86.xop.vphaddubw(<16 x i8> %a0) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vphaddubw(<16 x i8>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vphaddudq(<4 x i32> %a0) { + ; CHECK: vphaddudq + %res = call <2 x i64> @llvm.x86.xop.vphaddudq(<4 x i32> %a0) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vphaddudq(<4 x i32>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vphadduwd(<8 x i16> %a0) { + ; CHECK: vphadduwd + %res = call <4 x i32> @llvm.x86.xop.vphadduwd(<8 x i16> %a0) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vphadduwd(<8 x i16>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vphadduwq(<8 x i16> %a0) { + ; CHECK: vphadduwq + %res = call <2 x i64> @llvm.x86.xop.vphadduwq(<8 x i16> %a0) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vphadduwq(<8 x i16>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vphaddwd(<8 x i16> %a0) { + ; CHECK: vphaddwd + %res = call <4 x i32> @llvm.x86.xop.vphaddwd(<8 x i16> %a0) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vphaddwd(<8 x i16>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vphaddwq(<8 x i16> %a0) { + ; CHECK: vphaddwq + %res = call <2 x i64> @llvm.x86.xop.vphaddwq(<8 x i16> %a0) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vphaddwq(<8 x i16>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vphsubbw(<16 x i8> %a0) { + ; CHECK: vphsubbw + %res = call <8 x i16> @llvm.x86.xop.vphsubbw(<16 x i8> %a0) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vphsubbw(<16 x i8>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vphsubdq(<4 x i32> %a0) { + ; CHECK: vphsubdq + %res = call <2 x i64> @llvm.x86.xop.vphsubdq(<4 x i32> %a0) ; + ret <2 x i64> %res +} +define <2 x i64> @test_int_x86_xop_vphsubdq_mem(<4 x i32>* %a0) { + ; CHECK-NOT: vmovaps + ; CHECK: vphsubdq + %vec = load <4 x i32>* %a0 + %res = call <2 x i64> @llvm.x86.xop.vphsubdq(<4 x i32> %vec) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vphsubdq(<4 x i32>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vphsubwd(<8 x i16> %a0) { + ; CHECK: vphsubwd + %res = call <4 x i32> @llvm.x86.xop.vphsubwd(<8 x i16> %a0) ; + ret <4 x i32> %res +} +define <4 x i32> @test_int_x86_xop_vphsubwd_mem(<8 x i16>* %a0) { + ; CHECK-NOT: vmovaps + ; CHECK: vphsubwd + %vec = load <8 x i16>* %a0 + %res = call <4 x i32> @llvm.x86.xop.vphsubwd(<8 x i16> %vec) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vphsubwd(<8 x i16>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpmacsdd(<4 x i32> %a0, <4 x i32> %a1, <4 x i32> %a2) { + ; CHECK: vpmacsdd + %res = call <4 x i32> @llvm.x86.xop.vpmacsdd(<4 x i32> %a0, <4 x i32> %a1, <4 x i32> %a2) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpmacsdd(<4 x i32>, <4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpmacsdqh(<4 x i32> %a0, <4 x i32> %a1, <2 x i64> %a2) { + ; CHECK: vpmacsdqh + %res = call <2 x i64> @llvm.x86.xop.vpmacsdqh(<4 x i32> %a0, <4 x i32> %a1, <2 x i64> %a2) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpmacsdqh(<4 x i32>, <4 x i32>, <2 x i64>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpmacsdql(<4 x i32> %a0, <4 x i32> %a1, <2 x i64> %a2) { + ; CHECK: vpmacsdql + %res = call <2 x i64> @llvm.x86.xop.vpmacsdql(<4 x i32> %a0, <4 x i32> %a1, <2 x i64> %a2) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpmacsdql(<4 x i32>, <4 x i32>, <2 x i64>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpmacssdd(<4 x i32> %a0, <4 x i32> %a1, <4 x i32> %a2) { + ; CHECK: vpmacssdd + %res = call <4 x i32> @llvm.x86.xop.vpmacssdd(<4 x i32> %a0, <4 x i32> %a1, <4 x i32> %a2) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpmacssdd(<4 x i32>, <4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpmacssdqh(<4 x i32> %a0, <4 x i32> %a1, <2 x i64> %a2) { + ; CHECK: vpmacssdqh + %res = call <2 x i64> @llvm.x86.xop.vpmacssdqh(<4 x i32> %a0, <4 x i32> %a1, <2 x i64> %a2) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpmacssdqh(<4 x i32>, <4 x i32>, <2 x i64>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpmacssdql(<4 x i32> %a0, <4 x i32> %a1, <2 x i64> %a2) { + ; CHECK: vpmacssdql + %res = call <2 x i64> @llvm.x86.xop.vpmacssdql(<4 x i32> %a0, <4 x i32> %a1, <2 x i64> %a2) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpmacssdql(<4 x i32>, <4 x i32>, <2 x i64>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpmacsswd(<8 x i16> %a0, <8 x i16> %a1, <4 x i32> %a2) { + ; CHECK: vpmacsswd + %res = call <4 x i32> @llvm.x86.xop.vpmacsswd(<8 x i16> %a0, <8 x i16> %a1, <4 x i32> %a2) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpmacsswd(<8 x i16>, <8 x i16>, <4 x i32>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpmacssww(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> %a2) { + ; CHECK: vpmacssww + %res = call <8 x i16> @llvm.x86.xop.vpmacssww(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> %a2) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpmacssww(<8 x i16>, <8 x i16>, <8 x i16>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpmacswd(<8 x i16> %a0, <8 x i16> %a1, <4 x i32> %a2) { + ; CHECK: vpmacswd + %res = call <4 x i32> @llvm.x86.xop.vpmacswd(<8 x i16> %a0, <8 x i16> %a1, <4 x i32> %a2) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpmacswd(<8 x i16>, <8 x i16>, <4 x i32>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpmacsww(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> %a2) { + ; CHECK: vpmacsww + %res = call <8 x i16> @llvm.x86.xop.vpmacsww(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> %a2) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpmacsww(<8 x i16>, <8 x i16>, <8 x i16>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpmadcsswd(<8 x i16> %a0, <8 x i16> %a1, <4 x i32> %a2) { + ; CHECK: vpmadcsswd + %res = call <4 x i32> @llvm.x86.xop.vpmadcsswd(<8 x i16> %a0, <8 x i16> %a1, <4 x i32> %a2) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpmadcsswd(<8 x i16>, <8 x i16>, <4 x i32>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpmadcswd(<8 x i16> %a0, <8 x i16> %a1, <4 x i32> %a2) { + ; CHECK: vpmadcswd + %res = call <4 x i32> @llvm.x86.xop.vpmadcswd(<8 x i16> %a0, <8 x i16> %a1, <4 x i32> %a2) ; + ret <4 x i32> %res +} +define <4 x i32> @test_int_x86_xop_vpmadcswd_mem(<8 x i16> %a0, <8 x i16>* %a1, <4 x i32> %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpmadcswd + %vec = load <8 x i16>* %a1 + %res = call <4 x i32> @llvm.x86.xop.vpmadcswd(<8 x i16> %a0, <8 x i16> %vec, <4 x i32> %a2) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpmadcswd(<8 x i16>, <8 x i16>, <4 x i32>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpperm(<16 x i8> %a0, <16 x i8> %a1, <16 x i8> %a2) { + ; CHECK: vpperm + %res = call <16 x i8> @llvm.x86.xop.vpperm(<16 x i8> %a0, <16 x i8> %a1, <16 x i8> %a2) ; + ret <16 x i8> %res +} +define <16 x i8> @test_int_x86_xop_vpperm_rm(<16 x i8> %a0, <16 x i8> %a1, <16 x i8>* %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpperm + %vec = load <16 x i8>* %a2 + %res = call <16 x i8> @llvm.x86.xop.vpperm(<16 x i8> %a0, <16 x i8> %a1, <16 x i8> %vec) ; + ret <16 x i8> %res +} +define <16 x i8> @test_int_x86_xop_vpperm_mr(<16 x i8> %a0, <16 x i8>* %a1, <16 x i8> %a2) { + ; CHECK-NOT: vmovaps + ; CHECK: vpperm + %vec = load <16 x i8>* %a1 + %res = call <16 x i8> @llvm.x86.xop.vpperm(<16 x i8> %a0, <16 x i8> %vec, <16 x i8> %a2) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpperm(<16 x i8>, <16 x i8>, <16 x i8>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vprotb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vprotb + %res = call <16 x i8> @llvm.x86.xop.vprotb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vprotb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vprotd(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vprotd + %res = call <4 x i32> @llvm.x86.xop.vprotd(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vprotd(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vprotq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vprotq + %res = call <2 x i64> @llvm.x86.xop.vprotq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vprotq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vprotw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vprotw + %res = call <8 x i16> @llvm.x86.xop.vprotw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vprotw(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpshab(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpshab + %res = call <16 x i8> @llvm.x86.xop.vpshab(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpshab(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpshad(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpshad + %res = call <4 x i32> @llvm.x86.xop.vpshad(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpshad(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpshaq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpshaq + %res = call <2 x i64> @llvm.x86.xop.vpshaq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpshaq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpshaw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpshaw + %res = call <8 x i16> @llvm.x86.xop.vpshaw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpshaw(<8 x i16>, <8 x i16>) nounwind readnone + +define <16 x i8> @test_int_x86_xop_vpshlb(<16 x i8> %a0, <16 x i8> %a1) { + ; CHECK: vpshlb + %res = call <16 x i8> @llvm.x86.xop.vpshlb(<16 x i8> %a0, <16 x i8> %a1) ; + ret <16 x i8> %res +} +declare <16 x i8> @llvm.x86.xop.vpshlb(<16 x i8>, <16 x i8>) nounwind readnone + +define <4 x i32> @test_int_x86_xop_vpshld(<4 x i32> %a0, <4 x i32> %a1) { + ; CHECK: vpshld + %res = call <4 x i32> @llvm.x86.xop.vpshld(<4 x i32> %a0, <4 x i32> %a1) ; + ret <4 x i32> %res +} +declare <4 x i32> @llvm.x86.xop.vpshld(<4 x i32>, <4 x i32>) nounwind readnone + +define <2 x i64> @test_int_x86_xop_vpshlq(<2 x i64> %a0, <2 x i64> %a1) { + ; CHECK: vpshlq + %res = call <2 x i64> @llvm.x86.xop.vpshlq(<2 x i64> %a0, <2 x i64> %a1) ; + ret <2 x i64> %res +} +declare <2 x i64> @llvm.x86.xop.vpshlq(<2 x i64>, <2 x i64>) nounwind readnone + +define <8 x i16> @test_int_x86_xop_vpshlw(<8 x i16> %a0, <8 x i16> %a1) { + ; CHECK: vpshlw + %res = call <8 x i16> @llvm.x86.xop.vpshlw(<8 x i16> %a0, <8 x i16> %a1) ; + ret <8 x i16> %res +} +define <8 x i16> @test_int_x86_xop_vpshlw_rm(<8 x i16> %a0, <8 x i16>* %a1) { + ; CHECK-NOT: vmovaps + ; CHECK: vpshlw + %vec = load <8 x i16>* %a1 + %res = call <8 x i16> @llvm.x86.xop.vpshlw(<8 x i16> %a0, <8 x i16> %vec) ; + ret <8 x i16> %res +} +define <8 x i16> @test_int_x86_xop_vpshlw_mr(<8 x i16>* %a0, <8 x i16> %a1) { + ; CHECK-NOT: vmovaps + ; CHECK: vpshlw + %vec = load <8 x i16>* %a0 + %res = call <8 x i16> @llvm.x86.xop.vpshlw(<8 x i16> %vec, <8 x i16> %a1) ; + ret <8 x i16> %res +} +declare <8 x i16> @llvm.x86.xop.vpshlw(<8 x i16>, <8 x i16>) nounwind readnone + +define <4 x float> @test_int_x86_xop_vfrcz_ss(<4 x float> %a0, <4 x float> %a1) { + ; CHECK-NOT: mov + ; CHECK: vfrczss + %res = call <4 x float> @llvm.x86.xop.vfrcz.ss(<4 x float> %a0, <4 x float> %a1) ; + ret <4 x float> %res +} +define <4 x float> @test_int_x86_xop_vfrcz_ss_mem(<4 x float> %a0, float* %a1) { + ; CHECK-NOT: mov + ; CHECK: vfrczss + %elem = load float* %a1 + %vec = insertelement <4 x float> undef, float %elem, i32 0 + %res = call <4 x float> @llvm.x86.xop.vfrcz.ss(<4 x float> %a0, <4 x float> %vec) ; + ret <4 x float> %res +} +declare <4 x float> @llvm.x86.xop.vfrcz.ss(<4 x float>, <4 x float>) nounwind readnone + +define <2 x double> @test_int_x86_xop_vfrcz_sd(<2 x double> %a0, <2 x double> %a1) { + ; CHECK-NOT: mov + ; CHECK: vfrczsd + %res = call <2 x double> @llvm.x86.xop.vfrcz.sd(<2 x double> %a0, <2 x double> %a1) ; + ret <2 x double> %res +} +define <2 x double> @test_int_x86_xop_vfrcz_sd_mem(<2 x double> %a0, double* %a1) { + ; CHECK-NOT: mov + ; CHECK: vfrczsd + %elem = load double* %a1 + %vec = insertelement <2 x double> undef, double %elem, i32 0 + %res = call <2 x double> @llvm.x86.xop.vfrcz.sd(<2 x double> %a0, <2 x double> %vec) ; + ret <2 x double> %res +} +declare <2 x double> @llvm.x86.xop.vfrcz.sd(<2 x double>, <2 x double>) nounwind readnone + +define <2 x double> @test_int_x86_xop_vfrcz_pd(<2 x double> %a0) { + ; CHECK: vfrczpd + %res = call <2 x double> @llvm.x86.xop.vfrcz.pd(<2 x double> %a0) ; + ret <2 x double> %res +} +define <2 x double> @test_int_x86_xop_vfrcz_pd_mem(<2 x double>* %a0) { + ; CHECK-NOT: vmovaps + ; CHECK: vfrczpd + %vec = load <2 x double>* %a0 + %res = call <2 x double> @llvm.x86.xop.vfrcz.pd(<2 x double> %vec) ; + ret <2 x double> %res +} +declare <2 x double> @llvm.x86.xop.vfrcz.pd(<2 x double>) nounwind readnone + +define <4 x double> @test_int_x86_xop_vfrcz_pd_256(<4 x double> %a0) { + ; CHECK: vfrczpd + ; CHECK: ymm + %res = call <4 x double> @llvm.x86.xop.vfrcz.pd.256(<4 x double> %a0) ; + ret <4 x double> %res +} +define <4 x double> @test_int_x86_xop_vfrcz_pd_256_mem(<4 x double>* %a0) { + ; CHECK-NOT: vmovaps + ; CHECK: vfrczpd + ; CHECK: ymm + %vec = load <4 x double>* %a0 + %res = call <4 x double> @llvm.x86.xop.vfrcz.pd.256(<4 x double> %vec) ; + ret <4 x double> %res +} +declare <4 x double> @llvm.x86.xop.vfrcz.pd.256(<4 x double>) nounwind readnone + +define <4 x float> @test_int_x86_xop_vfrcz_ps(<4 x float> %a0) { + ; CHECK: vfrczps + %res = call <4 x float> @llvm.x86.xop.vfrcz.ps(<4 x float> %a0) ; + ret <4 x float> %res +} +define <4 x float> @test_int_x86_xop_vfrcz_ps_mem(<4 x float>* %a0) { + ; CHECK-NOT: vmovaps + ; CHECK: vfrczps + %vec = load <4 x float>* %a0 + %res = call <4 x float> @llvm.x86.xop.vfrcz.ps(<4 x float> %vec) ; + ret <4 x float> %res +} +declare <4 x float> @llvm.x86.xop.vfrcz.ps(<4 x float>) nounwind readnone + +define <8 x float> @test_int_x86_xop_vfrcz_ps_256(<8 x float> %a0) { + ; CHECK: vfrczps + ; CHECK: ymm + %res = call <8 x float> @llvm.x86.xop.vfrcz.ps.256(<8 x float> %a0) ; + ret <8 x float> %res +} +define <8 x float> @test_int_x86_xop_vfrcz_ps_256_mem(<8 x float>* %a0) { + ; CHECK-NOT: vmovaps + ; CHECK: vfrczps + ; CHECK: ymm + %vec = load <8 x float>* %a0 + %res = call <8 x float> @llvm.x86.xop.vfrcz.ps.256(<8 x float> %vec) ; + ret <8 x float> %res +} +declare <8 x float> @llvm.x86.xop.vfrcz.ps.256(<8 x float>) nounwind readnone + diff --git a/test/CodeGen/X86/xor.ll b/test/CodeGen/X86/xor.ll index 178c59d..ddc4cab 100644 --- a/test/CodeGen/X86/xor.ll +++ b/test/CodeGen/X86/xor.ll @@ -8,7 +8,7 @@ define <4 x i32> @test1() nounwind { ret <4 x i32> %tmp ; X32: test1: -; X32: pxor %xmm0, %xmm0 +; X32: xorps %xmm0, %xmm0 ; X32: ret } diff --git a/test/CodeGen/X86/zero-remat.ll b/test/CodeGen/X86/zero-remat.ll index 4470074..4242530 100644 --- a/test/CodeGen/X86/zero-remat.ll +++ b/test/CodeGen/X86/zero-remat.ll @@ -16,9 +16,9 @@ define double @foo() nounwind { ;CHECK-32: ret ;CHECK-64: foo: -;CHECK-64: pxor +;CHECK-64: xorps ;CHECK-64: call -;CHECK-64: pxor +;CHECK-64: xorps ;CHECK-64: ret } @@ -33,8 +33,8 @@ define float @foof() nounwind { ;CHECK-32: ret ;CHECK-64: foof: -;CHECK-64: pxor +;CHECK-64: xorps ;CHECK-64: call -;CHECK-64: pxor +;CHECK-64: xorps ;CHECK-64: ret } diff --git a/test/CodeGen/X86/zext-fold.ll b/test/CodeGen/X86/zext-fold.ll index b3f5cdb..ff93c68 100644 --- a/test/CodeGen/X86/zext-fold.ll +++ b/test/CodeGen/X86/zext-fold.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -mcpu=generic -march=x86 | FileCheck %s ;; Simple case define i32 @test1(i8 %x) nounwind readnone { @@ -34,7 +34,7 @@ define void @test3(i8 %x) nounwind readnone { ret void } ; CHECK: test3 -; CHECK: movzbl 16(%esp), [[REGISTER:%e[a-z]{2}]] +; CHECK: movzbl {{[0-9]+}}(%esp), [[REGISTER:%e[a-z]{2}]] ; CHECK-NEXT: movl [[REGISTER]], 4(%esp) ; CHECK-NEXT: andl $224, [[REGISTER]] ; CHECK-NEXT: movl [[REGISTER]], (%esp) diff --git a/test/CodeGen/X86/zext-sext.ll b/test/CodeGen/X86/zext-sext.ll index cea9e9c..6432ae3 100644 --- a/test/CodeGen/X86/zext-sext.ll +++ b/test/CodeGen/X86/zext-sext.ll @@ -1,4 +1,5 @@ ; XFAIL: * +; ...should pass. See PR12324: misched bringup ; RUN: llc < %s -march=x86-64 | FileCheck %s ; <rdar://problem/8006248> |