[llvm-branch-commits] [llvm] b8cb180 - [obj2yaml] - Dump the content of a broken GNU hash table properly.
Author: Georgii Rymar Date: 2020-12-24T11:16:31+03:00 New Revision: b8cb1802a8a2037bd893e038b4eafa61bd5c279e URL: https://github.com/llvm/llvm-project/commit/b8cb1802a8a2037bd893e038b4eafa61bd5c279e DIFF: https://github.com/llvm/llvm-project/commit/b8cb1802a8a2037bd893e038b4eafa61bd5c279e.diff LOG: [obj2yaml] - Dump the content of a broken GNU hash table properly. When something is wrong with the GNU hash table header we dump its context as a raw data. Currently we have the calculation overflow issue and it is possible to bypass the validation we have (and crash). The patch fixes it. Differential revision: https://reviews.llvm.org/D93760 Added: Modified: llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml llvm/tools/obj2yaml/elf2yaml.cpp Removed: diff --git a/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml b/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml index 7dd0a7c870ea..00861c013100 100644 --- a/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml +++ b/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml @@ -54,9 +54,12 @@ Sections: # INVALID-NEXT: - Name:.gnu.hash.broken.maskwords # INVALID-NEXT: Type:SHT_GNU_HASH # INVALID-NEXT: Content: '0100' -# INVALID-NEXT: - Name:.gnu.hash.broken.nbuckets +# INVALID-NEXT: - Name:.gnu.hash.broken.nbuckets.a # INVALID-NEXT: Type:SHT_GNU_HASH # INVALID-NEXT: Content: '0100' +# INVALID-NEXT: - Name:.gnu.hash.broken.nbuckets.b +# INVALID-NEXT: Type:SHT_GNU_HASH +# INVALID-NEXT: Content: 0100{{$}} # INVALID-NEXT: - Name:.gnu.hash.hashvalues.ok # INVALID-NEXT: Type:SHT_GNU_HASH # INVALID-NEXT: Header: @@ -108,9 +111,9 @@ Sections: BloomFilter: [] HashBuckets: [] HashValues: [] -## Case 4: NBuckets field is broken, it says that the number of entries +## Case 4(a): NBuckets field is broken, it says that the number of entries ## in the hash buckets is 1, but it is empty. - - Name: .gnu.hash.broken.nbuckets + - Name: .gnu.hash.broken.nbuckets.a Type: SHT_GNU_HASH Header: SymNdx: 0x0 @@ -120,6 +123,18 @@ Sections: BloomFilter: [] HashBuckets: [] HashValues: [] +## Case 4(b): NBuckets = 0x is incorrect. The result will cause 32-bit +## unsigned overflows if we keep intermediate expressions uint32_t. + - Name: .gnu.hash.broken.nbuckets.b +Type: SHT_GNU_HASH +Header: + SymNdx: 0x0 + Shift2: 0x0 + MaskWords: 0x1 + NBuckets: 0x +BloomFilter: [] +HashBuckets: [] +HashValues: [] ## Case 5: Check that we use the various properties to dump the data when it ## has a size that is a multiple of 4, but fallback to dumping the whole section ## using the "Content" property otherwise. diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 1f9ff88f042a..2b54acd99f9e 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -1271,9 +1271,9 @@ ELFDumper::dumpGnuHashSection(const Elf_Shdr *Shdr) { ELFYAML::GnuHashHeader Header; DataExtractor::Cursor Cur(0); - uint32_t NBuckets = Data.getU32(Cur); + uint64_t NBuckets = Data.getU32(Cur); Header.SymNdx = Data.getU32(Cur); - uint32_t MaskWords = Data.getU32(Cur); + uint64_t MaskWords = Data.getU32(Cur); Header.Shift2 = Data.getU32(Cur); // Set just the raw binary content if we were unable to read the header ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 9017791 - Revert "[InstCombine] Fold gep inbounds of null to null"
Author: Nikita Popov Date: 2020-12-24T10:20:31+01:00 New Revision: 90177912a4dbf425a511caa6420e951a73c5fcf7 URL: https://github.com/llvm/llvm-project/commit/90177912a4dbf425a511caa6420e951a73c5fcf7 DIFF: https://github.com/llvm/llvm-project/commit/90177912a4dbf425a511caa6420e951a73c5fcf7.diff LOG: Revert "[InstCombine] Fold gep inbounds of null to null" This reverts commit eb79fd3c928dbbb97f7937963361c1dad2bf8222. This causes stage2 crashes, possibly due to StringMap being miscompiled. Reverting for now. Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/test/Transforms/InstCombine/getelementptr.ll llvm/test/Transforms/InstCombine/store.ll Removed: diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 153947802f80..71f165abe52e 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -903,14 +903,29 @@ static Instruction *replaceGEPIdxWithZero(InstCombinerImpl &IC, Value *Ptr, } static bool canSimplifyNullStoreOrGEP(StoreInst &SI) { - return isa(SI.getPointerOperand()) && - !NullPointerIsDefined(SI.getFunction(), SI.getPointerAddressSpace()); + if (NullPointerIsDefined(SI.getFunction(), SI.getPointerAddressSpace())) +return false; + + auto *Ptr = SI.getPointerOperand(); + if (GetElementPtrInst *GEPI = dyn_cast(Ptr)) +if (GEPI->isInBounds()) + Ptr = GEPI->getOperand(0); + return (isa(Ptr) && + !NullPointerIsDefined(SI.getFunction(), SI.getPointerAddressSpace())); } static bool canSimplifyNullLoadOrGEP(LoadInst &LI, Value *Op) { - return isa(Op) || - (isa(Op) && - !NullPointerIsDefined(LI.getFunction(), LI.getPointerAddressSpace())); + if (GetElementPtrInst *GEPI = dyn_cast(Op)) { +const Value *GEPI0 = GEPI->getOperand(0); +if (isa(GEPI0) && GEPI->isInBounds() && +!NullPointerIsDefined(LI.getFunction(), GEPI->getPointerAddressSpace())) + return true; + } + if (isa(Op) || + (isa(Op) && + !NullPointerIsDefined(LI.getFunction(), LI.getPointerAddressSpace( +return true; + return false; } Instruction *InstCombinerImpl::visitLoadInst(LoadInst &LI) { diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 8ace625e1fad..ec932aaf0b9e 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1855,13 +1855,6 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) { Value *PtrOp = GEP.getOperand(0); - // The only pointer that is inbounds of null is null. - if (isa(PtrOp) && GEP.isInBounds() && - !NullPointerIsDefined(GEP.getFunction(), -PtrOp->getType()->getPointerAddressSpace())) -if (auto *PtrTy = dyn_cast(GEPType)) - return replaceInstUsesWith(GEP, ConstantPointerNull::get(PtrTy)); - // Eliminate unneeded casts for indices, and replace indices which displace // by multiples of a zero size type with zero. bool MadeChange = false; diff --git a/llvm/test/Transforms/InstCombine/getelementptr.ll b/llvm/test/Transforms/InstCombine/getelementptr.ll index f1af3fda79e7..1ceba393aff6 100644 --- a/llvm/test/Transforms/InstCombine/getelementptr.ll +++ b/llvm/test/Transforms/InstCombine/getelementptr.ll @@ -1239,7 +1239,8 @@ define i32* @PR45084_extra_use(i1 %cond, %struct.f** %p) { define i8* @gep_null_inbounds(i64 %idx) { ; CHECK-LABEL: @gep_null_inbounds( -; CHECK-NEXT:ret i8* null +; CHECK-NEXT:[[GEP:%.*]] = getelementptr inbounds i8, i8* null, i64 [[IDX:%.*]] +; CHECK-NEXT:ret i8* [[GEP]] ; %gep = getelementptr inbounds i8, i8* null, i64 %idx ret i8* %gep @@ -1265,7 +1266,8 @@ define i8* @gep_null_defined(i64 %idx) null_pointer_is_valid { define i8* @gep_null_inbounds_ diff erent_type(i64 %idx1, i64 %idx2) { ; CHECK-LABEL: @gep_null_inbounds_ diff erent_type( -; CHECK-NEXT:ret i8* null +; CHECK-NEXT:[[GEP:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* null, i64 0, i64 [[IDX2:%.*]] +; CHECK-NEXT:ret i8* [[GEP]] ; %gep = getelementptr inbounds [0 x i8], [0 x i8]* null, i64 %idx1, i64 %idx2 ret i8* %gep diff --git a/llvm/test/Transforms/InstCombine/store.ll b/llvm/test/Transforms/InstCombine/store.ll index a94ce92d214e..d3842f4bb469 100644 --- a/llvm/test/Transforms/InstCombine/store.ll +++ b/llvm/test/Transforms/InstCombine/store.ll @@ -25,7 +25,8 @@ define void @test2(i32* %P) { define void @store_at_gep_off_null_inbounds(i64 %offset) { ; CHECK-LABEL: @store_at_gep_off_null_inbounds( -; CHECK-NEXT:store i32 undef, i
[llvm-branch-commits] [llvm] e075123 - [CodeGen] Add "noreturn" attirbute to _Unwind_Resume
Author: Evgeniy Brevnov Date: 2020-12-24T18:14:18+07:00 New Revision: e0751234ef0df733032b777ed0d993a490121855 URL: https://github.com/llvm/llvm-project/commit/e0751234ef0df733032b777ed0d993a490121855 DIFF: https://github.com/llvm/llvm-project/commit/e0751234ef0df733032b777ed0d993a490121855.diff LOG: [CodeGen] Add "noreturn" attirbute to _Unwind_Resume Currently 'resume' is lowered to _Unwind_Resume with out "noreturn" attribute. Semantically _Unwind_Resume library call is expected to never return and should be marked as such. Though I didn't find any changes in behavior of existing tests there will be a difference once https://reviews.llvm.org/D79485 lands. I was not able to come up with the test case anything better than just checking for presence of "noreturn" attribute. Please let me know if there is a better way to test the change. Reviewed By: xbolva00 Differential Revision: https://reviews.llvm.org/D93682 Added: llvm/test/CodeGen/Generic/dwarf_eh_resume.ll Modified: llvm/lib/CodeGen/DwarfEHPrepare.cpp llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-invoke-probabilities.ll Removed: diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp index c75c957bff8a..c7048337cdf2 100644 --- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp +++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp @@ -235,6 +235,7 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) { CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME)); // We never expect _Unwind_Resume to return. +CI->setDoesNotReturn(); new UnreachableInst(Ctx, UnwindBB); return true; } @@ -260,6 +261,7 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) { CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME)); // We never expect _Unwind_Resume to return. + CI->setDoesNotReturn(); new UnreachableInst(Ctx, UnwindBB); return true; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-invoke-probabilities.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-invoke-probabilities.ll index a10148f1ffdc..473216e9f170 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-invoke-probabilities.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-invoke-probabilities.ll @@ -11,7 +11,7 @@ declare i32 @hoge(...) define void @pluto() align 2 personality i8* bitcast (i32 (...)* @hoge to i8*) { ; CHECK-LABEL: @pluto ; CHECK: bb.1.bb -; CHECK: successors: %bb.2(0x4000), %bb.3(0x4000) +; CHECK: successors: %bb.2(0x), %bb.3(0x8000) ; CHECK: EH_LABEL ; CHECK: G_BR %bb.2 diff --git a/llvm/test/CodeGen/Generic/dwarf_eh_resume.ll b/llvm/test/CodeGen/Generic/dwarf_eh_resume.ll new file mode 100644 index ..b7bc17c46963 --- /dev/null +++ b/llvm/test/CodeGen/Generic/dwarf_eh_resume.ll @@ -0,0 +1,23 @@ +; RUN: llc %s -stop-after=irtranslator -o - | FileCheck %s + +declare i32 @hoge(...) + +; Check that 'resume' is lowered to _Unwind_Resume which marked as 'noreturn' +define void @pluto() align 2 personality i8* bitcast (i32 (...)* @hoge to i8*) { +;CHECK: call void @_Unwind_Resume(i8* %exn.obj) [[A:#.*]] +;CHECK: attributes [[A]] = { noreturn } +bb: + invoke void @spam() + to label %bb1 unwind label %bb2 + +bb1: ; preds = %bb + ret void + +bb2: ; preds = %bb + %tmp = landingpad { i8*, i32 } + cleanup + resume { i8*, i32 } %tmp + +} + +declare void @spam() ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] ef2f843 - Revert "[InstCombine] Check inbounds in load/store of gep null transform (PR48577)"
Author: Nikita Popov Date: 2020-12-24T12:36:56+01:00 New Revision: ef2f843347baca1ece69066a3c3a7afa45532079 URL: https://github.com/llvm/llvm-project/commit/ef2f843347baca1ece69066a3c3a7afa45532079 DIFF: https://github.com/llvm/llvm-project/commit/ef2f843347baca1ece69066a3c3a7afa45532079.diff LOG: Revert "[InstCombine] Check inbounds in load/store of gep null transform (PR48577)" This reverts commit 899faa50f206073cdd8eeaaa130ffa15f850e656. Upon further consideration, this does not fix the right issue. Doing this fold for non-inbounds GEPs is legal, because the resulting pointer is still based-on null, which has no associated address range, and as such and access to it is UB. https://bugs.llvm.org/show_bug.cgi?id=48577#c3 Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/test/Transforms/InstCombine/load.ll llvm/test/Transforms/InstCombine/store.ll Removed: diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 71f165abe52e..ac617ecd4fd1 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -908,8 +908,7 @@ static bool canSimplifyNullStoreOrGEP(StoreInst &SI) { auto *Ptr = SI.getPointerOperand(); if (GetElementPtrInst *GEPI = dyn_cast(Ptr)) -if (GEPI->isInBounds()) - Ptr = GEPI->getOperand(0); +Ptr = GEPI->getOperand(0); return (isa(Ptr) && !NullPointerIsDefined(SI.getFunction(), SI.getPointerAddressSpace())); } @@ -917,7 +916,7 @@ static bool canSimplifyNullStoreOrGEP(StoreInst &SI) { static bool canSimplifyNullLoadOrGEP(LoadInst &LI, Value *Op) { if (GetElementPtrInst *GEPI = dyn_cast(Op)) { const Value *GEPI0 = GEPI->getOperand(0); -if (isa(GEPI0) && GEPI->isInBounds() && +if (isa(GEPI0) && !NullPointerIsDefined(LI.getFunction(), GEPI->getPointerAddressSpace())) return true; } diff --git a/llvm/test/Transforms/InstCombine/load.ll b/llvm/test/Transforms/InstCombine/load.ll index e4ba908599c9..a6a2155be0b5 100644 --- a/llvm/test/Transforms/InstCombine/load.ll +++ b/llvm/test/Transforms/InstCombine/load.ll @@ -69,9 +69,8 @@ define i32 @load_gep_null_inbounds(i64 %X) { define i32 @load_gep_null_not_inbounds(i64 %X) { ; CHECK-LABEL: @load_gep_null_not_inbounds( -; CHECK-NEXT:[[V:%.*]] = getelementptr i32, i32* null, i64 [[X:%.*]] -; CHECK-NEXT:[[R:%.*]] = load i32, i32* [[V]], align 4 -; CHECK-NEXT:ret i32 [[R]] +; CHECK-NEXT:store i32 undef, i32* null, align 536870912 +; CHECK-NEXT:ret i32 undef ; %V = getelementptr i32, i32* null, i64 %X %R = load i32, i32* %V diff --git a/llvm/test/Transforms/InstCombine/store.ll b/llvm/test/Transforms/InstCombine/store.ll index d3842f4bb469..cda08f89501a 100644 --- a/llvm/test/Transforms/InstCombine/store.ll +++ b/llvm/test/Transforms/InstCombine/store.ll @@ -37,7 +37,7 @@ define void @store_at_gep_off_null_inbounds(i64 %offset) { define void @store_at_gep_off_null_not_inbounds(i64 %offset) { ; CHECK-LABEL: @store_at_gep_off_null_not_inbounds( ; CHECK-NEXT:[[PTR:%.*]] = getelementptr i32, i32* null, i64 [[OFFSET:%.*]] -; CHECK-NEXT:store i32 24, i32* [[PTR]], align 4 +; CHECK-NEXT:store i32 undef, i32* [[PTR]], align 4 ; CHECK-NEXT:ret void ; %ptr = getelementptr i32, i32 *null, i64 %offset ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] ce4413e - Moved dwarf_eh_resume.ll from Generic to X86 folder
Author: Evgeniy Brevnov Date: 2020-12-24T20:08:50+07:00 New Revision: ce4413e48941eeb85769e35b1a31112f39d9cc4c URL: https://github.com/llvm/llvm-project/commit/ce4413e48941eeb85769e35b1a31112f39d9cc4c DIFF: https://github.com/llvm/llvm-project/commit/ce4413e48941eeb85769e35b1a31112f39d9cc4c.diff LOG: Moved dwarf_eh_resume.ll from Generic to X86 folder Make test case x86 specific. Reviewed By: xbolva00 Differential Revision: https://reviews.llvm.org/D93803 Added: llvm/test/CodeGen/X86/dwarf_eh_resume.ll Modified: Removed: llvm/test/CodeGen/Generic/dwarf_eh_resume.ll diff --git a/llvm/test/CodeGen/Generic/dwarf_eh_resume.ll b/llvm/test/CodeGen/X86/dwarf_eh_resume.ll similarity index 88% rename from llvm/test/CodeGen/Generic/dwarf_eh_resume.ll rename to llvm/test/CodeGen/X86/dwarf_eh_resume.ll index b7bc17c46963..f44f0bc1e503 100644 --- a/llvm/test/CodeGen/Generic/dwarf_eh_resume.ll +++ b/llvm/test/CodeGen/X86/dwarf_eh_resume.ll @@ -1,4 +1,4 @@ -; RUN: llc %s -stop-after=irtranslator -o - | FileCheck %s +; RUN: opt -mtriple=x86_64-linux-gnu -dwarfehprepare -S %s | FileCheck %s declare i32 @hoge(...) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] fb46895 - [Support] Explicitly state that KnownBits::getMinValue/getMaxValue are UNSIGNED values. NFCI.
Author: Simon Pilgrim Date: 2020-12-24T14:10:11Z New Revision: fb468953082c1fe97d42e6eabe8d3511bdb4054f URL: https://github.com/llvm/llvm-project/commit/fb468953082c1fe97d42e6eabe8d3511bdb4054f DIFF: https://github.com/llvm/llvm-project/commit/fb468953082c1fe97d42e6eabe8d3511bdb4054f.diff LOG: [Support] Explicitly state that KnownBits::getMinValue/getMaxValue are UNSIGNED values. NFCI. Update the comment to make this clear, following the same approach as APInt. Added: Modified: llvm/include/llvm/Support/KnownBits.h Removed: diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h index f55839a35c13..2acaecfc3440 100644 --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -113,13 +113,13 @@ struct KnownBits { Zero.setSignBit(); } - /// Return the minimal value possible given these KnownBits. + /// Return the minimal unsigned value possible given these KnownBits. APInt getMinValue() const { // Assume that all bits that aren't known-ones are zeros. return One; } - /// Return the maximal value possible given these KnownBits. + /// Return the maximal unsigned value possible given these KnownBits. APInt getMaxValue() const { // Assume that all bits that aren't known-zeros are ones. return ~Zero; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 6895581 - [Support] Add KnownBits::getSignedMinValue/getSignedMaxValue helpers.
Author: Simon Pilgrim Date: 2020-12-24T14:10:12Z New Revision: 6895581fd2c1cbe1a51d157d40219b7bb51a9cd5 URL: https://github.com/llvm/llvm-project/commit/6895581fd2c1cbe1a51d157d40219b7bb51a9cd5 DIFF: https://github.com/llvm/llvm-project/commit/6895581fd2c1cbe1a51d157d40219b7bb51a9cd5.diff LOG: [Support] Add KnownBits::getSignedMinValue/getSignedMaxValue helpers. Add unit test coverage - a followup will update InstCombineCompares.cpp to use this and could be used by D86578 as well. Added: Modified: llvm/include/llvm/Support/KnownBits.h llvm/unittests/Support/KnownBitsTest.cpp Removed: diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h index 2acaecfc3440..ec88b9807174 100644 --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -119,12 +119,32 @@ struct KnownBits { return One; } + /// Return the minimal signed value possible given these KnownBits. + APInt getSignedMinValue() const { +// Assume that all bits that aren't known-ones are zeros. +APInt Min = One; +// Sign bit is unknown. +if (Zero.isSignBitClear() && One.isSignBitClear()) + Min.setSignBit(); +return Min; + } + /// Return the maximal unsigned value possible given these KnownBits. APInt getMaxValue() const { // Assume that all bits that aren't known-zeros are ones. return ~Zero; } + /// Return the maximal signed value possible given these KnownBits. + APInt getSignedMaxValue() const { +// Assume that all bits that aren't known-zeros are ones. +APInt Max = ~Zero; +// Sign bit is unknown. +if (Zero.isSignBitClear() && One.isSignBitClear()) + Max.clearSignBit(); +return Max; + } + /// Return known bits for a truncation of the value we're tracking. KnownBits trunc(unsigned BitWidth) const { return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth)); diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp index c5eb96efc85e..528a645ec51a 100644 --- a/llvm/unittests/Support/KnownBitsTest.cpp +++ b/llvm/unittests/Support/KnownBitsTest.cpp @@ -295,6 +295,20 @@ TEST(KnownBitsTest, GetMinMaxVal) { }); } +TEST(KnownBitsTest, GetSignedMinMaxVal) { + unsigned Bits = 4; + ForeachKnownBits(Bits, [&](const KnownBits &Known) { +APInt Min = APInt::getSignedMaxValue(Bits); +APInt Max = APInt::getSignedMinValue(Bits); +ForeachNumInKnownBits(Known, [&](const APInt &N) { + Min = APIntOps::smin(Min, N); + Max = APIntOps::smax(Max, N); +}); +EXPECT_EQ(Min, Known.getSignedMinValue()); +EXPECT_EQ(Max, Known.getSignedMaxValue()); + }); +} + TEST(KnownBitsTest, SExtOrTrunc) { const unsigned NarrowerSize = 4; const unsigned BaseSize = 6; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 89abe1c - [InstCombine] foldICmpUsingKnownBits - use KnownBits signed/unsigned getMin/MaxValue helpers. NFCI.
Author: Simon Pilgrim Date: 2020-12-24T14:22:26Z New Revision: 89abe1cf83a037e5e5c22d07d1b2bd456def5bbe URL: https://github.com/llvm/llvm-project/commit/89abe1cf83a037e5e5c22d07d1b2bd456def5bbe DIFF: https://github.com/llvm/llvm-project/commit/89abe1cf83a037e5e5c22d07d1b2bd456def5bbe.diff LOG: [InstCombine] foldICmpUsingKnownBits - use KnownBits signed/unsigned getMin/MaxValue helpers. NFCI. Replace the local compute*SignedMinMaxValuesFromKnownBits methods with the equivalent KnownBits helpers to determine the min/max value ranges. Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp Removed: diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 139b04bb6a81..83b310bfcd05 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -96,45 +96,6 @@ static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C) { return false; } -/// Given a signed integer type and a set of known zero and one bits, compute -/// the maximum and minimum values that could have the specified known zero and -/// known one bits, returning them in Min/Max. -/// TODO: Move to method on KnownBits struct? -static void computeSignedMinMaxValuesFromKnownBits(const KnownBits &Known, - APInt &Min, APInt &Max) { - assert(Known.getBitWidth() == Min.getBitWidth() && - Known.getBitWidth() == Max.getBitWidth() && - "KnownZero, KnownOne and Min, Max must have equal bitwidth."); - APInt UnknownBits = ~(Known.Zero|Known.One); - - // The minimum value is when all unknown bits are zeros, EXCEPT for the sign - // bit if it is unknown. - Min = Known.One; - Max = Known.One|UnknownBits; - - if (UnknownBits.isNegative()) { // Sign bit is unknown -Min.setSignBit(); -Max.clearSignBit(); - } -} - -/// Given an unsigned integer type and a set of known zero and one bits, compute -/// the maximum and minimum values that could have the specified known zero and -/// known one bits, returning them in Min/Max. -/// TODO: Move to method on KnownBits struct? -static void computeUnsignedMinMaxValuesFromKnownBits(const KnownBits &Known, - APInt &Min, APInt &Max) { - assert(Known.getBitWidth() == Min.getBitWidth() && - Known.getBitWidth() == Max.getBitWidth() && - "Ty, KnownZero, KnownOne and Min, Max must have equal bitwidth."); - APInt UnknownBits = ~(Known.Zero|Known.One); - - // The minimum value is when the unknown bits are all zeros. - Min = Known.One; - // The maximum value is when the unknown bits are all ones. - Max = Known.One|UnknownBits; -} - /// This is called when we see this pattern: /// cmp pred (load (gep GV, ...)), cmpcst /// where GV is a global variable with a constant initializer. Try to simplify @@ -5050,11 +5011,15 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) { APInt Op0Min(BitWidth, 0), Op0Max(BitWidth, 0); APInt Op1Min(BitWidth, 0), Op1Max(BitWidth, 0); if (I.isSigned()) { -computeSignedMinMaxValuesFromKnownBits(Op0Known, Op0Min, Op0Max); -computeSignedMinMaxValuesFromKnownBits(Op1Known, Op1Min, Op1Max); +Op0Min = Op0Known.getSignedMinValue(); +Op0Max = Op0Known.getSignedMaxValue(); +Op1Min = Op1Known.getSignedMinValue(); +Op1Max = Op1Known.getSignedMaxValue(); } else { -computeUnsignedMinMaxValuesFromKnownBits(Op0Known, Op0Min, Op0Max); -computeUnsignedMinMaxValuesFromKnownBits(Op1Known, Op1Min, Op1Max); +Op0Min = Op0Known.getMinValue(); +Op0Max = Op0Known.getMaxValue(); +Op1Min = Op1Known.getMinValue(); +Op1Max = Op1Known.getMaxValue(); } // If Min and Max are known to be the same, then SimplifyDemandedBits figured ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] df81211 - [CodeGen, Transforms] Use llvm::any_of (NFC)
Author: Kazu Hirata Date: 2020-12-24T09:08:36-08:00 New Revision: df812115e3ca9741f094a8102325cb2351868b48 URL: https://github.com/llvm/llvm-project/commit/df812115e3ca9741f094a8102325cb2351868b48 DIFF: https://github.com/llvm/llvm-project/commit/df812115e3ca9741f094a8102325cb2351868b48.diff LOG: [CodeGen, Transforms] Use llvm::any_of (NFC) Added: Modified: llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp llvm/lib/CodeGen/MultiHazardRecognizer.cpp llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp llvm/lib/Transforms/Utils/CodeMoverUtils.cpp llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp Removed: diff --git a/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp b/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp index 9ca6d9a9a551..1993f6033291 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp @@ -57,11 +57,10 @@ LegalityPredicate LegalityPredicates::typePairAndMemDescInSet( TypePairAndMemDesc Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1], Query.MMODescrs[MMOIdx].SizeInBits, Query.MMODescrs[MMOIdx].AlignInBits}; -return std::find_if( - TypesAndMemDesc.begin(), TypesAndMemDesc.end(), - [=](const TypePairAndMemDesc &Entry) ->bool { -return Match.isCompatible(Entry); - }) != TypesAndMemDesc.end(); +return llvm::any_of(TypesAndMemDesc, +[=](const TypePairAndMemDesc &Entry) -> bool { + return Match.isCompatible(Entry); +}); }; } diff --git a/llvm/lib/CodeGen/MultiHazardRecognizer.cpp b/llvm/lib/CodeGen/MultiHazardRecognizer.cpp index d66110ba3ac0..e4cd92ac4868 100644 --- a/llvm/lib/CodeGen/MultiHazardRecognizer.cpp +++ b/llvm/lib/CodeGen/MultiHazardRecognizer.cpp @@ -12,6 +12,7 @@ //===--===// #include "llvm/CodeGen/MultiHazardRecognizer.h" +#include "llvm/ADT/STLExtras.h" #include #include #include @@ -25,8 +26,8 @@ void MultiHazardRecognizer::AddHazardRecognizer( } bool MultiHazardRecognizer::atIssueLimit() const { - return std::any_of(Recognizers.begin(), Recognizers.end(), - std::mem_fn(&ScheduleHazardRecognizer::atIssueLimit)); + return llvm::any_of(Recognizers, + std::mem_fn(&ScheduleHazardRecognizer::atIssueLimit)); } ScheduleHazardRecognizer::HazardType @@ -72,7 +73,7 @@ bool MultiHazardRecognizer::ShouldPreferAnother(SUnit *SU) { auto SPA = [=](std::unique_ptr &R) { return R->ShouldPreferAnother(SU); }; - return std::any_of(Recognizers.begin(), Recognizers.end(), SPA); + return llvm::any_of(Recognizers, SPA); } void MultiHazardRecognizer::AdvanceCycle() { diff --git a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp index ab7e0ae9d4a5..fd734df053cd 100644 --- a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp +++ b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp @@ -260,10 +260,9 @@ class CHRScope { if (TailRegionSet.count(Parent)) return false; - assert(llvm::find_if(RegInfos, - [&Parent](const RegInfo &RI) { - return Parent == RI.R; - }) != RegInfos.end() && + assert(llvm::any_of( + RegInfos, + [&Parent](const RegInfo &RI) { return Parent == RI.R; }) && "Must be in head"); return true; }); diff --git a/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp b/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp index 08047dc0f96e..ce982c7403aa 100644 --- a/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp +++ b/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp @@ -355,35 +355,32 @@ bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint, // Check if there exists instructions which may throw, may synchonize, or may // never return, from I to InsertPoint. if (!isSafeToSpeculativelyExecute(&I)) -if (std::any_of(InstsToCheck.begin(), InstsToCheck.end(), -[](Instruction *I) { - if (I->mayThrow()) -return true; - - const CallBase *CB = dyn_cast(I); - if (!CB) -return false; - if (!CB->hasFnAttr(Attribute::WillReturn)) -return true; - if (!CB->hasFnAttr(Attribute::NoSync)) -return true; - - return false; -})) { +if (llvm::any_of(InstsToCheck, [](Instruction *I) { + if (I->ma
[llvm-branch-commits] [llvm] e457896 - [CodeGen] Remove unused function hasInlineAsmMemConstraint (NFC)
Author: Kazu Hirata Date: 2020-12-24T09:17:58-08:00 New Revision: e457896a6ef02d94e8419404321b521902189841 URL: https://github.com/llvm/llvm-project/commit/e457896a6ef02d94e8419404321b521902189841 DIFF: https://github.com/llvm/llvm-project/commit/e457896a6ef02d94e8419404321b521902189841.diff LOG: [CodeGen] Remove unused function hasInlineAsmMemConstraint (NFC) The last use of the function was removed on Sep 13, 2010 in commit 1094c80281e3cdd9e9a9d7ee716da6386b33359b. Added: Modified: llvm/include/llvm/CodeGen/Analysis.h llvm/lib/CodeGen/Analysis.cpp Removed: diff --git a/llvm/include/llvm/CodeGen/Analysis.h b/llvm/include/llvm/CodeGen/Analysis.h index fe610b5bdc8d..bdfb416d9bd9 100644 --- a/llvm/include/llvm/CodeGen/Analysis.h +++ b/llvm/include/llvm/CodeGen/Analysis.h @@ -92,11 +92,6 @@ void computeValueLLTs(const DataLayout &DL, Type &Ty, /// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V. GlobalValue *ExtractTypeInfo(Value *V); -/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being -/// processed uses a memory 'm' constraint. -bool hasInlineAsmMemConstraint(InlineAsm::ConstraintInfoVector &CInfos, - const TargetLowering &TLI); - /// getFCmpCondCode - Return the ISD condition code corresponding to /// the given LLVM IR floating-point condition code. This includes /// consideration of global floating-point math flags. diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp index 45099cdaf46f..cfd53bf53115 100644 --- a/llvm/lib/CodeGen/Analysis.cpp +++ b/llvm/lib/CodeGen/Analysis.cpp @@ -174,27 +174,6 @@ GlobalValue *llvm::ExtractTypeInfo(Value *V) { return GV; } -/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being -/// processed uses a memory 'm' constraint. -bool -llvm::hasInlineAsmMemConstraint(InlineAsm::ConstraintInfoVector &CInfos, -const TargetLowering &TLI) { - for (unsigned i = 0, e = CInfos.size(); i != e; ++i) { -InlineAsm::ConstraintInfo &CI = CInfos[i]; -for (unsigned j = 0, ee = CI.Codes.size(); j != ee; ++j) { - TargetLowering::ConstraintType CType = TLI.getConstraintType(CI.Codes[j]); - if (CType == TargetLowering::C_Memory) -return true; -} - -// Indirect operand accesses access memory. -if (CI.isIndirect) - return true; - } - - return false; -} - /// getFCmpCondCode - Return the ISD condition code corresponding to /// the given LLVM IR floating-point condition code. This includes /// consideration of global floating-point math flags. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] ff3749f - [NFC] SimplifyCFGOpt::simplifyUnreachable(): pacify unused variable warning
Author: Roman Lebedev Date: 2020-12-24T21:20:46+03:00 New Revision: ff3749fc7933a6f45b77739380e434060ca7693d URL: https://github.com/llvm/llvm-project/commit/ff3749fc7933a6f45b77739380e434060ca7693d DIFF: https://github.com/llvm/llvm-project/commit/ff3749fc7933a6f45b77739380e434060ca7693d.diff LOG: [NFC] SimplifyCFGOpt::simplifyUnreachable(): pacify unused variable warning Thanks to Luke Benes for pointing it out. Added: Modified: llvm/lib/Transforms/Utils/SimplifyCFG.cpp Removed: diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 777ec44cd0bd..67e0d2ac9cd7 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4632,6 +4632,7 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { Changed = true; } } else if (auto *CRI = dyn_cast(TI)) { + (void)CRI; assert(CRI->hasUnwindDest() && CRI->getUnwindDest() == BB && "Expected to always have an unwind to BB."); Updates.push_back({DominatorTree::Delete, Predecessor, BB}); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] b3021a7 - [IR][InstCombine] Add m_ImmConstant(), that matches on non-ConstantExpr constants, and use it
Author: Roman Lebedev Date: 2020-12-24T21:20:47+03:00 New Revision: b3021a72a6d2fea8702b75f34f9f3317ae923d92 URL: https://github.com/llvm/llvm-project/commit/b3021a72a6d2fea8702b75f34f9f3317ae923d92 DIFF: https://github.com/llvm/llvm-project/commit/b3021a72a6d2fea8702b75f34f9f3317ae923d92.diff LOG: [IR][InstCombine] Add m_ImmConstant(), that matches on non-ConstantExpr constants, and use it A pattern to ignore ConstantExpr's is quite common, since they frequently lead into infinite combine loops, so let's make writing it easier. Added: Modified: llvm/include/llvm/IR/PatternMatch.h llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp Removed: diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index c25573b9f8a6..c40f5d1d15d1 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -88,11 +88,6 @@ inline class_match m_BinOp() { /// Matches any compare instruction and ignore it. inline class_match m_Cmp() { return class_match(); } -/// Match an arbitrary ConstantInt and ignore it. -inline class_match m_ConstantInt() { - return class_match(); -} - /// Match an arbitrary undef constant. inline class_match m_Undef() { return class_match(); } @@ -102,6 +97,21 @@ inline class_match m_Poison() { return class_match(); /// Match an arbitrary Constant and ignore it. inline class_match m_Constant() { return class_match(); } +/// Match an arbitrary ConstantInt and ignore it. +inline class_match m_ConstantInt() { + return class_match(); +} + +/// Match an arbitrary ConstantFP and ignore it. +inline class_match m_ConstantFP() { + return class_match(); +} + +/// Match an arbitrary ConstantExpr and ignore it. +inline class_match m_ConstantExpr() { + return class_match(); +} + /// Match an arbitrary basic block value and ignore it. inline class_match m_BasicBlock() { return class_match(); @@ -699,21 +709,38 @@ inline bind_ty m_BinOp(BinaryOperator *&I) { return I; } /// Match a with overflow intrinsic, capturing it if we match. inline bind_ty m_WithOverflowInst(WithOverflowInst *&I) { return I; } -/// Match a ConstantInt, capturing the value if we match. -inline bind_ty m_ConstantInt(ConstantInt *&CI) { return CI; } - /// Match a Constant, capturing the value if we match. inline bind_ty m_Constant(Constant *&C) { return C; } +/// Match a ConstantInt, capturing the value if we match. +inline bind_ty m_ConstantInt(ConstantInt *&CI) { return CI; } + /// Match a ConstantFP, capturing the value if we match. inline bind_ty m_ConstantFP(ConstantFP *&C) { return C; } +/// Match a ConstantExpr, capturing the value if we match. +inline bind_ty m_ConstantExpr(ConstantExpr *&C) { return C; } + /// Match a basic block value, capturing it if we match. inline bind_ty m_BasicBlock(BasicBlock *&V) { return V; } inline bind_ty m_BasicBlock(const BasicBlock *&V) { return V; } +/// Match an arbitrary immediate Constant and ignore it. +inline match_combine_and, + match_unless>> +m_ImmConstant() { + return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr())); +} + +/// Match an immediate Constant, capturing the value if we match. +inline match_combine_and, + match_unless>> +m_ImmConstant(Constant *&C) { + return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr())); +} + /// Match a specified Value*. struct specificval_ty { const Value *Val; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 74ba23d343a0..c20861f20f07 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1841,7 +1841,7 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) { Constant *C2; // C-(C2-X) --> X+(C-C2) -if (match(Op1, m_Sub(m_Constant(C2), m_Value(X))) && !isa(C2)) +if (match(Op1, m_Sub(m_ImmConstant(C2), m_Value(X return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2)); } @@ -2198,7 +2198,7 @@ Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) { // X - C --> X + (-C) // But don't transform constant expressions because there's an inverse fold // for X + (-Y) --> X - Y. - if (match(Op1, m_Constant(C)) && !isa(Op1)) + if (match(Op1, m_ImmConstant(C))) return BinaryOperator::CreateFAddFMF(Op0, ConstantExpr::getFNeg(C), &I); // X - (-Y) --> X + Y diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 22e4fd7d9955..3dc8508aa760 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/l
[llvm-branch-commits] [llvm] da4c7e1 - [NFC][InstCombine] Autogenerate check lines in vec_shuffle.ll test
Author: Roman Lebedev Date: 2020-12-24T21:20:48+03:00 New Revision: da4c7e15df33aa659d160b645c595b977c81ad02 URL: https://github.com/llvm/llvm-project/commit/da4c7e15df33aa659d160b645c595b977c81ad02 DIFF: https://github.com/llvm/llvm-project/commit/da4c7e15df33aa659d160b645c595b977c81ad02.diff LOG: [NFC][InstCombine] Autogenerate check lines in vec_shuffle.ll test Added: Modified: llvm/test/Transforms/InstCombine/vec_shuffle.ll Removed: diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll index 874189d505c8..a033431c4bcc 100644 --- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll +++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll @@ -61,8 +61,8 @@ define float @test6(<4 x float> %X) { define float @testvscale6( %X) { ; CHECK-LABEL: @testvscale6( -; CHECK-NEXT:[[T:%.*]] = shufflevector [[X:%.*]], undef, zeroinitializer -; CHECK-NEXT:[[R:%.*]] = extractelement [[T]], i32 0 +; CHECK-NEXT:[[T2:%.*]] = shufflevector [[X:%.*]], undef, zeroinitializer +; CHECK-NEXT:[[R:%.*]] = extractelement [[T2]], i32 0 ; CHECK-NEXT:ret float [[R]] ; %X1 = bitcast %X to @@ -749,8 +749,8 @@ define <8 x i8> @pr19730(<16 x i8> %in0) { define i32 @pr19737(<4 x i32> %in0) { ; CHECK-LABEL: @pr19737( -; CHECK-NEXT:[[TMP1:%.*]] = extractelement <4 x i32> [[IN0:%.*]], i32 0 -; CHECK-NEXT:ret i32 [[TMP1]] +; CHECK-NEXT:[[RV:%.*]] = extractelement <4 x i32> [[IN0:%.*]], i32 0 +; CHECK-NEXT:ret i32 [[RV]] ; %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> %neg.i = xor <4 x i32> %shuffle.i, ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 8001dcb - [NFC][InstCombine] Add test coverage for `(x ^ C) ^ y` pattern
Author: Roman Lebedev Date: 2020-12-24T21:20:50+03:00 New Revision: 8001dcbd50ce501e75e06886c5e225298e9eea2b URL: https://github.com/llvm/llvm-project/commit/8001dcbd50ce501e75e06886c5e225298e9eea2b DIFF: https://github.com/llvm/llvm-project/commit/8001dcbd50ce501e75e06886c5e225298e9eea2b.diff LOG: [NFC][InstCombine] Add test coverage for `(x ^ C) ^ y` pattern Added: llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll Modified: Removed: diff --git a/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll b/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll new file mode 100644 index ..20b114ff0b0c --- /dev/null +++ b/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll @@ -0,0 +1,75 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare i8 @gen8() +declare void @use8(i8) + +@a = global i8 17 + +define i8 @t0_scalar(i8 %x, i8 %y) { +; CHECK-LABEL: @t0_scalar( +; CHECK-NEXT:[[I0:%.*]] = xor i8 [[X:%.*]], 42 +; CHECK-NEXT:[[R:%.*]] = xor i8 [[I0]], [[Y:%.*]] +; CHECK-NEXT:ret i8 [[R]] +; + %i0 = xor i8 %x, 42 + %r = xor i8 %i0, %y + ret i8 %r +} + +define <2 x i8> @t1_splatvec(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @t1_splatvec( +; CHECK-NEXT:[[I0:%.*]] = xor <2 x i8> [[X:%.*]], +; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[I0]], [[Y:%.*]] +; CHECK-NEXT:ret <2 x i8> [[R]] +; + %i0 = xor <2 x i8> %x, + %r = xor <2 x i8> %i0, %y + ret <2 x i8> %r +} +define <2 x i8> @t2_vec(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @t2_vec( +; CHECK-NEXT:[[I0:%.*]] = xor <2 x i8> [[X:%.*]], +; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[I0]], [[Y:%.*]] +; CHECK-NEXT:ret <2 x i8> [[R]] +; + %i0 = xor <2 x i8> %x, + %r = xor <2 x i8> %i0, %y + ret <2 x i8> %r +} +define <2 x i8> @t3_vec_undef(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @t3_vec_undef( +; CHECK-NEXT:[[I0:%.*]] = xor <2 x i8> [[X:%.*]], +; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[I0]], [[Y:%.*]] +; CHECK-NEXT:ret <2 x i8> [[R]] +; + %i0 = xor <2 x i8> %x, + %r = xor <2 x i8> %i0, %y + ret <2 x i8> %r +} + +define i8 @t4_extrause(i8 %x, i8 %y) { +; CHECK-LABEL: @t4_extrause( +; CHECK-NEXT:[[I0:%.*]] = xor i8 [[X:%.*]], 42 +; CHECK-NEXT:call void @use8(i8 [[I0]]) +; CHECK-NEXT:[[R:%.*]] = xor i8 [[I0]], [[Y:%.*]] +; CHECK-NEXT:ret i8 [[R]] +; + %i0 = xor i8 %x, 42 + call void @use8(i8 %i0) + %r = xor i8 %i0, %y + ret i8 %r +} + +define i8 @t5_commutativity(i8 %x) { +; CHECK-LABEL: @t5_commutativity( +; CHECK-NEXT:[[I0:%.*]] = xor i8 [[X:%.*]], 42 +; CHECK-NEXT:[[Y:%.*]] = call i8 @gen8() +; CHECK-NEXT:[[R:%.*]] = xor i8 [[Y]], [[I0]] +; CHECK-NEXT:ret i8 [[R]] +; + %i0 = xor i8 %x, 42 + %y = call i8 @gen8() + %r = xor i8 %y, %i0 + ret i8 %r +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] d9ebaee - [InstCombine] Hoist xor-by-constant from xor-by-value
Author: Roman Lebedev Date: 2020-12-24T21:20:50+03:00 New Revision: d9ebaeeb468d6a8f29eb479f18d2790f7efb8565 URL: https://github.com/llvm/llvm-project/commit/d9ebaeeb468d6a8f29eb479f18d2790f7efb8565 DIFF: https://github.com/llvm/llvm-project/commit/d9ebaeeb468d6a8f29eb479f18d2790f7efb8565.diff LOG: [InstCombine] Hoist xor-by-constant from xor-by-value This is one of the deficiencies that can be observed in https://godbolt.org/z/YPczsG after D91038 patch set. This exposed two missing folds, one was fixed by the previous commit, another one is `(A ^ B) | ~(A ^ B) --> -1` / `(A ^ B) & ~(A ^ B) --> 0`. `-early-cse` will catch it: https://godbolt.org/z/4n1T1v, but isn't meaningful to fix it in InstCombine, because we'd need to essentially do our own CSE, and we can't even rely on `Instruction::isIdenticalTo()`, because there are no guarantees that the order of operands matches. So let's just accept it as a loss. Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll llvm/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-scalar.ll llvm/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-vector.ll llvm/test/Transforms/InstCombine/or-xor.ll llvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-scalar.ll llvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-vector.ll llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll llvm/test/Transforms/InstCombine/vec_shuffle.ll llvm/test/Transforms/InstCombine/xor2.ll Removed: diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 3c0cdaf6e843..9d3b81a1cdd5 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -3457,5 +3457,13 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) { if (Instruction *NewXor = sinkNotIntoXor(I, Builder)) return NewXor; + // Otherwise, if all else failed, try to hoist the xor-by-constant: + // (X ^ C) ^ Y --> (X ^ Y) ^ C + // FIXME: does this need hardening against ConstantExpr's + //to prevent infinite combine loops? + if (match(&I, +m_c_Xor(m_OneUse(m_Xor(m_Value(X), m_Constant(C1))), m_Value(Y +return BinaryOperator::CreateXor(Builder.CreateXor(X, Y), C1); + return nullptr; } diff --git a/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll b/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll index 20b114ff0b0c..e5ffb4622cbc 100644 --- a/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll +++ b/llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll @@ -8,8 +8,8 @@ declare void @use8(i8) define i8 @t0_scalar(i8 %x, i8 %y) { ; CHECK-LABEL: @t0_scalar( -; CHECK-NEXT:[[I0:%.*]] = xor i8 [[X:%.*]], 42 -; CHECK-NEXT:[[R:%.*]] = xor i8 [[I0]], [[Y:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[R:%.*]] = xor i8 [[TMP1]], 42 ; CHECK-NEXT:ret i8 [[R]] ; %i0 = xor i8 %x, 42 @@ -19,8 +19,8 @@ define i8 @t0_scalar(i8 %x, i8 %y) { define <2 x i8> @t1_splatvec(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @t1_splatvec( -; CHECK-NEXT:[[I0:%.*]] = xor <2 x i8> [[X:%.*]], -; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[I0]], [[Y:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = xor <2 x i8> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[TMP1]], ; CHECK-NEXT:ret <2 x i8> [[R]] ; %i0 = xor <2 x i8> %x, @@ -29,8 +29,8 @@ define <2 x i8> @t1_splatvec(<2 x i8> %x, <2 x i8> %y) { } define <2 x i8> @t2_vec(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @t2_vec( -; CHECK-NEXT:[[I0:%.*]] = xor <2 x i8> [[X:%.*]], -; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[I0]], [[Y:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = xor <2 x i8> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[TMP1]], ; CHECK-NEXT:ret <2 x i8> [[R]] ; %i0 = xor <2 x i8> %x, @@ -39,8 +39,8 @@ define <2 x i8> @t2_vec(<2 x i8> %x, <2 x i8> %y) { } define <2 x i8> @t3_vec_undef(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @t3_vec_undef( -; CHECK-NEXT:[[I0:%.*]] = xor <2 x i8> [[X:%.*]], -; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[I0]], [[Y:%.*]] +; CHECK-NEXT:[[TMP1:%.*]] = xor <2 x i8> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT:[[R:%.*]] = xor <2 x i8> [[TMP1]], ; CHECK-NEXT:ret <2 x i8> [[R]] ; %i0 = xor <2 x i8> %x, @@ -63,9 +63,9 @@ define i8 @t4_extrause(i8 %x, i8 %y) { define i8 @t5_commutativity(i8 %x) { ; CHECK-LABEL: @t5_commutativity( -; CHECK-NEXT:[[I0:%.*]] = xor i8 [[X:%.*]], 42 ; CHECK-NEXT:[[Y:%.*]] = call i8 @gen8() -; CHECK-NEXT:[[R:%.*]] =
[llvm-branch-commits] [llvm] 5b78303 - [InstCombine] Fold `a & ~(a ^ b)` to `x & y`
Author: Roman Lebedev Date: 2020-12-24T21:20:49+03:00 New Revision: 5b78303433c0778a839e89d20daa57fbc037d0c7 URL: https://github.com/llvm/llvm-project/commit/5b78303433c0778a839e89d20daa57fbc037d0c7 DIFF: https://github.com/llvm/llvm-project/commit/5b78303433c0778a839e89d20daa57fbc037d0c7.diff LOG: [InstCombine] Fold `a & ~(a ^ b)` to `x & y` ``` define i32 @and_xor_not_common_op(i32 %a, i32 %b) { %0: %b2 = xor i32 %b, 4294967295 %t2 = xor i32 %a, %b2 %t4 = and i32 %t2, %a ret i32 %t4 } => define i32 @and_xor_not_common_op(i32 %a, i32 %b) { %0: %t4 = and i32 %a, %b ret i32 %t4 } Transformation seems to be correct! ``` Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/test/Transforms/InstCombine/and-xor-or.ll Removed: diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 6b5fd571ecf5..3c0cdaf6e843 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1883,6 +1883,13 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) { if (match(Op0, m_OneUse(m_c_Xor(m_Specific(Op1), m_Value(B) return BinaryOperator::CreateAnd(Op1, Builder.CreateNot(B)); +// A & ~(A ^ B) --> A & B +if (match(Op1, m_Not(m_c_Xor(m_Specific(Op0), m_Value(B) + return BinaryOperator::CreateAnd(Op0, B); +// ~(A ^ B) & A --> A & B +if (match(Op0, m_Not(m_c_Xor(m_Specific(Op1), m_Value(B) + return BinaryOperator::CreateAnd(Op1, B); + // (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & ~C if (match(Op0, m_Xor(m_Value(A), m_Value(B if (match(Op1, m_Xor(m_Xor(m_Specific(B), m_Value(C)), m_Specific(A diff --git a/llvm/test/Transforms/InstCombine/and-xor-or.ll b/llvm/test/Transforms/InstCombine/and-xor-or.ll index 4a27e3f00c89..4cb88d0766ba 100644 --- a/llvm/test/Transforms/InstCombine/and-xor-or.ll +++ b/llvm/test/Transforms/InstCombine/and-xor-or.ll @@ -116,9 +116,7 @@ define i32 @and_xor_not_common_op_extrause(i32 %a, i32 %b, i32* %dst) { define i32 @and_not_xor_common_op(i32 %a, i32 %b) { ; CHECK-LABEL: @and_not_xor_common_op( -; CHECK-NEXT:[[B2:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT:[[T2:%.*]] = xor i32 [[B2]], -1 -; CHECK-NEXT:[[T4:%.*]] = and i32 [[T2]], [[A]] +; CHECK-NEXT:[[T4:%.*]] = and i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT:ret i32 [[T4]] ; %b2 = xor i32 %b, %a @@ -131,9 +129,7 @@ declare i32 @gen32() define i32 @and_not_xor_common_op_commutative(i32 %b) { ; CHECK-LABEL: @and_not_xor_common_op_commutative( ; CHECK-NEXT:[[A:%.*]] = call i32 @gen32() -; CHECK-NEXT:[[B2:%.*]] = xor i32 [[A]], [[B:%.*]] -; CHECK-NEXT:[[T2:%.*]] = xor i32 [[B2]], -1 -; CHECK-NEXT:[[T4:%.*]] = and i32 [[A]], [[T2]] +; CHECK-NEXT:[[T4:%.*]] = and i32 [[A]], [[B:%.*]] ; CHECK-NEXT:ret i32 [[T4]] ; %a = call i32 @gen32() ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 25aebe2 - [LoopIdiom] 'left-shift-until-bittest': keep no-wrap flags on shift, fix edge-case miscompilation for %x.next
Author: Roman Lebedev Date: 2020-12-24T21:20:52+03:00 New Revision: 25aebe2ccfb4622b17494c5cfdb2b422c93cee4d URL: https://github.com/llvm/llvm-project/commit/25aebe2ccfb4622b17494c5cfdb2b422c93cee4d DIFF: https://github.com/llvm/llvm-project/commit/25aebe2ccfb4622b17494c5cfdb2b422c93cee4d.diff LOG: [LoopIdiom] 'left-shift-until-bittest': keep no-wrap flags on shift, fix edge-case miscompilation for %x.next While `%x.curr` is always safe to compute, because `LoopBackedgeTakenCount` will always be smaller than `bitwidth(X)`, i.e. we never get poison, rewriting `%x.next` is more complicated, however, because `X << LoopTripCount` will be poison iff `LoopTripCount == bitwidth(X)` (which will happen iff `BitPos` is `bitwidth(x) - 1` and `X` is `1`). So unless we know that isn't the case (as alive2 notes, we know it's safe to do iff shift had no-wrap flags, or bitpos does not indicate signbit, or we know that %x is never `1`), we'll need to emit an alternative, safe IR, by either just shifting the `%x.curr`, or conditionally selecting between the computed `%x.next` and `0`.. Former IR looks better so let's do that. While there, ensure that we don't drop no-wrap flags from said shift. Added: Modified: llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/test/Transforms/LoopIdiom/X86/left-shift-until-bittest.ll Removed: diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index 9ab896f58141..3612f8cc1a71 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -1963,7 +1963,7 @@ inline match_LoopInvariant m_LoopInvariant(const Ty &M, const Loop *L) { /// \endcode static bool detectShiftUntilBitTestIdiom(Loop *CurLoop, Value *&BaseX, Value *&BitMask, Value *&BitPos, - Value *&CurrX, Value *&NextX) { + Value *&CurrX, Instruction *&NextX) { LLVM_DEBUG(dbgs() << DEBUG_TYPE " Performing shift-until-bittest idiom detection.\n"); @@ -2030,9 +2030,10 @@ static bool detectShiftUntilBitTestIdiom(Loop *CurLoop, Value *&BaseX, } BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB); - NextX = CurrXPN->getIncomingValueForBlock(LoopHeaderBB); + NextX = + dyn_cast(CurrXPN->getIncomingValueForBlock(LoopHeaderBB)); - if (!match(NextX, m_Shl(m_Specific(CurrX), m_One( { + if (!NextX || !match(NextX, m_Shl(m_Specific(CurrX), m_One( { // FIXME: support right-shift? LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad recurrence.\n"); return false; @@ -2113,7 +2114,8 @@ static bool detectShiftUntilBitTestIdiom(Loop *CurLoop, Value *&BaseX, bool LoopIdiomRecognize::recognizeShiftUntilBitTest() { bool MadeChange = false; - Value *X, *BitMask, *BitPos, *XCurr, *XNext; + Value *X, *BitMask, *BitPos, *XCurr; + Instruction *XNext; if (!detectShiftUntilBitTestIdiom(CurLoop, X, BitMask, BitPos, XCurr, XNext)) { LLVM_DEBUG(dbgs() << DEBUG_TYPE @@ -2163,9 +2165,8 @@ bool LoopIdiomRecognize::recognizeShiftUntilBitTest() { // Step 1: Compute the loop trip count. - Value *LowBitMask = - Builder.CreateAdd(BitMask, Constant::getAllOnesValue(BitMask->getType()), -BitPos->getName() + ".lowbitmask"); + Value *LowBitMask = Builder.CreateAdd(BitMask, Constant::getAllOnesValue(Ty), +BitPos->getName() + ".lowbitmask"); Value *Mask = Builder.CreateOr(LowBitMask, BitMask, BitPos->getName() + ".mask"); Value *XMasked = Builder.CreateAnd(X, Mask, X->getName() + ".masked"); @@ -2173,11 +2174,11 @@ bool LoopIdiomRecognize::recognizeShiftUntilBitTest() { IntrID, Ty, {XMasked, /*is_zero_undef=*/Builder.getTrue()}, /*FMFSource=*/nullptr, XMasked->getName() + ".numleadingzeros"); Value *XMaskedNumActiveBits = Builder.CreateSub( - ConstantInt::get(X->getType(), X->getType()->getScalarSizeInBits()), - XMaskedNumLeadingZeros, XMasked->getName() + ".numactivebits"); - Value *XMaskedLeadingOnePos = Builder.CreateAdd( - XMaskedNumActiveBits, Constant::getAllOnesValue(BitMask->getType()), - XMasked->getName() + ".leadingonepos"); + ConstantInt::get(Ty, Ty->getScalarSizeInBits()), XMaskedNumLeadingZeros, + XMasked->getName() + ".numactivebits"); + Value *XMaskedLeadingOnePos = + Builder.CreateAdd(XMaskedNumActiveBits, Constant::getAllOnesValue(Ty), +XMasked->getName() + ".leadingonepos"); Value *LoopBackedgeTakenCount = Builder.CreateSub( BitPos, XMaskedLeadingOnePos, CurLoop->getName() + ".backedgetakencount"); @@ -2189,11 +2190,34 @@ bool LoopIdiomRecognize::recognizeShiftUntilBitTest() { // Step 2: Compute the recurrenc
[llvm-branch-commits] [llvm] 1fda233 - [NFC][InstCombine] Add test for `a & ~(a ^ b)` pattern
Author: Roman Lebedev Date: 2020-12-24T21:20:48+03:00 New Revision: 1fda23367d46955fcb6e605f4114d47e499f0901 URL: https://github.com/llvm/llvm-project/commit/1fda23367d46955fcb6e605f4114d47e499f0901 DIFF: https://github.com/llvm/llvm-project/commit/1fda23367d46955fcb6e605f4114d47e499f0901.diff LOG: [NFC][InstCombine] Add test for `a & ~(a ^ b)` pattern ... which is a variation of `a & (a ^ ~b)` --> a & b`. A follow-up patch exposes this missing fold, so we need to fix it first. Added: Modified: llvm/test/Transforms/InstCombine/and-xor-or.ll Removed: diff --git a/llvm/test/Transforms/InstCombine/and-xor-or.ll b/llvm/test/Transforms/InstCombine/and-xor-or.ll index 6e54c5318d21..4a27e3f00c89 100644 --- a/llvm/test/Transforms/InstCombine/and-xor-or.ll +++ b/llvm/test/Transforms/InstCombine/and-xor-or.ll @@ -96,6 +96,53 @@ define i32 @and_xor_not_common_op(i32 %a, i32 %b) { ret i32 %t4 } +; a & (a ^ ~b) --> a & b + +define i32 @and_xor_not_common_op_extrause(i32 %a, i32 %b, i32* %dst) { +; CHECK-LABEL: @and_xor_not_common_op_extrause( +; CHECK-NEXT:[[B2:%.*]] = xor i32 [[B:%.*]], -1 +; CHECK-NEXT:store i32 [[B2]], i32* [[DST:%.*]], align 4 +; CHECK-NEXT:[[T4:%.*]] = and i32 [[A:%.*]], [[B]] +; CHECK-NEXT:ret i32 [[T4]] +; + %b2 = xor i32 %b, -1 + store i32 %b2, i32* %dst + %t2 = xor i32 %a, %b2 + %t4 = and i32 %t2, %a + ret i32 %t4 +} + +; a & ~(a ^ b) --> a & b + +define i32 @and_not_xor_common_op(i32 %a, i32 %b) { +; CHECK-LABEL: @and_not_xor_common_op( +; CHECK-NEXT:[[B2:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT:[[T2:%.*]] = xor i32 [[B2]], -1 +; CHECK-NEXT:[[T4:%.*]] = and i32 [[T2]], [[A]] +; CHECK-NEXT:ret i32 [[T4]] +; + %b2 = xor i32 %b, %a + %t2 = xor i32 %b2, -1 + %t4 = and i32 %t2, %a + ret i32 %t4 +} + +declare i32 @gen32() +define i32 @and_not_xor_common_op_commutative(i32 %b) { +; CHECK-LABEL: @and_not_xor_common_op_commutative( +; CHECK-NEXT:[[A:%.*]] = call i32 @gen32() +; CHECK-NEXT:[[B2:%.*]] = xor i32 [[A]], [[B:%.*]] +; CHECK-NEXT:[[T2:%.*]] = xor i32 [[B2]], -1 +; CHECK-NEXT:[[T4:%.*]] = and i32 [[A]], [[T2]] +; CHECK-NEXT:ret i32 [[T4]] +; + %a = call i32 @gen32() + %b2 = xor i32 %a, %b ; swapped order + %t2 = xor i32 %b2, -1 + %t4 = and i32 %a, %t2 ; swapped order + ret i32 %t4 +} + ; rdar://10770603 ; (x & y) | (x ^ y) -> x | y ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 351c216 - [RISCV] Define vector mask-register logical intrinsics.
Author: Zakk Chen Date: 2020-12-24T18:59:05-08:00 New Revision: 351c216f36afab3bb88eb74995a39940b85e3812 URL: https://github.com/llvm/llvm-project/commit/351c216f36afab3bb88eb74995a39940b85e3812 DIFF: https://github.com/llvm/llvm-project/commit/351c216f36afab3bb88eb74995a39940b85e3812.diff LOG: [RISCV] Define vector mask-register logical intrinsics. Define vector mask-register logical intrinsics and lower them to V instructions. Also define pseudo instructions vmmv.m and vmnot.m. We work with @rogfer01 from BSC to come out this patch. Authored-by: Roger Ferrer Ibanez Co-Authored-by: Zakk Chen Differential Revision: https://reviews.llvm.org/D93705 Added: llvm/test/CodeGen/RISCV/rvv/vmand-rv32.ll llvm/test/CodeGen/RISCV/rvv/vmand-rv64.ll llvm/test/CodeGen/RISCV/rvv/vmandnot-rv32.ll llvm/test/CodeGen/RISCV/rvv/vmandnot-rv64.ll llvm/test/CodeGen/RISCV/rvv/vmnand-rv32.ll llvm/test/CodeGen/RISCV/rvv/vmnand-rv64.ll llvm/test/CodeGen/RISCV/rvv/vmnor-rv32.ll llvm/test/CodeGen/RISCV/rvv/vmnor-rv64.ll llvm/test/CodeGen/RISCV/rvv/vmor-rv32.ll llvm/test/CodeGen/RISCV/rvv/vmor-rv64.ll llvm/test/CodeGen/RISCV/rvv/vmornot-rv32.ll llvm/test/CodeGen/RISCV/rvv/vmornot-rv64.ll llvm/test/CodeGen/RISCV/rvv/vmxnor-rv32.ll llvm/test/CodeGen/RISCV/rvv/vmxnor-rv64.ll llvm/test/CodeGen/RISCV/rvv/vmxor-rv32.ll llvm/test/CodeGen/RISCV/rvv/vmxor-rv64.ll Modified: llvm/include/llvm/IR/IntrinsicsRISCV.td llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td Removed: diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index cb335e739266..6778b20ac0a8 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -189,6 +189,12 @@ let TargetPrefix = "riscv" in { LLVMPointerType>, llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty], [NoCapture>, IntrWriteMem]>, RISCVVIntrinsic; + // For destination vector type is the same as first and second source vector. + // Input: (vector_in, vector_in, vl) + class RISCVBinaryAAANoMask +: Intrinsic<[llvm_anyvector_ty], +[LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty], +[IntrNoMem]>, RISCVVIntrinsic; // For destination vector type is the same as first source vector. // Input: (vector_in, vector_in/scalar_in, vl) class RISCVBinaryAAXNoMask @@ -643,4 +649,13 @@ let TargetPrefix = "riscv" in { defm vfredsum : RISCVReduction; defm vfredmin : RISCVReduction; defm vfredmax : RISCVReduction; + + def int_riscv_vmand: RISCVBinaryAAANoMask; + def int_riscv_vmnand: RISCVBinaryAAANoMask; + def int_riscv_vmandnot: RISCVBinaryAAANoMask; + def int_riscv_vmxor: RISCVBinaryAAANoMask; + def int_riscv_vmor: RISCVBinaryAAANoMask; + def int_riscv_vmnor: RISCVBinaryAAANoMask; + def int_riscv_vmornot: RISCVBinaryAAANoMask; + def int_riscv_vmxnor: RISCVBinaryAAANoMask; } // TargetPrefix = "riscv" diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td index 713a289badc2..c23c650973b3 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -188,6 +188,25 @@ class GetIntVTypeInfo VTypeInfo Vti = !cast(!subst("VF", "VI", !cast(vti))); } +class MTypeInfo { + ValueType Mask = Mas; + // {SEW, VLMul} values set a valid VType to deal with this mask type. + // we assume SEW=8 and set corresponding LMUL. + int SEW = 8; + LMULInfo LMul = M; +} + +defset list AllMasks = { + // vbool_t, = SEW/LMUL, we assume SEW=8 and corresponding LMUL. + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; +} + class VTypeInfoToWide { VTypeInfo Vti = vti; @@ -697,6 +716,13 @@ multiclass VPseudoBinaryV_VI { defm _VI : VPseudoBinary; } +multiclass VPseudoBinaryM_MM { + foreach m = MxList.m in +let VLMul = m.value in { + def "_MM_" # m.MX : VPseudoBinaryNoMask; +} +} + // We use earlyclobber here due to // * The destination EEW is smaller than the source EEW and the overlap is // in the lowest-numbered part of the source register group is legal. @@ -1297,6 +1323,13 @@ multiclass VPatBinaryV_VI; } +multiclass VPatBinaryM_MM { + foreach mti = AllMasks in +def : VPatBinaryNoMask; +} + multiclass VPatBinaryW_VV vtilist> { foreach VtiToWti = vtilist in { @@ -2053,6 +2086,27 @@ defm PseudoVFREDMIN: VPseudoReductionV_VS; defm PseudoVFREDMAX: VPseudoReductionV_VS; } // Predicates = [HasStdExtV, HasStdExtF] +//===--===// +// 16. Vector Mask Instructions +//===--
[llvm-branch-commits] [llvm] d6ff5cf - [Target] Use llvm::any_of (NFC)
Author: Kazu Hirata Date: 2020-12-24T19:43:26-08:00 New Revision: d6ff5cf995db22c37890b5469a5ad62022996c8c URL: https://github.com/llvm/llvm-project/commit/d6ff5cf995db22c37890b5469a5ad62022996c8c DIFF: https://github.com/llvm/llvm-project/commit/d6ff5cf995db22c37890b5469a5ad62022996c8c.diff LOG: [Target] Use llvm::any_of (NFC) Added: Modified: llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp llvm/lib/Target/AMDGPU/SIFoldOperands.cpp llvm/lib/Target/RISCV/RISCVISelLowering.cpp llvm/tools/llvm-lipo/llvm-lipo.cpp Removed: diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp index 86cfdf8f7cf9..954b0960fc02 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -333,9 +333,9 @@ bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF, } bool AArch64RegisterInfo::isAnyArgRegReserved(const MachineFunction &MF) const { - return std::any_of(std::begin(*AArch64::GPR64argRegClass.MC), - std::end(*AArch64::GPR64argRegClass.MC), - [this, &MF](MCPhysReg r){return isReservedReg(MF, r);}); + return llvm::any_of(*AArch64::GPR64argRegClass.MC, [this, &MF](MCPhysReg r) { +return isReservedReg(MF, r); + }); } void AArch64RegisterInfo::emitReservedArgRegCallError( diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp index edc5fe287167..85d26cd4d0ff 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp @@ -325,9 +325,10 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { Value *ReplVal = Store.second->getValueOperand(); auto &ValVec = Replacements[Store.first]; -if (llvm::find_if(ValVec, - [OutArg](const std::pair &Entry) { - return Entry.first == OutArg;}) != ValVec.end()) { +if (llvm::any_of(ValVec, + [OutArg](const std::pair &Entry) { + return Entry.first == OutArg; + })) { LLVM_DEBUG(dbgs() << "Saw multiple out arg stores" << *OutArg << '\n'); // It is possible to see stores to the same argument multiple times, diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp index 06cce54e540c..d86527df5c3c 100644 --- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp +++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp @@ -560,8 +560,9 @@ static bool tryToFoldACImm(const SIInstrInfo *TII, if (!UseReg.isVirtual()) return false; - if (llvm::find_if(FoldList, [UseMI](const FoldCandidate &FC) { -return FC.UseMI == UseMI; }) != FoldList.end()) + if (llvm::any_of(FoldList, [UseMI](const FoldCandidate &FC) { +return FC.UseMI == UseMI; + })) return false; MachineRegisterInfo &MRI = UseMI->getParent()->getParent()->getRegInfo(); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index c0037fb623ee..92bb316356c6 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3434,7 +3434,7 @@ void RISCVTargetLowering::validateCCReservedRegs( const Function &F = MF.getFunction(); const RISCVSubtarget &STI = MF.getSubtarget(); - if (std::any_of(std::begin(Regs), std::end(Regs), [&STI](auto Reg) { + if (llvm::any_of(Regs, [&STI](auto Reg) { return STI.isRegisterReservedByUser(Reg.first); })) F.getContext().diagnose(DiagnosticInfoUnsupported{ diff --git a/llvm/tools/llvm-lipo/llvm-lipo.cpp b/llvm/tools/llvm-lipo/llvm-lipo.cpp index 6761f9951e58..7fbe489ecc6f 100644 --- a/llvm/tools/llvm-lipo/llvm-lipo.cpp +++ b/llvm/tools/llvm-lipo/llvm-lipo.cpp @@ -538,9 +538,8 @@ static void updateAlignments(Range &Slices, static void checkUnusedAlignments(ArrayRef Slices, const StringMap &Alignments) { auto HasArch = [&](StringRef Arch) { -return llvm::find_if(Slices, [Arch](Slice S) { - return S.getArchString() == Arch; - }) != Slices.end(); +return llvm::any_of(Slices, +[Arch](Slice S) { return S.getArchString() == Arch; }); }; for (StringRef Arch : Alignments.keys()) if (!HasArch(Arch)) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] da4a637 - [RISCV] Define vpopc/vfirst intrinsics.
Author: Zakk Chen Date: 2020-12-24T19:44:34-08:00 New Revision: da4a637e99170b16e1f15e5cfa5e0b020bd6736d URL: https://github.com/llvm/llvm-project/commit/da4a637e99170b16e1f15e5cfa5e0b020bd6736d DIFF: https://github.com/llvm/llvm-project/commit/da4a637e99170b16e1f15e5cfa5e0b020bd6736d.diff LOG: [RISCV] Define vpopc/vfirst intrinsics. Define vpopc/vfirst intrinsics and lower to V instructions. We work with @rogfer01 from BSC to come out this patch. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D93795 Added: llvm/test/CodeGen/RISCV/rvv/vfirst-rv32.ll llvm/test/CodeGen/RISCV/rvv/vfirst-rv64.ll llvm/test/CodeGen/RISCV/rvv/vpopc-rv32.ll llvm/test/CodeGen/RISCV/rvv/vpopc-rv64.ll Modified: llvm/include/llvm/IR/IntrinsicsRISCV.td llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td Removed: diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 6778b20ac0a8..5e222e7474d2 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -375,6 +375,20 @@ let TargetPrefix = "riscv" in { [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>, LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>, llvm_anyint_ty], [IntrNoMem]>, RISCVVIntrinsic; + // For unary operations with scalar type output without mask + // Output: (scalar type) + // Input: (vector_in, vl) + class RISCVMaskUnarySOutNoMask +: Intrinsic<[llvm_anyint_ty], +[llvm_anyvector_ty, LLVMMatchType<0>], +[IntrNoMem]>, RISCVVIntrinsic; + // For unary operations with scalar type output with mask + // Output: (scalar type) + // Input: (vector_in, mask, vl) + class RISCVMaskUnarySOutMask +: Intrinsic<[llvm_anyint_ty], +[llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<0>], +[IntrNoMem]>, RISCVVIntrinsic; multiclass RISCVUSLoad { def "int_riscv_" # NAME : RISCVUSLoad; @@ -451,6 +465,10 @@ let TargetPrefix = "riscv" in { def "int_riscv_" # NAME : RISCVReductionNoMask; def "int_riscv_" # NAME # "_mask" : RISCVReductionMask; } + multiclass RISCVMaskUnarySOut { +def "int_riscv_" # NAME : RISCVMaskUnarySOutNoMask; +def "int_riscv_" # NAME # "_mask" : RISCVMaskUnarySOutMask; + } defm vle : RISCVUSLoad; defm vleff : RISCVUSLoad; @@ -658,4 +676,8 @@ let TargetPrefix = "riscv" in { def int_riscv_vmnor: RISCVBinaryAAANoMask; def int_riscv_vmornot: RISCVBinaryAAANoMask; def int_riscv_vmxnor: RISCVBinaryAAANoMask; + + defm vpopc : RISCVMaskUnarySOut; + defm vfirst : RISCVMaskUnarySOut; + } // TargetPrefix = "riscv" diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td index c23c650973b3..fd4fb7c3e219 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -188,23 +188,24 @@ class GetIntVTypeInfo VTypeInfo Vti = !cast(!subst("VF", "VI", !cast(vti))); } -class MTypeInfo { +class MTypeInfo { ValueType Mask = Mas; // {SEW, VLMul} values set a valid VType to deal with this mask type. // we assume SEW=8 and set corresponding LMUL. int SEW = 8; LMULInfo LMul = M; + string BX = Bx; // Appendix of mask operations. } defset list AllMasks = { // vbool_t, = SEW/LMUL, we assume SEW=8 and corresponding LMUL. - def : MTypeInfo; - def : MTypeInfo; - def : MTypeInfo; - def : MTypeInfo; - def : MTypeInfo; - def : MTypeInfo; - def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; + def : MTypeInfo; } class VTypeInfoToWide @@ -294,8 +295,15 @@ class PseudoToVInst { !subst("_MF2", "", !subst("_MF4", "", !subst("_MF8", "", + !subst("_B1", "", + !subst("_B2", "", + !subst("_B4", "", + !subst("_B8", "", + !subst("_B16", "", + !subst("_B32", "", + !subst("_B64", "", !subst("_MASK", "", - !subst("Pseudo", "", PseudoInst); + !subst("Pseudo", "", PseudoInst; } // The destination vector register group for a masked vector instruction cannot @@ -499,6 +507,36 @@ class VPseudoUnaryNoDummyMask(PseudoToVInst.VInst); } +class VMaskPseudoUnarySOutNoMask: +Pseudo<(outs GPR:$rd), + (ins VR:$rs1, GPR:$vl, ixlenimm:$sew), []>, +RISCVVPseudo { + let mayLoad = 0; + let mayStore = 0; + let hasSideEffects = 0; + let usesCustomInserter = 1; + let Uses = [VL, VTYPE]; + let VLIndex = 2; + let SEWIndex = 3; + let HasDummyMask = 1; + let BaseInstr = !cast(PseudoT