diff options
| author | Vitaly Buka <vitalybuka@google.com> | 2024-06-10 13:03:22 -0700 |
|---|---|---|
| committer | Vitaly Buka <vitalybuka@google.com> | 2024-06-10 13:03:22 -0700 |
| commit | 2379c2ce5857433661e036f81126986808c6135a (patch) | |
| tree | 3ab16747c3f74e475ffe923af77c4d7dd9391546 | |
| parent | 9eb64cc52506fe1ccaa4ceff4636a32d22bc6ddb (diff) | |
| parent | 2cddf72042818a03a4d1dfd2b19ae642dc7a2c90 (diff) | |
[𝘀𝗽𝗿] changes introduced through rebaseusers/vitalybuka/spr/main.nfcmsan-prepare-function-to-extract-main-logic
Created using spr 1.3.4
[skip ci]
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 19 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp | 18 | ||||
| -rw-r--r-- | llvm/include/llvm/MC/MCContext.h | 27 | ||||
| -rw-r--r-- | llvm/lib/MC/MCContext.cpp | 47 | ||||
| -rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 78 | ||||
| -rw-r--r-- | llvm/test/Instrumentation/MemorySanitizer/X86/avx-intrinsics-x86.ll | 23 | ||||
| -rw-r--r-- | llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll | 38 |
9 files changed, 112 insertions, 145 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 75b144909038..dd4a665ebc78 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4512,6 +4512,19 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { return Resolver; } +bool CodeGenModule::shouldDropDLLAttribute(const Decl *D, + const llvm::GlobalValue *GV) const { + auto SC = GV->getDLLStorageClass(); + if (SC == llvm::GlobalValue::DefaultStorageClass) + return false; + const Decl *MRD = D->getMostRecentDecl(); + return (((SC == llvm::GlobalValue::DLLImportStorageClass && + !MRD->hasAttr<DLLImportAttr>()) || + (SC == llvm::GlobalValue::DLLExportStorageClass && + !MRD->hasAttr<DLLExportAttr>())) && + !shouldMapVisibilityToDLLExport(cast<NamedDecl>(MRD))); +} + /// GetOrCreateLLVMFunction - If the specified mangled name is not in the /// module, create and return an llvm Function with the specified type. If there /// is something in the module with the specified name, return it potentially @@ -4564,8 +4577,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( } // Handle dropped DLL attributes. - if (D && !D->hasAttr<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>() && - !shouldMapVisibilityToDLLExport(cast_or_null<NamedDecl>(D))) { + if (D && shouldDropDLLAttribute(D, Entry)) { Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); setDSOLocal(Entry); } @@ -4859,8 +4871,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, } // Handle dropped DLL attributes. - if (D && !D->hasAttr<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>() && - !shouldMapVisibilityToDLLExport(D)) + if (D && shouldDropDLLAttribute(D, Entry)) Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); if (LangOpts.OpenMP && !LangOpts.OpenMPSimd && D) diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index dc24971a3c18..9b63f47ef42c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1594,6 +1594,8 @@ public: } private: + bool shouldDropDLLAttribute(const Decl *D, const llvm::GlobalValue *GV) const; + llvm::Constant *GetOrCreateLLVMFunction( StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, bool DontDefer = false, bool IsThunk = false, diff --git a/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp b/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp new file mode 100644 index 000000000000..97f341ba1f90 --- /dev/null +++ b/clang/test/CodeGenCXX/windows-instantiate-dllexport-template-specialization.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple i686-windows -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MS +// RUN: %clang_cc1 -triple i686-windows-itanium -fdeclspec -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fdeclspec -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fdeclspec -emit-llvm %s -o - | FileCheck %s + +struct s { + template <bool b = true> static bool f(); +}; + +template <typename T> bool template_using_f(T) { return s::f(); } + +bool use_template_using_f() { return template_using_f(0); } + +template<> +bool __declspec(dllexport) s::f<true>() { return true; } + +// CHECK-MS: dllexport {{.*}} @"??$f@$00@s@@SA_NXZ" +// CHECK: dllexport {{.*}} @_ZN1s1fILb1EEEbv diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index b0ac432a065b..b2a52b4297e6 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -252,31 +252,6 @@ private: /// A collection of MCPseudoProbe in the current module MCPseudoProbeTable PseudoProbeTable; - // Sections are differentiated by the quadruple (section_name, group_name, - // unique_id, link_to_symbol_name). Sections sharing the same quadruple are - // combined into one section. - struct ELFSectionKey { - std::string SectionName; - StringRef GroupName; - StringRef LinkedToName; - unsigned UniqueID; - - ELFSectionKey(StringRef SectionName, StringRef GroupName, - StringRef LinkedToName, unsigned UniqueID) - : SectionName(SectionName), GroupName(GroupName), - LinkedToName(LinkedToName), UniqueID(UniqueID) {} - - bool operator<(const ELFSectionKey &Other) const { - if (SectionName != Other.SectionName) - return SectionName < Other.SectionName; - if (GroupName != Other.GroupName) - return GroupName < Other.GroupName; - if (int O = LinkedToName.compare(Other.LinkedToName)) - return O < 0; - return UniqueID < Other.UniqueID; - } - }; - struct COFFSectionKey { std::string SectionName; StringRef GroupName; @@ -350,8 +325,8 @@ private: }; StringMap<MCSectionMachO *> MachOUniquingMap; - std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap; std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap; + StringMap<MCSectionELF *> ELFUniquingMap; std::map<std::string, MCSectionGOFF *> GOFFUniquingMap; std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap; std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap; diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 771ca9c6006c..d5bde2bcb730 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -44,6 +44,7 @@ #include "llvm/MC/SectionKind.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/EndianStream.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -548,16 +549,42 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, if (GroupSym) Group = GroupSym->getName(); assert(!(LinkedToSym && LinkedToSym->getName().empty())); - // Do the lookup, if we have a hit, return it. - auto IterBool = ELFUniquingMap.insert(std::make_pair( - ELFSectionKey{Section.str(), Group, - LinkedToSym ? LinkedToSym->getName() : "", UniqueID}, - nullptr)); - auto &Entry = *IterBool.first; - if (!IterBool.second) - return Entry.second; - StringRef CachedName = Entry.first.SectionName; + // Sections are differentiated by the quadruple (section_name, group_name, + // unique_id, link_to_symbol_name). Sections sharing the same quadruple are + // combined into one section. As an optimization, non-unique sections without + // group or linked-to symbol have a shorter unique-ing key. + std::pair<StringMap<MCSectionELF *>::iterator, bool> EntryNewPair; + // Length of the section name, which are the first SectionLen bytes of the key + unsigned SectionLen; + if (GroupSym || LinkedToSym || UniqueID != MCSection::NonUniqueID) { + SmallString<128> Buffer; + Section.toVector(Buffer); + SectionLen = Buffer.size(); + Buffer.push_back(0); // separator which cannot occur in the name + if (GroupSym) + Buffer.append(GroupSym->getName()); + Buffer.push_back(0); // separator which cannot occur in the name + if (LinkedToSym) + Buffer.append(LinkedToSym->getName()); + support::endian::write(Buffer, UniqueID, endianness::native); + StringRef UniqueMapKey = StringRef(Buffer); + EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); + } else if (!Section.isSingleStringRef()) { + SmallString<128> Buffer; + SectionLen = Buffer.size(); + StringRef UniqueMapKey = Section.toStringRef(Buffer); + EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); + } else { + SectionLen = Section.getSingleStringRef().size(); + StringRef UniqueMapKey = Section.getSingleStringRef(); + EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); + } + + if (!EntryNewPair.second) + return EntryNewPair.first->second; + + StringRef CachedName = EntryNewPair.first->getKey().take_front(SectionLen); SectionKind Kind; if (Flags & ELF::SHF_ARM_PURECODE) @@ -601,7 +628,7 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, MCSectionELF *Result = createELFSectionImpl(CachedName, Type, Flags, Kind, EntrySize, GroupSym, IsComdat, UniqueID, LinkedToSym); - Entry.second = Result; + EntryNewPair.first->second = Result; recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(), Result->getUniqueID(), Result->getEntrySize()); diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 0ccade91677a..8d3873bed9ef 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -175,8 +175,11 @@ void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, } void MCObjectStreamer::reset() { - if (Assembler) + if (Assembler) { Assembler->reset(); + if (getContext().getTargetOptions()) + Assembler->setRelaxAll(getContext().getTargetOptions()->MCRelaxAll); + } CurInsertionPoint = MCSection::iterator(); EmitEHFrame = true; EmitDebugFrame = false; diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 43b2dee4572a..b352558a1c0d 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -3287,76 +3287,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { setOriginForNaryOp(I); } - // Convert `Mask` into `<n x i1>`. - Constant *createDppMask(unsigned Width, unsigned Mask) { - SmallVector<Constant *, 4> R; - R.assign(Width, ConstantInt::getFalse(F.getContext())); - for (auto &M : R) { - if (Mask & 1) - M = ConstantInt::getTrue(F.getContext()); - Mask >>= 1; - } - return ConstantVector::get(R); - } - - // Calculate output shadow as array of booleans `<n x i1>`, assuming if any - // arg is poisoned, entire dot product is poisoned. - Value *makeDppShadowI1(IRBuilder<> &IRB, Value *S, unsigned SrcMask, - unsigned DstMask) { - const unsigned Width = - cast<FixedVectorType>(S->getType())->getNumElements(); - - S = IRB.CreateSelect(createDppMask(Width, SrcMask), S, - Constant::getNullValue(S->getType())); - Value *SElem = IRB.CreateOrReduce(S); - Value *IsClean = IRB.CreateIsNull(SElem, "_msdpp"); - Value *DstMaskV = createDppMask(Width, DstMask); - - return IRB.CreateSelect( - IsClean, Constant::getNullValue(DstMaskV->getType()), DstMaskV); - } - - // See `Intel Intrinsics Guide` for `_dp_p*` instructions. - // - // 2 and 4 element versions produce single scalar of dot product, and then - // puts it into elements of output vector, selected by 4 lowest bits of the - // mask. Top 4 bits of the mask control which elements of input to use for dot - // product. - // - // 8 element version mask still has only 4 bit for input, and 4 bit for output - // mask. According to the spec it just operates as 4 element version on first - // 4 elements of inputs and output, and then on last 4 elements of inputs and - // output. - void handleDppIntrinsic(IntrinsicInst &I) { - IRBuilder<> IRB(&I); - - Value *S0 = getShadow(&I, 0); - Value *S1 = getShadow(&I, 1); - Value *S = IRB.CreateOr(S0, S1); - - const unsigned Width = - cast<FixedVectorType>(S->getType())->getNumElements(); - assert(Width == 2 || Width == 4 || Width == 8); - - const unsigned Mask = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue(); - const unsigned SrcMask = Mask >> 4; - const unsigned DstMask = Mask & 0xf; - - // Calculate shadow as `<n x i1>`. - Value *SI1 = makeDppShadowI1(IRB, S, SrcMask, DstMask); - if (Width == 8) { - // First 4 elements of shadow are already calculated. `makeDppShadow` - // operats on 32 bit masks, so we can just shift masks, and repeat. - SI1 = IRB.CreateOr(SI1, - makeDppShadowI1(IRB, S, SrcMask << 4, DstMask << 4)); - } - // Extend to real size of shadow, poisoning all no none bits of an element. - S = IRB.CreateSExt(SI1, S->getType(), "_msdpp"); - - setShadow(&I, S); - setOriginForNaryOp(I); - } - // Instrument sum-of-absolute-differences intrinsic. void handleVectorSadIntrinsic(IntrinsicInst &I) { const unsigned SignificantBitsPerResultElement = 16; @@ -3712,7 +3642,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { setOriginForNaryOp(I); } - static SmallVector<int, 8> getPclmulMask(unsigned Width, bool OddElements) { + SmallVector<int, 8> getPclmulMask(unsigned Width, bool OddElements) { SmallVector<int, 8> Mask; for (unsigned X = OddElements ? 1 : 0; X < Width; X += 2) { Mask.append(2, X); @@ -4028,12 +3958,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { handleVectorPackIntrinsic(I); break; - case Intrinsic::x86_avx_dp_ps_256: - case Intrinsic::x86_sse41_dppd: - case Intrinsic::x86_sse41_dpps: - handleDppIntrinsic(I); - break; - case Intrinsic::x86_mmx_packsswb: case Intrinsic::x86_mmx_packuswb: handleVectorPackIntrinsic(I, 16); diff --git a/llvm/test/Instrumentation/MemorySanitizer/X86/avx-intrinsics-x86.ll b/llvm/test/Instrumentation/MemorySanitizer/X86/avx-intrinsics-x86.ll index d031e049ebdb..bc61970ecc4b 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/X86/avx-intrinsics-x86.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/X86/avx-intrinsics-x86.ll @@ -389,19 +389,18 @@ define <8 x float> @test_x86_avx_dp_ps_256(<8 x float> %a0, <8 x float> %a1) #0 ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, ptr @__msan_param_tls, align 8 ; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i32>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 32) to ptr), align 8 ; CHECK-NEXT: call void @llvm.donothing() -; CHECK-NEXT: [[TMP3:%.*]] = or <8 x i32> [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = select <8 x i1> <i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false>, <8 x i32> [[TMP3]], <8 x i32> zeroinitializer -; CHECK-NEXT: [[TMP5:%.*]] = call i32 @llvm.vector.reduce.or.v8i32(<8 x i32> [[TMP4]]) -; CHECK-NEXT: [[_MSDPP:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[_MSDPP]], <8 x i1> zeroinitializer, <8 x i1> <i1 false, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false> -; CHECK-NEXT: [[TMP7:%.*]] = select <8 x i1> <i1 false, i1 false, i1 false, i1 false, i1 false, i1 true, i1 true, i1 true>, <8 x i32> [[TMP3]], <8 x i32> zeroinitializer -; CHECK-NEXT: [[TMP8:%.*]] = call i32 @llvm.vector.reduce.or.v8i32(<8 x i32> [[TMP7]]) -; CHECK-NEXT: [[_MSDPP1:%.*]] = icmp eq i32 [[TMP8]], 0 -; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[_MSDPP1]], <8 x i1> zeroinitializer, <8 x i1> <i1 false, i1 false, i1 false, i1 false, i1 false, i1 true, i1 true, i1 true> -; CHECK-NEXT: [[TMP10:%.*]] = or <8 x i1> [[TMP6]], [[TMP9]] -; CHECK-NEXT: [[_MSDPP2:%.*]] = sext <8 x i1> [[TMP10]] to <8 x i32> +; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i32> [[TMP1]] to i256 +; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i256 [[TMP3]], 0 +; CHECK-NEXT: [[TMP4:%.*]] = bitcast <8 x i32> [[TMP2]] to i256 +; CHECK-NEXT: [[_MSCMP1:%.*]] = icmp ne i256 [[TMP4]], 0 +; CHECK-NEXT: [[_MSOR:%.*]] = or i1 [[_MSCMP]], [[_MSCMP1]] +; CHECK-NEXT: br i1 [[_MSOR]], label [[TMP5:%.*]], label [[TMP6:%.*]], !prof [[PROF0]] +; CHECK: 5: +; CHECK-NEXT: call void @__msan_warning_noreturn() +; CHECK-NEXT: unreachable +; CHECK: 6: ; CHECK-NEXT: [[RES:%.*]] = call <8 x float> @llvm.x86.avx.dp.ps.256(<8 x float> [[A0:%.*]], <8 x float> [[A1:%.*]], i8 -18) -; CHECK-NEXT: store <8 x i32> [[_MSDPP2]], ptr @__msan_retval_tls, align 8 +; CHECK-NEXT: store <8 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8 ; CHECK-NEXT: ret <8 x float> [[RES]] ; %res = call <8 x float> @llvm.x86.avx.dp.ps.256(<8 x float> %a0, <8 x float> %a1, i8 -18) ; <<8 x float>> [#uses=1] diff --git a/llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll b/llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll index e6775cf3eae6..36f837507833 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/X86/sse41-intrinsics-x86.ll @@ -45,14 +45,18 @@ define <2 x double> @test_x86_sse41_dppd(<2 x double> %a0, <2 x double> %a1) #0 ; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8 ; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8 ; CHECK-NEXT: call void @llvm.donothing() -; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = select <2 x i1> <i1 false, i1 true>, <2 x i64> [[TMP3]], <2 x i64> zeroinitializer -; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vector.reduce.or.v2i64(<2 x i64> [[TMP4]]) -; CHECK-NEXT: [[_MSDPP:%.*]] = icmp eq i64 [[TMP5]], 0 -; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[_MSDPP]], <2 x i1> zeroinitializer, <2 x i1> <i1 false, i1 true> -; CHECK-NEXT: [[_MSDPP1:%.*]] = sext <2 x i1> [[TMP6]] to <2 x i64> +; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP1]] to i128 +; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i128 [[TMP3]], 0 +; CHECK-NEXT: [[TMP4:%.*]] = bitcast <2 x i64> [[TMP2]] to i128 +; CHECK-NEXT: [[_MSCMP1:%.*]] = icmp ne i128 [[TMP4]], 0 +; CHECK-NEXT: [[_MSOR:%.*]] = or i1 [[_MSCMP]], [[_MSCMP1]] +; CHECK-NEXT: br i1 [[_MSOR]], label [[TMP5:%.*]], label [[TMP6:%.*]], !prof [[PROF0:![0-9]+]] +; CHECK: 5: +; CHECK-NEXT: call void @__msan_warning_noreturn() +; CHECK-NEXT: unreachable +; CHECK: 6: ; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse41.dppd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]], i8 -18) -; CHECK-NEXT: store <2 x i64> [[_MSDPP1]], ptr @__msan_retval_tls, align 8 +; CHECK-NEXT: store <2 x i64> zeroinitializer, ptr @__msan_retval_tls, align 8 ; CHECK-NEXT: ret <2 x double> [[RES]] ; %res = call <2 x double> @llvm.x86.sse41.dppd(<2 x double> %a0, <2 x double> %a1, i8 -18) ; <<2 x double>> [#uses=1] @@ -66,14 +70,18 @@ define <4 x float> @test_x86_sse41_dpps(<4 x float> %a0, <4 x float> %a1) #0 { ; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8 ; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8 ; CHECK-NEXT: call void @llvm.donothing() -; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x i32> [[TMP3]], <4 x i32> zeroinitializer -; CHECK-NEXT: [[TMP5:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP4]]) -; CHECK-NEXT: [[_MSDPP:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[_MSDPP]], <4 x i1> zeroinitializer, <4 x i1> <i1 false, i1 true, i1 true, i1 true> -; CHECK-NEXT: [[_MSDPP1:%.*]] = sext <4 x i1> [[TMP6]] to <4 x i32> +; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP1]] to i128 +; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i128 [[TMP3]], 0 +; CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 +; CHECK-NEXT: [[_MSCMP1:%.*]] = icmp ne i128 [[TMP4]], 0 +; CHECK-NEXT: [[_MSOR:%.*]] = or i1 [[_MSCMP]], [[_MSCMP1]] +; CHECK-NEXT: br i1 [[_MSOR]], label [[TMP5:%.*]], label [[TMP6:%.*]], !prof [[PROF0]] +; CHECK: 5: +; CHECK-NEXT: call void @__msan_warning_noreturn() +; CHECK-NEXT: unreachable +; CHECK: 6: ; CHECK-NEXT: [[RES:%.*]] = call <4 x float> @llvm.x86.sse41.dpps(<4 x float> [[A0:%.*]], <4 x float> [[A1:%.*]], i8 -18) -; CHECK-NEXT: store <4 x i32> [[_MSDPP1]], ptr @__msan_retval_tls, align 8 +; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr @__msan_retval_tls, align 8 ; CHECK-NEXT: ret <4 x float> [[RES]] ; %res = call <4 x float> @llvm.x86.sse41.dpps(<4 x float> %a0, <4 x float> %a1, i8 -18) ; <<4 x float>> [#uses=1] @@ -92,7 +100,7 @@ define <4 x float> @test_x86_sse41_insertps(<4 x float> %a0, <4 x float> %a1) #0 ; CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP2]] to i128 ; CHECK-NEXT: [[_MSCMP1:%.*]] = icmp ne i128 [[TMP4]], 0 ; CHECK-NEXT: [[_MSOR:%.*]] = or i1 [[_MSCMP]], [[_MSCMP1]] -; CHECK-NEXT: br i1 [[_MSOR]], label [[TMP5:%.*]], label [[TMP6:%.*]], !prof [[PROF0:![0-9]+]] +; CHECK-NEXT: br i1 [[_MSOR]], label [[TMP5:%.*]], label [[TMP6:%.*]], !prof [[PROF0]] ; CHECK: 5: ; CHECK-NEXT: call void @__msan_warning_noreturn() ; CHECK-NEXT: unreachable |
