Skip to content

Commit 0ce0f08

Browse files
authored
Merge branch 'llvm:main' into change-758703
2 parents afaa766 + 33a92af commit 0ce0f08

File tree

5 files changed

+96
-45
lines changed

5 files changed

+96
-45
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58844,16 +58844,18 @@ static SDValue combineConcatVectorOps(const SDLoc &DL, MVT VT,
5884458844
llvm::all_of(Ops, [](SDValue Op) {
5884558845
return Op.getConstantOperandAPInt(1) == 32;
5884658846
})) {
58847-
SDValue Res = DAG.getBitcast(MVT::v8i32, ConcatSubOperand(VT, Ops, 0));
58848-
SDValue Zero = getZeroVector(MVT::v8i32, Subtarget, DAG, DL);
58849-
if (Opcode == X86ISD::VSHLI) {
58850-
Res = DAG.getVectorShuffle(MVT::v8i32, DL, Res, Zero,
58851-
{8, 0, 8, 2, 8, 4, 8, 6});
58852-
} else {
58853-
Res = DAG.getVectorShuffle(MVT::v8i32, DL, Res, Zero,
58854-
{1, 8, 3, 8, 5, 8, 7, 8});
58847+
if (SDValue Res = CombineSubOperand(VT, Ops, 0)) {
58848+
SDValue Zero = getZeroVector(MVT::v8i32, Subtarget, DAG, DL);
58849+
Res = DAG.getBitcast(MVT::v8i32, Res);
58850+
if (Opcode == X86ISD::VSHLI) {
58851+
Res = DAG.getVectorShuffle(MVT::v8i32, DL, Res, Zero,
58852+
{8, 0, 8, 2, 8, 4, 8, 6});
58853+
} else {
58854+
Res = DAG.getVectorShuffle(MVT::v8i32, DL, Res, Zero,
58855+
{1, 8, 3, 8, 5, 8, 7, 8});
58856+
}
58857+
return DAG.getBitcast(VT, Res);
5885558858
}
58856-
return DAG.getBitcast(VT, Res);
5885758859
}
5885858860
[[fallthrough]];
5885958861
case X86ISD::VSRAI:

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,22 @@ static cl::opt<bool>
265265
cl::desc("Print name of local stack variable"),
266266
cl::Hidden, cl::init(true));
267267

268-
static cl::opt<bool> ClPoisonUndef("msan-poison-undef",
269-
cl::desc("poison undef temps"), cl::Hidden,
270-
cl::init(true));
268+
static cl::opt<bool>
269+
ClPoisonUndef("msan-poison-undef",
270+
cl::desc("Poison fully undef temporary values. "
271+
"Partially undefined constant vectors "
272+
"are unaffected by this flag (see "
273+
"-msan-poison-undef-vectors)."),
274+
cl::Hidden, cl::init(true));
275+
276+
static cl::opt<bool> ClPoisonUndefVectors(
277+
"msan-poison-undef-vectors",
278+
cl::desc("Precisely poison partially undefined constant vectors. "
279+
"If false (legacy behavior), the entire vector is "
280+
"considered fully initialized, which may lead to false "
281+
"negatives. Fully undefined constant vectors are "
282+
"unaffected by this flag (see -msan-poison-undef)."),
283+
cl::Hidden, cl::init(false));
271284

272285
static cl::opt<bool>
273286
ClHandleICmp("msan-handle-icmp",
@@ -1181,6 +1194,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
11811194
bool PropagateShadow;
11821195
bool PoisonStack;
11831196
bool PoisonUndef;
1197+
bool PoisonUndefVectors;
11841198

11851199
struct ShadowOriginAndInsertPoint {
11861200
Value *Shadow;
@@ -1207,6 +1221,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
12071221
PropagateShadow = SanitizeFunction;
12081222
PoisonStack = SanitizeFunction && ClPoisonStack;
12091223
PoisonUndef = SanitizeFunction && ClPoisonUndef;
1224+
PoisonUndefVectors = SanitizeFunction && ClPoisonUndefVectors;
12101225

12111226
// In the presence of unreachable blocks, we may see Phi nodes with
12121227
// incoming nodes from such blocks. Since InstVisitor skips unreachable
@@ -1989,6 +2004,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
19892004
}
19902005
return Shadow;
19912006
}
2007+
// Handle fully undefined values
2008+
// (partially undefined constant vectors are handled later)
19922009
if (UndefValue *U = dyn_cast<UndefValue>(V)) {
19932010
Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
19942011
: getCleanShadow(V);
@@ -2086,8 +2103,27 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
20862103
return ShadowPtr;
20872104
}
20882105

