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