1; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s 2 3; Test instrumentation of vector shift instructions. 4 5target 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" 6target triple = "x86_64-unknown-linux-gnu" 7 8declare x86_mmx @llvm.x86.mmx.psll.d(x86_mmx, x86_mmx) 9declare <16 x i32> @llvm.x86.avx512.psllv.d.512(<16 x i32>, <16 x i32>) 10declare <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32>, <8 x i32>) 11declare <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32>, <4 x i32>) 12declare <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16>, <8 x i16>) 13declare <32 x i16> @llvm.x86.avx512.psrl.w.512(<32 x i16>, <8 x i16>) 14declare <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16>, i32) 15declare <32 x i16> @llvm.x86.avx512.pslli.w.512(<32 x i16>, i32) 16 17define i64 @test_mmx(i64 %x.coerce, i64 %y.coerce) sanitize_memory { 18entry: 19 %0 = bitcast i64 %x.coerce to <2 x i32> 20 %1 = bitcast <2 x i32> %0 to x86_mmx 21 %2 = bitcast i64 %y.coerce to x86_mmx 22 %3 = tail call x86_mmx @llvm.x86.mmx.psll.d(x86_mmx %1, x86_mmx %2) 23 %4 = bitcast x86_mmx %3 to <2 x i32> 24 %5 = bitcast <2 x i32> %4 to <1 x i64> 25 %6 = extractelement <1 x i64> %5, i32 0 26 ret i64 %6 27} 28 29; CHECK-LABEL: @test_mmx 30; CHECK: = icmp ne i64 {{.*}}, 0 31; CHECK: [[C:%.*]] = sext i1 {{.*}} to i64 32; CHECK: [[A:%.*]] = call x86_mmx @llvm.x86.mmx.psll.d( 33; CHECK: [[B:%.*]] = bitcast x86_mmx {{.*}}[[A]] to i64 34; CHECK: = or i64 {{.*}}[[B]], {{.*}}[[C]] 35; CHECK: call x86_mmx @llvm.x86.mmx.psll.d( 36; CHECK: ret i64 37 38 39define <8 x i16> @test_sse2_scalar(<8 x i16> %x, i32 %y) sanitize_memory { 40entry: 41 %0 = tail call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> %x, i32 %y) 42 ret <8 x i16> %0 43} 44 45; CHECK-LABEL: @test_sse2_scalar 46; CHECK: = icmp ne i32 {{.*}}, 0 47; CHECK: = sext i1 {{.*}} to i128 48; CHECK: = bitcast i128 {{.*}} to <8 x i16> 49; CHECK: = call <8 x i16> @llvm.x86.sse2.pslli.w( 50; CHECK: = or <8 x i16> 51; CHECK: call <8 x i16> @llvm.x86.sse2.pslli.w( 52; CHECK: ret <8 x i16> 53 54 55define <32 x i16> @test_avx512_scalar(<32 x i16> %x, i32 %y) sanitize_memory { 56entry: 57 %0 = tail call <32 x i16> @llvm.x86.avx512.pslli.w.512(<32 x i16> %x, i32 %y) 58 ret <32 x i16> %0 59} 60 61; CHECK-LABEL: @test_avx512_scalar 62; CHECK: = icmp ne i32 {{.*}}, 0 63; CHECK: = sext i1 {{.*}} to i512 64; CHECK: = bitcast i512 {{.*}} to <32 x i16> 65; CHECK: = call <32 x i16> @llvm.x86.avx512.pslli.w.512( 66; CHECK: = or <32 x i16> 67; CHECK: call <32 x i16> @llvm.x86.avx512.pslli.w.512( 68; CHECK: ret <32 x i16> 69 70 71define <8 x i16> @test_sse2(<8 x i16> %x, <8 x i16> %y) sanitize_memory { 72entry: 73 %0 = tail call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> %x, <8 x i16> %y) 74 ret <8 x i16> %0 75} 76 77; CHECK-LABEL: @test_sse2 78; CHECK: = bitcast <8 x i16> {{.*}} to i128 79; CHECK: = trunc i128 {{.*}} to i64 80; CHECK: = icmp ne i64 {{.*}}, 0 81; CHECK: = sext i1 {{.*}} to i128 82; CHECK: = bitcast i128 {{.*}} to <8 x i16> 83; CHECK: = call <8 x i16> @llvm.x86.sse2.psrl.w( 84; CHECK: = or <8 x i16> 85; CHECK: call <8 x i16> @llvm.x86.sse2.psrl.w( 86; CHECK: ret <8 x i16> 87 88 89define <32 x i16> @test_avx512(<32 x i16> %x, <8 x i16> %y) sanitize_memory { 90entry: 91 %0 = tail call <32 x i16> @llvm.x86.avx512.psrl.w.512(<32 x i16> %x, <8 x i16> %y) 92 ret <32 x i16> %0 93} 94 95; CHECK-LABEL: @test_avx512 96; CHECK: = bitcast <8 x i16> {{.*}} to i128 97; CHECK: = trunc i128 {{.*}} to i64 98; CHECK: = icmp ne i64 {{.*}}, 0 99; CHECK: = sext i1 {{.*}} to i512 100; CHECK: = bitcast i512 {{.*}} to <32 x i16> 101; CHECK: = call <32 x i16> @llvm.x86.avx512.psrl.w.512( 102; CHECK: = or <32 x i16> 103; CHECK: call <32 x i16> @llvm.x86.avx512.psrl.w.512( 104; CHECK: ret <32 x i16> 105 106 107; Test variable shift (i.e. vector by vector). 108 109define <4 x i32> @test_avx2(<4 x i32> %x, <4 x i32> %y) sanitize_memory { 110entry: 111 %0 = tail call <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32> %x, <4 x i32> %y) 112 ret <4 x i32> %0 113} 114 115; CHECK-LABEL: @test_avx2 116; CHECK: = icmp ne <4 x i32> {{.*}}, zeroinitializer 117; CHECK: = sext <4 x i1> {{.*}} to <4 x i32> 118; CHECK: = call <4 x i32> @llvm.x86.avx2.psllv.d( 119; CHECK: = or <4 x i32> 120; CHECK: = tail call <4 x i32> @llvm.x86.avx2.psllv.d( 121; CHECK: ret <4 x i32> 122 123define <8 x i32> @test_avx2_256(<8 x i32> %x, <8 x i32> %y) sanitize_memory { 124entry: 125 %0 = tail call <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32> %x, <8 x i32> %y) 126 ret <8 x i32> %0 127} 128 129; CHECK-LABEL: @test_avx2_256 130; CHECK: = icmp ne <8 x i32> {{.*}}, zeroinitializer 131; CHECK: = sext <8 x i1> {{.*}} to <8 x i32> 132; CHECK: = call <8 x i32> @llvm.x86.avx2.psllv.d.256( 133; CHECK: = or <8 x i32> 134; CHECK: = tail call <8 x i32> @llvm.x86.avx2.psllv.d.256( 135; CHECK: ret <8 x i32> 136 137define <16 x i32> @test_avx512_512(<16 x i32> %x, <16 x i32> %y) sanitize_memory { 138entry: 139 %0 = tail call <16 x i32> @llvm.x86.avx512.psllv.d.512(<16 x i32> %x, <16 x i32> %y) 140 ret <16 x i32> %0 141} 142 143; CHECK-LABEL: @test_avx512_512 144; CHECK: = icmp ne <16 x i32> {{.*}}, zeroinitializer 145; CHECK: = sext <16 x i1> {{.*}} to <16 x i32> 146; CHECK: = call <16 x i32> @llvm.x86.avx512.psllv.d.512( 147; CHECK: = or <16 x i32> 148; CHECK: = tail call <16 x i32> @llvm.x86.avx512.psllv.d.512( 149; CHECK: ret <16 x i32> 150