[llvm-branch-commits] [llvm] b8cb180 - [obj2yaml] - Dump the content of a broken GNU hash table properly.

2020-12-24 Thread Georgii Rymar via llvm-branch-commits

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"

2020-12-24 Thread Nikita Popov via llvm-branch-commits

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

2020-12-24 Thread Evgeniy Brevnov via llvm-branch-commits

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)"

2020-12-24 Thread Nikita Popov via llvm-branch-commits

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

2020-12-24 Thread Evgeniy Brevnov via llvm-branch-commits

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.

2020-12-24 Thread Simon Pilgrim via llvm-branch-commits

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.

2020-12-24 Thread Simon Pilgrim via llvm-branch-commits

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.

2020-12-24 Thread Simon Pilgrim via llvm-branch-commits

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)

2020-12-24 Thread Kazu Hirata via llvm-branch-commits

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)

2020-12-24 Thread Kazu Hirata via llvm-branch-commits

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

2020-12-24 Thread Roman Lebedev via llvm-branch-commits

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

2020-12-24 Thread Roman Lebedev via llvm-branch-commits

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

2020-12-24 Thread Roman Lebedev via llvm-branch-commits

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

2020-12-24 Thread Roman Lebedev via llvm-branch-commits

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

2020-12-24 Thread Roman Lebedev via llvm-branch-commits

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`

2020-12-24 Thread Roman Lebedev via llvm-branch-commits

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

2020-12-24 Thread Roman Lebedev via llvm-branch-commits

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

2020-12-24 Thread Roman Lebedev via llvm-branch-commits

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.

2020-12-24 Thread Zakk Chen via llvm-branch-commits

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)

2020-12-24 Thread Kazu Hirata via llvm-branch-commits

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.

2020-12-24 Thread Zakk Chen via llvm-branch-commits

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