2089-
// TODO: Partially undefined vectors are handled by the fall-through case
2090-
// below (see partial-poison.ll); this causes false negatives.
2106+
// Check for partially-undefined constant vectors
2107+
// TODO: scalable vectors (this is hard because we do not have IRBuilder)
2108+
if (isa<FixedVectorType>(V->getType()) && isa<Constant>(V) &&
2109+
cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2110+
PoisonUndefVectors) {
2111+
unsigned NumElems = cast<FixedVectorType>(V->getType())->getNumElements();
2112+
SmallVector<Constant *, 32> ShadowVector(NumElems);
2113+
for (unsigned i = 0; i != NumElems; ++i) {
2114+
Constant *Elem = cast<Constant>(V)->getAggregateElement(i);
2115+
ShadowVector[i] = isa<UndefValue>(Elem) ? getPoisonedShadow(Elem)
2116+
: getCleanShadow(Elem);
2117+
}
2118+
2119+
Value *ShadowConstant = ConstantVector::get(ShadowVector);
2120+
LLVM_DEBUG(dbgs() << "Partial undef constant vector: " << *V << " ==> "
2121+
<< *ShadowConstant << "\n");
2122+
2123+
return ShadowConstant;
2124+
}
2125+
2126+
// TODO: partially-undefined constant arrays, structures, and nested types
20912127

20922128
// For everything else the shadow is zero.
20932129
return getCleanShadow(V);

llvm/test/CodeGen/X86/vector-shift-lshr-256.ll

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,11 +1974,9 @@ define <4 x i64> @shift32_v4i64(<4 x i64> %a) nounwind {
19741974
define <4 x i64> @shift32_v4i64_concat(<2 x i64> %lo, <2 x i64> %hi) nounwind {
19751975
; AVX1-LABEL: shift32_v4i64_concat:
19761976
; AVX1: # %bb.0:
1977-
; AVX1-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0
1977+
; AVX1-NEXT: vpsrlq $32, %xmm0, %xmm0
1978+
; AVX1-NEXT: vpsrlq $32, %xmm1, %xmm1
19781979
; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
1979-
; AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1
1980-
; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,3],ymm1[1,3],ymm0[5,7],ymm1[5,7]
1981-
; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2,1,3,4,6,5,7]
19821980
; AVX1-NEXT: retq
19831981
;
19841982
; AVX2-LABEL: shift32_v4i64_concat:
@@ -1990,11 +1988,9 @@ define <4 x i64> @shift32_v4i64_concat(<2 x i64> %lo, <2 x i64> %hi) nounwind {
19901988
;
19911989
; XOPAVX1-LABEL: shift32_v4i64_concat:
19921990
; XOPAVX1: # %bb.0:
1993-
; XOPAVX1-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0
1991+
; XOPAVX1-NEXT: vpsrlq $32, %xmm0, %xmm0
1992+
; XOPAVX1-NEXT: vpsrlq $32, %xmm1, %xmm1
19941993
; XOPAVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
1995-
; XOPAVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1
1996-
; XOPAVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,3],ymm1[1,3],ymm0[5,7],ymm1[5,7]
1997-
; XOPAVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2,1,3,4,6,5,7]
19981994
; XOPAVX1-NEXT: retq
19991995
;
20001996
; XOPAVX2-LABEL: shift32_v4i64_concat:
@@ -2020,11 +2016,9 @@ define <4 x i64> @shift32_v4i64_concat(<2 x i64> %lo, <2 x i64> %hi) nounwind {
20202016
;
20212017
; X86-AVX1-LABEL: shift32_v4i64_concat:
20222018
; X86-AVX1: # %bb.0:
2023-
; X86-AVX1-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0
2019+
; X86-AVX1-NEXT: vpsrlq $32, %xmm0, %xmm0
2020+
; X86-AVX1-NEXT: vpsrlq $32, %xmm1, %xmm1
20242021
; X86-AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
2025-
; X86-AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1
2026-
; X86-AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,3],ymm1[1,3],ymm0[5,7],ymm1[5,7]
2027-
; X86-AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2,1,3,4,6,5,7]
20282022
; X86-AVX1-NEXT: retl
20292023
;
20302024
; X86-AVX2-LABEL: shift32_v4i64_concat:

llvm/test/CodeGen/X86/vector-shift-shl-256.ll

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,11 +1827,9 @@ define <4 x i64> @shift32_v4i64(<4 x i64> %a) nounwind {
18271827
define <4 x i64> @shift32_v4i64_concat(<2 x i64> %lo, <2 x i64> %hi) nounwind {
18281828
; AVX1-LABEL: shift32_v4i64_concat:
18291829
; AVX1: # %bb.0:
1830-
; AVX1-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0
1830+
; AVX1-NEXT: vpsllq $32, %xmm0, %xmm0
1831+
; AVX1-NEXT: vpsllq $32, %xmm1, %xmm1
18311832
; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
1832-
; AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1
1833-
; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm1[0,2],ymm0[0,2],ymm1[4,6],ymm0[4,6]
1834-
; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2,1,3,4,6,5,7]
18351833
; AVX1-NEXT: retq
18361834
;
18371835
; AVX2-LABEL: shift32_v4i64_concat:
@@ -1843,11 +1841,9 @@ define <4 x i64> @shift32_v4i64_concat(<2 x i64> %lo, <2 x i64> %hi) nounwind {
18431841
;
18441842
; XOPAVX1-LABEL: shift32_v4i64_concat:
18451843
; XOPAVX1: # %bb.0:
1846-
; XOPAVX1-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0
1844+
; XOPAVX1-NEXT: vpsllq $32, %xmm0, %xmm0
1845+
; XOPAVX1-NEXT: vpsllq $32, %xmm1, %xmm1
18471846
; XOPAVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
1848-
; XOPAVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1
1849-
; XOPAVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm1[0,2],ymm0[0,2],ymm1[4,6],ymm0[4,6]
1850-
; XOPAVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2,1,3,4,6,5,7]
18511847
; XOPAVX1-NEXT: retq
18521848
;
18531849
; XOPAVX2-LABEL: shift32_v4i64_concat:
@@ -1873,11 +1869,9 @@ define <4 x i64> @shift32_v4i64_concat(<2 x i64> %lo, <2 x i64> %hi) nounwind {
18731869
;
18741870
; X86-AVX1-LABEL: shift32_v4i64_concat:
18751871
; X86-AVX1: # %bb.0:
1876-
; X86-AVX1-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0
1872+
; X86-AVX1-NEXT: vpsllq $32, %xmm0, %xmm0
1873+
; X86-AVX1-NEXT: vpsllq $32, %xmm1, %xmm1
18771874
; X86-AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
1878-
; X86-AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1
1879-
; X86-AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm1[0,2],ymm0[0,2],ymm1[4,6],ymm0[4,6]
1880-
; X86-AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2,1,3,4,6,5,7]
18811875
; X86-AVX1-NEXT: retl
18821876
;
18831877
; X86-AVX2-LABEL: shift32_v4i64_concat:

llvm/test/Instrumentation/MemorySanitizer/partial-poison.ll

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2-
; RUN: opt < %s -S -passes='msan' 2>&1 | FileCheck %s
2+
; RUN: opt < %s -S -passes='msan' -msan-poison-undef-vectors=true 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PRECISE
3+
; RUN: opt < %s -S -passes='msan' -msan-poison-undef-vectors=false 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-IMPRECISE
34
;
4-
; Test case to show that MSan computes shadows for partially poisoned vectors
5-
; as fully initialized, resulting in false negatives.
5+
; Regression test case for computing shadows of partially poisoned vectors.
6+
; Partially poisoned structs and arrays are not correctly implemented.
67

78
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"
89
target triple = "x86_64-unknown-linux-gnu"
@@ -11,7 +12,8 @@ define <2 x i64> @left_poison(ptr %add.ptr) sanitize_memory {
1112
; CHECK-LABEL: define <2 x i64> @left_poison(
1213
; CHECK-SAME: ptr [[ADD_PTR:%.*]]) #[[ATTR0:[0-9]+]] {
1314
; CHECK-NEXT: call void @llvm.donothing()
14-
; CHECK-NEXT: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8
15+
; CHECK-PRECISE: store <2 x i64> <i64 -1, i64 0>, ptr @__msan_retval_tls, align 8
16+
; CHECK-IMPRECISE: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8
1517
; CHECK-NEXT: ret <2 x i64> <i64 poison, i64 42>
1618
;
1719
ret <2 x i64> <i64 poison, i64 42>
@@ -21,7 +23,8 @@ define <2 x i64> @right_poison(ptr %add.ptr) sanitize_memory {
2123
; CHECK-LABEL: define <2 x i64> @right_poison(
2224
; CHECK-SAME: ptr [[ADD_PTR:%.*]]) #[[ATTR0]] {
2325
; CHECK-NEXT: call void @llvm.donothing()
24-
; CHECK-NEXT: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8
26+
; CHECK-PRECISE: store <2 x i64> <i64 0, i64 -1>, ptr @__msan_retval_tls, align 8
27+
; CHECK-IMPRECISE: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8
2528
; CHECK-NEXT: ret <2 x i64> <i64 42, i64 poison>
2629
;
2730
ret <2 x i64> <i64 42, i64 poison>
@@ -51,7 +54,8 @@ define <2 x i64> @left_undef(ptr %add.ptr) sanitize_memory {
5154
; CHECK-LABEL: define <2 x i64> @left_undef(
5255
; CHECK-SAME: ptr [[ADD_PTR:%.*]]) #[[ATTR0]] {
5356
; CHECK-NEXT: call void @llvm.donothing()
54-
; CHECK-NEXT: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8
57+
; CHECK-PRECISE: store <2 x i64> <i64 -1, i64 0>, ptr @__msan_retval_tls, align 8
58+
; CHECK-IMPRECISE: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8
5559
; CHECK-NEXT: ret <2 x i64> <i64 undef, i64 42>
5660
;
5761
ret <2 x i64> <i64 undef, i64 42>
@@ -61,7 +65,8 @@ define <2 x i64> @right_undef(ptr %add.ptr) sanitize_memory {
6165
; CHECK-LABEL: define <2 x i64> @right_undef(
6266
; CHECK-SAME: ptr [[ADD_PTR:%.*]]) #[[ATTR0]] {
6367
; CHECK-NEXT: call void @llvm.donothing()
64-
; CHECK-NEXT: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8
68+
; CHECK-PRECISE: store <2 x i64> <i64 0, i64 -1>, ptr @__msan_retval_tls, align 8
69+
; CHECK-IMPRECISE: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8
6570
; CHECK-NEXT: ret <2 x i64> <i64 42, i64 undef>
6671
;
6772
ret <2 x i64> <i64 42, i64 undef>
@@ -76,3 +81,23 @@ define <2 x i64> @full_undef(ptr %add.ptr) sanitize_memory {
7681
;
7782
ret <2 x i64> <i64 undef, i64 undef>
7883
}
84+
85+
define {i64, i64} @struct_left_undef() sanitize_memory {
86+
; CHECK-LABEL: define { i64, i64 } @struct_left_undef(
87+
; CHECK-SAME: ) #[[ATTR0]] {
88+
; CHECK-NEXT: call void @llvm.donothing()
89+
; CHECK-NEXT: store { i64, i64 } zeroinitializer, ptr @__msan_retval_tls, align 8
90+
; CHECK-NEXT: ret { i64, i64 } { i64 undef, i64 42 }
91+
;
92+
ret {i64, i64} { i64 undef, i64 42 }
93+
}
94+
95+
define [2x i64] @array_right_undef() sanitize_memory {
96+
; CHECK-LABEL: define [2 x i64] @array_right_undef(
97+
; CHECK-SAME: ) #[[ATTR0]] {
98+
; CHECK-NEXT: call void @llvm.donothing()
99+
; CHECK-NEXT: store [2 x i64] zeroinitializer, ptr @__msan_retval_tls, align 8
100+
; CHECK-NEXT: ret [2 x i64] [i64 42, i64 undef]
101+
;
102+
ret [2x i64] [ i64 42, i64 undef ]
103+
}

0 commit comments

Comments
 (0)