[llvm-branch-commits] [clang] 7d8d30d - [Clang][NFC] Added testcase from #49549

2022-01-31 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2022-01-31T23:43:36+01:00
New Revision: 7d8d30d6d3ddb37230a519bf4ee8144a547e4195

URL: 
https://github.com/llvm/llvm-project/commit/7d8d30d6d3ddb37230a519bf4ee8144a547e4195
DIFF: 
https://github.com/llvm/llvm-project/commit/7d8d30d6d3ddb37230a519bf4ee8144a547e4195.diff

LOG: [Clang][NFC] Added testcase from #49549

The issue is fixed in trunk, so add testcase to avoid regression in the future.

Added: 


Modified: 
clang/test/SemaCXX/attr-likelihood.cpp

Removed: 




diff  --git a/clang/test/SemaCXX/attr-likelihood.cpp 
b/clang/test/SemaCXX/attr-likelihood.cpp
index f7503fed49b93..642d62fa89826 100644
--- a/clang/test/SemaCXX/attr-likelihood.cpp
+++ b/clang/test/SemaCXX/attr-likelihood.cpp
@@ -159,4 +159,18 @@ constexpr int constexpr_function() {
   [[likely]] return 0;
 }
 static_assert(constexpr_function() == 0);
+
+constexpr double pow(double x, long long n) noexcept {
+if (n > 0) [[likely]]
+return x * pow(x, n - 1);
+else [[unlikely]]
+return 1;
+}
+constexpr long long fact(long long n) noexcept {
+if (n > 1) [[likely]]
+return n * fact(n - 1);
+else [[unlikely]]
+return 1;
+}
+
 #endif



___
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] 7a61357 - [AlwaysInliner] Enable call site inlining to make flatten attribute working again (#53360)

2022-01-25 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2022-01-25T22:51:51+01:00
New Revision: 7a61357ea2c3b737ce338452aee058033119fa28

URL: 
https://github.com/llvm/llvm-project/commit/7a61357ea2c3b737ce338452aee058033119fa28
DIFF: 
https://github.com/llvm/llvm-project/commit/7a61357ea2c3b737ce338452aee058033119fa28.diff

LOG: [AlwaysInliner] Enable call site inlining to make flatten attribute 
working again (#53360)

Problem: Migration to new PM broke flatten attribute.

This is one use case why LLVM should support inlining call-site with 
alwaysinline.  The flatten attribute is nowdays broken, so we should either 
land patch like this one or remove everything related to  flatten attribute 
from Clang.

Second use case is something like "per call site inlining intrinsics" to 
control inlining even more; mentioned in
https://lists.llvm.org/pipermail/cfe-dev/2018-September/059232.html

Fixes https://github.com/llvm/llvm-project/issues/53360

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D117965

Added: 


Modified: 
clang/test/CodeGen/flatten.c
clang/test/CodeGenCXX/flatten.cpp
llvm/lib/Transforms/IPO/AlwaysInliner.cpp
llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll
llvm/test/Transforms/Inline/always-inline.ll

Removed: 




diff  --git a/clang/test/CodeGen/flatten.c b/clang/test/CodeGen/flatten.c
index 287d4f2a46b65..4e762223de486 100644
--- a/clang/test/CodeGen/flatten.c
+++ b/clang/test/CodeGen/flatten.c
@@ -1,9 +1,3 @@
-// UNSUPPORTED: experimental-new-pass-manager
-// Currently, 
diff erent code seems to be intentionally generated under the new
-// PM since we alwaysinline functions and not callsites under new PM.
-// Under new PM, f() will not be inlined from g() since f is not marked as
-// alwaysinline.
-
 // RUN: %clang_cc1 -triple=x86_64-linux-gnu %s -emit-llvm -o - | FileCheck %s
 
 void f(void) {}

diff  --git a/clang/test/CodeGenCXX/flatten.cpp 
b/clang/test/CodeGenCXX/flatten.cpp
index 7a6484591aaa0..e988d6d726dd7 100644
--- a/clang/test/CodeGenCXX/flatten.cpp
+++ b/clang/test/CodeGenCXX/flatten.cpp
@@ -1,7 +1,3 @@
-// UNSUPPORTED: experimental-new-pass-manager
-// See the comment for CodeGen/flatten.c on why this is unsupported with the 
new
-// PM.
-
 // RUN: %clang_cc1 -triple=x86_64-linux-gnu -std=c++11 %s -emit-llvm -o - | 
FileCheck %s
 
 void f(void) {}

diff  --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp 
b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index 7acc9b266ad82..8f20f59b5e4d7 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -54,13 +54,13 @@ PreservedAnalyses AlwaysInlinerPass::run(Module ,
 if (F.isPresplitCoroutine())
   continue;
 
-if (!F.isDeclaration() && F.hasFnAttribute(Attribute::AlwaysInline) &&
-isInlineViable(F).isSuccess()) {
+if (!F.isDeclaration() && isInlineViable(F).isSuccess()) {
   Calls.clear();
 
   for (User *U : F.users())
 if (auto *CB = dyn_cast(U))
-  if (CB->getCalledFunction() == )
+  if (CB->getCalledFunction() ==  &&
+  CB->hasFnAttr(Attribute::AlwaysInline))
 Calls.insert(CB);
 
   for (CallBase *CB : Calls) {

diff  --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll 
b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll
index d805d7549231d..5d62747180233 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll
@@ -3,9 +3,7 @@
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.12.0"
 
-; CHECK: define internal { i8*, i32 } @f(i8* %buffer, i32* %array)
-; CHECK-NEXT: entry:
-; CHECK-NEXT:  unreachable
+; CHECK-NOT: define {{.*}} @f(i8* %buffer, i32* %array)
 
 define internal {i8*, i32} @f(i8* %buffer, i32* %array) {
 entry:

diff  --git a/llvm/test/Transforms/Inline/always-inline.ll 
b/llvm/test/Transforms/Inline/always-inline.ll
index 0fcf956199c46..8eb3d020f6634 100644
--- a/llvm/test/Transforms/Inline/always-inline.ll
+++ b/llvm/test/Transforms/Inline/always-inline.ll
@@ -1,14 +1,11 @@
-; RUN: opt < %s -inline-threshold=0 -always-inline -enable-new-pm=0 -S | 
FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CALL
+; RUN: opt < %s -inline-threshold=0 -always-inline -enable-new-pm=0 -S | 
FileCheck %s --check-prefix=CHECK
 ;
 ; Ensure the threshold has no impact on these decisions.
-; RUN: opt < %s -inline-threshold=2000 -always-inline -enable-new-pm=0 -S 
| FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CALL
-; RUN: opt < %s -inline-threshold=-2000 -always-inline -enable-new-pm=0 -S 
| FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CALL
+; RUN: opt < %s -inline-threshold=2000 -always-inline -enable-new-pm=0 -S 
| FileCheck %s --check-prefix=CHECK
+; RUN: opt < %s -inline-threshold=-2000 

[llvm-branch-commits] [llvm] bb3f169 - [BuildLibcalls, Attrs] Support more variants of C++'s new, add attributes for C++'s delete

2021-01-20 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-21T00:12:37+01:00
New Revision: bb3f169b59e1c8bd7fd70097532220bbd11e9967

URL: 
https://github.com/llvm/llvm-project/commit/bb3f169b59e1c8bd7fd70097532220bbd11e9967
DIFF: 
https://github.com/llvm/llvm-project/commit/bb3f169b59e1c8bd7fd70097532220bbd11e9967.diff

LOG: [BuildLibcalls, Attrs] Support more variants of C++'s new, add attributes 
for C++'s delete

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D95095

Added: 


Modified: 
llvm/lib/Transforms/Utils/BuildLibCalls.cpp
llvm/test/Transforms/InferFunctionAttrs/annotate.ll

Removed: 




diff  --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp 
b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index 857c3d915e8c..a14c30071399 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -1001,10 +1001,52 @@ bool llvm::inferLibFuncAttributes(Function , const 
TargetLibraryInfo ) {
 Changed |= setDoesNotCapture(F, 0);
 Changed |= setDoesNotCapture(F, 1);
 return Changed;
+  case LibFunc_ZdlPvRKSt9nothrow_t: // delete(void*, nothrow)
+  case LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t: // delete(void*, 
align_val_t, nothrow)
+  case LibFunc_ZdaPvRKSt9nothrow_t: // delete[](void*, nothrow)
+  case LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t: // delete[](void*, 
align_val_t, nothrow)
+Changed |= setDoesNotThrow(F);
+LLVM_FALLTHROUGH;
+  case LibFunc_ZdlPv: // delete(void*)
+  case LibFunc_ZdlPvj: // delete(void*, unsigned int)
+  case LibFunc_ZdlPvm: // delete(void*, unsigned long)
+  case LibFunc_ZdaPv: // delete[](void*)
+  case LibFunc_ZdaPvj: // delete[](void*, unsigned int)
+  case LibFunc_ZdaPvm: // delete[](void*, unsigned long)
+  case LibFunc_ZdlPvSt11align_val_t: // delete(void*, align_val_t)
+  case LibFunc_ZdlPvjSt11align_val_t: // delete(void*, unsigned int, 
align_val_t)
+  case LibFunc_ZdlPvmSt11align_val_t: // delete(void*, unsigned long, 
align_val_t)
+  case LibFunc_ZdaPvSt11align_val_t: // delete[](void*, align_val_t)
+  case LibFunc_ZdaPvjSt11align_val_t: // delete[](void*, unsigned int, 
align_val_t)
+  case LibFunc_ZdaPvmSt11align_val_t: // delete[](void*, unsigned long, 
align_val_t);
+Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
+Changed |= setArgsNoUndef(F);
+Changed |= setWillReturn(F);
+Changed |= setDoesNotCapture(F, 0);
+return Changed;
+  case LibFunc_ZnwjRKSt9nothrow_t: // new(unsigned int, nothrow)
+  case LibFunc_ZnwmRKSt9nothrow_t: // new(unsigned long, nothrow)
+  case LibFunc_ZnajRKSt9nothrow_t: // new[](unsigned int, nothrow)
+  case LibFunc_ZnamRKSt9nothrow_t: // new[](unsigned long, nothrow)
+  case LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t: // new(unsigned int, 
align_val_t, nothrow)
+  case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t: // new(unsigned long, 
align_val_t, nothrow)
+  case LibFunc_ZnajSt11align_val_tRKSt9nothrow_t: // new[](unsigned int, 
align_val_t, nothrow)
+  case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t: // new[](unsigned long, 
align_val_t, nothrow)
+// Nothrow operator new may return null pointer
+Changed |= setDoesNotThrow(F);
+Changed |= setOnlyAccessesInaccessibleMemory(F);
+Changed |= setRetNoUndef(F);
+Changed |= setRetDoesNotAlias(F);
+Changed |= setWillReturn(F);
+return Changed;
   case LibFunc_Znwj: // new(unsigned int)
   case LibFunc_Znwm: // new(unsigned long)
   case LibFunc_Znaj: // new[](unsigned int)
   case LibFunc_Znam: // new[](unsigned long)
+  case LibFunc_ZnwjSt11align_val_t: // new(unsigned int, align_val_t)
+  case LibFunc_ZnwmSt11align_val_t: // new(unsigned long, align_val_t)
+  case LibFunc_ZnajSt11align_val_t: // new[](unsigned int, align_val_t)
+  case LibFunc_ZnamSt11align_val_t: // new[](unsigned long, align_val_t)
   case LibFunc_msvc_new_int: // new(unsigned int)
   case LibFunc_msvc_new_longlong: // new(unsigned long long)
   case LibFunc_msvc_new_array_int: // new[](unsigned int)

diff  --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll 
b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
index 0af18151d6f6..a847db7eb550 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -9,6 +9,30 @@ declare i8* @_Znwj(i64 )
 ; CHECK: declare noalias noundef nonnull i8* @_Znwj(i64) 
[[INACCESSIBLEMEMONLY_NOFREE_WILLRETURN:#[0-9]+]]
 declare i8* @_Znwm(i64)
 ; CHECK: declare noalias noundef nonnull i8* @_Znwm(i64) 
[[INACCESSIBLEMEMONLY_NOFREE_WILLRETURN]]
+declare i8* @_Znaj(i64)
+; CHECK: declare noalias noundef nonnull i8* @_Znaj(i64) 
[[INACCESSIBLEMEMONLY_NOFREE_WILLRETURN]]
+declare i8* @_Znam(i64)
+; CHECK: declare noalias noundef nonnull i8* @_Znam(i64) 
[[INACCESSIBLEMEMONLY_NOFREE_WILLRETURN]]
+
+
+%"struct.std::nothrow_t" = type { i8 }
+declare i8* @_ZnwmRKSt9nothrow_t(i64, %"struct.std::nothrow_t"*)
+; 

[llvm-branch-commits] [llvm] 16d6e85 - [BuildLibcalls] Mark some libcalls with inaccessiblememonly and inaccessiblemem_or_argmemonly

2021-01-20 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-20T19:45:23+01:00
New Revision: 16d6e8527189298c75bf5690c771e8ab6dc3628d

URL: 
https://github.com/llvm/llvm-project/commit/16d6e8527189298c75bf5690c771e8ab6dc3628d
DIFF: 
https://github.com/llvm/llvm-project/commit/16d6e8527189298c75bf5690c771e8ab6dc3628d.diff

LOG: [BuildLibcalls] Mark some libcalls with inaccessiblememonly and 
inaccessiblemem_or_argmemonly

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D94850

Added: 


Modified: 
llvm/lib/Transforms/Utils/BuildLibCalls.cpp
llvm/test/Transforms/InferFunctionAttrs/annotate.ll

Removed: 




diff  --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp 
b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index d2ffb99274e3..857c3d915e8c 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -31,8 +31,12 @@ using namespace llvm;
 //- Infer Attributes 
-//
 
 STATISTIC(NumReadNone, "Number of functions inferred as readnone");
+STATISTIC(NumInaccessibleMemOnly,
+  "Number of functions inferred as inaccessiblememonly");
 STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
 STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
+STATISTIC(NumInaccessibleMemOrArgMemOnly,
+  "Number of functions inferred as inaccessiblemem_or_argmemonly");
 STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
 STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
 STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");
@@ -52,6 +56,14 @@ static bool setDoesNotAccessMemory(Function ) {
   return true;
 }
 
+static bool setOnlyAccessesInaccessibleMemory(Function ) {
+  if (F.onlyAccessesInaccessibleMemory())
+return false;
+  F.setOnlyAccessesInaccessibleMemory();
+  ++NumInaccessibleMemOnly;
+  return true;
+}
+
 static bool setOnlyReadsMemory(Function ) {
   if (F.onlyReadsMemory())
 return false;
@@ -68,6 +80,14 @@ static bool setOnlyAccessesArgMemory(Function ) {
   return true;
 }
 
+static bool setOnlyAccessesInaccessibleMemOrArgMem(Function ) {
+  if (F.onlyAccessesInaccessibleMemOrArgMem())
+return false;
+  F.setOnlyAccessesInaccessibleMemOrArgMem();
+  ++NumInaccessibleMemOrArgMemOnly;
+  return true;
+}
+
 static bool setDoesNotThrow(Function ) {
   if (F.doesNotThrow())
 return false;
@@ -315,6 +335,7 @@ bool llvm::inferLibFuncAttributes(Function , const 
TargetLibraryInfo ) {
 return Changed;
   case LibFunc_strdup:
   case LibFunc_strndup:
+Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
 Changed |= setDoesNotThrow(F);
 Changed |= setRetDoesNotAlias(F);
 Changed |= setWillReturn(F);
@@ -370,6 +391,7 @@ bool llvm::inferLibFuncAttributes(Function , const 
TargetLibraryInfo ) {
 Changed |= setOnlyReadsMemory(F, 0);
 return Changed;
   case LibFunc_malloc:
+Changed |= setOnlyAccessesInaccessibleMemory(F);
 Changed |= setRetNoUndef(F);
 Changed |= setDoesNotThrow(F);
 Changed |= setRetDoesNotAlias(F);
@@ -432,6 +454,9 @@ bool llvm::inferLibFuncAttributes(Function , const 
TargetLibraryInfo ) {
 Changed |= setDoesNotThrow(F);
 return Changed;
   case LibFunc_memalign:
+Changed |= setOnlyAccessesInaccessibleMemory(F);
+Changed |= setRetNoUndef(F);
+Changed |= setDoesNotThrow(F);
 Changed |= setRetDoesNotAlias(F);
 Changed |= setWillReturn(F);
 return Changed;
@@ -448,6 +473,7 @@ bool llvm::inferLibFuncAttributes(Function , const 
TargetLibraryInfo ) {
 Changed |= setDoesNotCapture(F, 0);
 return Changed;
   case LibFunc_realloc:
+Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
 Changed |= setRetNoUndef(F);
 Changed |= setDoesNotThrow(F);
 Changed |= setRetDoesNotAlias(F);
@@ -498,6 +524,7 @@ bool llvm::inferLibFuncAttributes(Function , const 
TargetLibraryInfo ) {
 Changed |= setOnlyReadsMemory(F, 1);
 return Changed;
   case LibFunc_aligned_alloc:
+Changed |= setOnlyAccessesInaccessibleMemory(F);
 Changed |= setRetNoUndef(F);
 Changed |= setDoesNotThrow(F);
 Changed |= setRetDoesNotAlias(F);
@@ -528,6 +555,7 @@ bool llvm::inferLibFuncAttributes(Function , const 
TargetLibraryInfo ) {
 Changed |= setOnlyWritesMemory(F, 0);
 return Changed;
   case LibFunc_calloc:
+Changed |= setOnlyAccessesInaccessibleMemory(F);
 Changed |= setRetNoUndef(F);
 Changed |= setDoesNotThrow(F);
 Changed |= setRetDoesNotAlias(F);
@@ -584,6 +612,7 @@ bool llvm::inferLibFuncAttributes(Function , const 
TargetLibraryInfo ) {
 Changed |= setDoesNotCapture(F, 0);
 return Changed;
   case LibFunc_free:
+Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
 Changed |= setArgsNoUndef(F);
 Changed |= setDoesNotThrow(F);
 Changed |= setWillReturn(F);
@@ 

[llvm-branch-commits] [llvm] ed39621 - [InstCombine] Transform abs pattern using multiplication to abs intrinsic (PR45691)

2021-01-17 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-17T17:06:14+01:00
New Revision: ed396212da41feed9bffb8cc1ca6518ab031a3c7

URL: 
https://github.com/llvm/llvm-project/commit/ed396212da41feed9bffb8cc1ca6518ab031a3c7
DIFF: 
https://github.com/llvm/llvm-project/commit/ed396212da41feed9bffb8cc1ca6518ab031a3c7.diff

LOG: [InstCombine] Transform abs pattern using multiplication to abs intrinsic 
(PR45691)

```
unsigned r(int v)
{
return (1 | -(v < 0)) * v;
}

`r` is equivalent to `abs(v)`.

```

```
define <4 x i8> @src(<4 x i8> %0) {
%1:
  %2 = ashr <4 x i8> %0, { 31, undef, 31, 31 }
  %3 = or <4 x i8> %2, { 1, 1, 1, undef }
  %4 = mul nsw <4 x i8> %3, %0
  ret <4 x i8> %4
}
=>
define <4 x i8> @tgt(<4 x i8> %0) {
%1:
  %2 = icmp slt <4 x i8> %0, { 0, 0, 0, 0 }
  %3 = sub nsw <4 x i8> { 0, 0, 0, 0 }, %0
  %4 = select <4 x i1> %2, <4 x i8> %3, <4 x i8> %0
  ret <4 x i8> %4
}
Transformation seems to be correct!
```

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D94874

Added: 


Modified: 
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll

Removed: 




diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 2da7415b908b..4b485a0ad85e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -153,8 +153,10 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator ) 
{
   if (Value *V = SimplifyUsingDistributiveLaws(I))
 return replaceInstUsesWith(I, V);
 
-  // X * -1 == 0 - X
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+  unsigned BitWidth = I.getType()->getScalarSizeInBits();
+
+  // X * -1 == 0 - X
   if (match(Op1, m_AllOnes())) {
 BinaryOperator *BO = BinaryOperator::CreateNeg(Op0, I.getName());
 if (I.hasNoSignedWrap())
@@ -360,6 +362,19 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator ) 
{
   if (match(Op1, m_LShr(m_Value(X), m_APInt(C))) && *C == C->getBitWidth() - 1)
 return BinaryOperator::CreateAnd(Builder.CreateAShr(X, *C), Op0);
 
+  // ((ashr X, 31) | 1) * X --> abs(X)
+  // X * ((ashr X, 31) | 1) --> abs(X)
+  if (match(, m_c_BinOp(m_Or(m_AShr(m_Value(X),
+m_SpecificIntAllowUndef(BitWidth - 1)),
+ m_One()),
+m_Deferred(X {
+Value *Abs = Builder.CreateBinaryIntrinsic(
+Intrinsic::abs, X,
+ConstantInt::getBool(I.getContext(), I.hasNoSignedWrap()));
+Abs->takeName();
+return replaceInstUsesWith(I, Abs);
+  }
+
   if (Instruction *Ext = narrowMathIfNoOverflow(I))
 return Ext;
 

diff  --git a/llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll 
b/llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll
index 1874378f1f1f..ab390a209340 100644
--- a/llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll
+++ b/llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll
@@ -6,9 +6,7 @@
 
 define i32 @ashr_or_mul_to_abs(i32 %X) {
 ; CHECK-LABEL: @ashr_or_mul_to_abs(
-; CHECK-NEXT:[[I:%.*]] = ashr i32 [[X:%.*]], 31
-; CHECK-NEXT:[[I1:%.*]] = or i32 [[I]], 1
-; CHECK-NEXT:[[I2:%.*]] = mul nsw i32 [[I1]], [[X]]
+; CHECK-NEXT:[[I2:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
 ; CHECK-NEXT:ret i32 [[I2]]
 ;
   %i = ashr i32 %X, 31
@@ -19,9 +17,7 @@ define i32 @ashr_or_mul_to_abs(i32 %X) {
 
 define i32 @ashr_or_mul_to_abs2(i32 %X) {
 ; CHECK-LABEL: @ashr_or_mul_to_abs2(
-; CHECK-NEXT:[[I:%.*]] = ashr i32 [[X:%.*]], 31
-; CHECK-NEXT:[[I1:%.*]] = or i32 [[I]], 1
-; CHECK-NEXT:[[I2:%.*]] = mul i32 [[I1]], [[X]]
+; CHECK-NEXT:[[I2:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
 ; CHECK-NEXT:ret i32 [[I2]]
 ;
   %i = ashr i32 %X, 31
@@ -30,13 +26,13 @@ define i32 @ashr_or_mul_to_abs2(i32 %X) {
   ret i32 %i2
 }
 
-define i32 @ashr_or_mul_to_abs3(i32 %X) {
+define i32 @ashr_or_mul_to_abs3(i32 %PX) {
 ; CHECK-LABEL: @ashr_or_mul_to_abs3(
-; CHECK-NEXT:[[I:%.*]] = ashr i32 [[X:%.*]], 31
-; CHECK-NEXT:[[I1:%.*]] = or i32 [[I]], 1
-; CHECK-NEXT:[[I2:%.*]] = mul i32 [[I1]], [[X]]
+; CHECK-NEXT:[[X:%.*]] = sdiv i32 42, [[PX:%.*]]
+; CHECK-NEXT:[[I2:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false)
 ; CHECK-NEXT:ret i32 [[I2]]
 ;
+  %X = sdiv i32 42, %PX ; thwart complexity-based canonicalization
   %i = ashr i32 %X, 31
   %i1 = or i32 %i, 1
   %i2 = mul i32 %X, %i1
@@ -46,9 +42,7 @@ define i32 @ashr_or_mul_to_abs3(i32 %X) {
 
 define <4 x i32> @ashr_or_mul_to_abs_vec(<4 x i32> %X) {
 ; CHECK-LABEL: @ashr_or_mul_to_abs_vec(
-; CHECK-NEXT:[[I:%.*]] = ashr <4 x i32> [[X:%.*]], 
-; CHECK-NEXT:[[I1:%.*]] = or <4 x i32> [[I]], 
-; CHECK-NEXT:[[I2:%.*]] = mul <4 x i32> [[I1]], [[X]]
+; CHECK-NEXT:[[I2:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> 
[[X:%.*]], i1 

[llvm-branch-commits] [llvm] 469ceaf - [Tests] Add test for PR45691

2021-01-17 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-17T17:04:49+01:00
New Revision: 469ceaf53892d26f7b68f86f1feb38fe7057815e

URL: 
https://github.com/llvm/llvm-project/commit/469ceaf53892d26f7b68f86f1feb38fe7057815e
DIFF: 
https://github.com/llvm/llvm-project/commit/469ceaf53892d26f7b68f86f1feb38fe7057815e.diff

LOG: [Tests] Add test for PR45691

Added: 
llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll

Modified: 


Removed: 




diff  --git a/llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll 
b/llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll
new file mode 100644
index ..1874378f1f1f
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/ashr-or-mul-abs.ll
@@ -0,0 +1,112 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; ((ashr X, 31) | 1 ) * X --> abs(X)
+; X * ((ashr X, 31) | 1 ) --> abs(X)
+
+define i32 @ashr_or_mul_to_abs(i32 %X) {
+; CHECK-LABEL: @ashr_or_mul_to_abs(
+; CHECK-NEXT:[[I:%.*]] = ashr i32 [[X:%.*]], 31
+; CHECK-NEXT:[[I1:%.*]] = or i32 [[I]], 1
+; CHECK-NEXT:[[I2:%.*]] = mul nsw i32 [[I1]], [[X]]
+; CHECK-NEXT:ret i32 [[I2]]
+;
+  %i = ashr i32 %X, 31
+  %i1 = or i32 %i, 1
+  %i2 = mul nsw i32 %i1, %X
+  ret i32 %i2
+}
+
+define i32 @ashr_or_mul_to_abs2(i32 %X) {
+; CHECK-LABEL: @ashr_or_mul_to_abs2(
+; CHECK-NEXT:[[I:%.*]] = ashr i32 [[X:%.*]], 31
+; CHECK-NEXT:[[I1:%.*]] = or i32 [[I]], 1
+; CHECK-NEXT:[[I2:%.*]] = mul i32 [[I1]], [[X]]
+; CHECK-NEXT:ret i32 [[I2]]
+;
+  %i = ashr i32 %X, 31
+  %i1 = or i32 %i, 1
+  %i2 = mul i32 %i1, %X
+  ret i32 %i2
+}
+
+define i32 @ashr_or_mul_to_abs3(i32 %X) {
+; CHECK-LABEL: @ashr_or_mul_to_abs3(
+; CHECK-NEXT:[[I:%.*]] = ashr i32 [[X:%.*]], 31
+; CHECK-NEXT:[[I1:%.*]] = or i32 [[I]], 1
+; CHECK-NEXT:[[I2:%.*]] = mul i32 [[I1]], [[X]]
+; CHECK-NEXT:ret i32 [[I2]]
+;
+  %i = ashr i32 %X, 31
+  %i1 = or i32 %i, 1
+  %i2 = mul i32 %X, %i1
+  ret i32 %i2
+}
+
+
+define <4 x i32> @ashr_or_mul_to_abs_vec(<4 x i32> %X) {
+; CHECK-LABEL: @ashr_or_mul_to_abs_vec(
+; CHECK-NEXT:[[I:%.*]] = ashr <4 x i32> [[X:%.*]], 
+; CHECK-NEXT:[[I1:%.*]] = or <4 x i32> [[I]], 
+; CHECK-NEXT:[[I2:%.*]] = mul <4 x i32> [[I1]], [[X]]
+; CHECK-NEXT:ret <4 x i32> [[I2]]
+;
+  %i = ashr <4 x i32> %X, 
+  %i1 = or <4 x i32> %i, 
+  %i2 = mul <4 x i32> %i1, %X
+  ret <4 x i32> %i2
+}
+
+define <4 x i32> @ashr_or_mul_to_abs_vec2(<4 x i32> %X) {
+; CHECK-LABEL: @ashr_or_mul_to_abs_vec2(
+; CHECK-NEXT:[[I:%.*]] = ashr <4 x i32> [[X:%.*]], 
+; CHECK-NEXT:[[I1:%.*]] = or <4 x i32> [[I]], 
+; CHECK-NEXT:[[I2:%.*]] = mul nsw <4 x i32> [[I1]], [[X]]
+; CHECK-NEXT:ret <4 x i32> [[I2]]
+;
+  %i = ashr <4 x i32> %X, 
+  %i1 = or <4 x i32> %i, 
+  %i2 = mul nsw <4 x i32> %i1, %X
+  ret <4 x i32> %i2
+}
+
+define <4 x i32> @ashr_or_mul_to_abs_vec3_undef(<4 x i32> %X) {
+; CHECK-LABEL: @ashr_or_mul_to_abs_vec3_undef(
+; CHECK-NEXT:[[I:%.*]] = ashr <4 x i32> [[X:%.*]], 
+; CHECK-NEXT:[[I1:%.*]] = or <4 x i32> [[I]], 
+; CHECK-NEXT:[[I2:%.*]] = mul <4 x i32> [[I1]], [[X]]
+; CHECK-NEXT:ret <4 x i32> [[I2]]
+;
+  %i = ashr <4 x i32> %X, 
+  %i1 = or <4 x i32> %i, 
+  %i2 = mul <4 x i32> %i1, %X
+  ret <4 x i32> %i2
+}
+
+; Negative tests
+
+define i32 @ashr_or_mul_to_abs_neg(i32 %X) {
+; CHECK-LABEL: @ashr_or_mul_to_abs_neg(
+; CHECK-NEXT:[[I:%.*]] = ashr i32 [[X:%.*]], 30
+; CHECK-NEXT:[[I1:%.*]] = or i32 [[I]], 1
+; CHECK-NEXT:[[I2:%.*]] = mul nsw i32 [[I1]], [[X]]
+; CHECK-NEXT:ret i32 [[I2]]
+;
+  %i = ashr i32 %X, 30
+  %i1 = or i32 %i, 1
+  %i2 = mul nsw i32 %i1, %X
+  ret i32 %i2
+}
+
+define i32 @ashr_or_mul_to_abs_neg2(i32 %X) {
+; CHECK-LABEL: @ashr_or_mul_to_abs_neg2(
+; CHECK-NEXT:[[I:%.*]] = ashr i32 [[X:%.*]], 31
+; CHECK-NEXT:[[I1:%.*]] = or i32 [[I]], 2
+; CHECK-NEXT:[[I2:%.*]] = mul nsw i32 [[I1]], [[X]]
+; CHECK-NEXT:ret i32 [[I2]]
+;
+  %i = ashr i32 %X, 31
+  %i1 = or i32 %i, 2
+  %i2 = mul nsw i32 %i1, %X
+  ret i32 %i2
+}



___
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] bfd75bd - [NFC] Removed extra text in comments

2021-01-16 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-16T22:48:56+01:00
New Revision: bfd75bdf3fd62d4f5e7028d4122f9ffa517f2a09

URL: 
https://github.com/llvm/llvm-project/commit/bfd75bdf3fd62d4f5e7028d4122f9ffa517f2a09
DIFF: 
https://github.com/llvm/llvm-project/commit/bfd75bdf3fd62d4f5e7028d4122f9ffa517f2a09.diff

LOG: [NFC] Removed extra text in comments

Added: 


Modified: 
llvm/lib/Analysis/InstructionSimplify.cpp

Removed: 




diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index 6a065c46d9bf..b672798aaffc 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2236,7 +2236,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, 
const SimplifyQuery ,
 
   // Commute the 'or' operands.
   // (A ^ B) | (A & ~B) -> (A ^ B)
-  // (A ^ B) | (~B & A) -> (A ^ B)D94870
+  // (A ^ B) | (~B & A) -> (A ^ B)
   // (B ^ A) | (A & ~B) -> (B ^ A)
   // (B ^ A) | (~B & A) -> (B ^ A)
   if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&



___
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] 63bedc8 - [InstSimplify] Handle commutativity for 'and' and 'outer or' for (~A & B) | ~(A | B) --> ~A

2021-01-16 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-16T19:42:50+01:00
New Revision: 63bedc80da36cf5eb71b06b453c186e057607bf4

URL: 
https://github.com/llvm/llvm-project/commit/63bedc80da36cf5eb71b06b453c186e057607bf4
DIFF: 
https://github.com/llvm/llvm-project/commit/63bedc80da36cf5eb71b06b453c186e057607bf4.diff

LOG: [InstSimplify] Handle commutativity for 'and' and 'outer or' for (~A & B) 
| ~(A | B) --> ~A

Reviewed By: lebedev.ri

Differential Revision: https://reviews.llvm.org/D94870

Added: 


Modified: 
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/or.ll

Removed: 




diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index 73f046dcb8de..6a065c46d9bf 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2224,7 +2224,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, 
const SimplifyQuery ,
   if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Or))
 return V;
 
-  Value *A, *B;
+  Value *A, *B, *NotA;
   // (A & ~B) | (A ^ B) -> (A ^ B)
   // (~B & A) | (A ^ B) -> (A ^ B)
   // (A & ~B) | (B ^ A) -> (B ^ A)
@@ -2236,7 +2236,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, 
const SimplifyQuery ,
 
   // Commute the 'or' operands.
   // (A ^ B) | (A & ~B) -> (A ^ B)
-  // (A ^ B) | (~B & A) -> (A ^ B)
+  // (A ^ B) | (~B & A) -> (A ^ B)D94870
   // (B ^ A) | (A & ~B) -> (B ^ A)
   // (B ^ A) | (~B & A) -> (B ^ A)
   if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
@@ -2253,6 +2253,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, 
const SimplifyQuery ,
match(Op1, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)
 return Op1;
 
+  // Commute the 'or' operands.
   // (~A ^ B) | (A & B) -> (~A ^ B)
   // (~A ^ B) | (B & A) -> (~A ^ B)
   // (B ^ ~A) | (A & B) -> (B ^ ~A)
@@ -2266,9 +2267,20 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, 
const SimplifyQuery ,
   // (~A & B) | ~(B | A) --> ~A
   // (B & ~A) | ~(A | B) --> ~A
   // (B & ~A) | ~(B | A) --> ~A
-  if (match(Op0, m_And(m_Not(m_Value(A)), m_Value(B))) &&
+  if (match(Op0, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
+ m_Value(B))) &&
   match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)
-return cast(Op0)->getOperand(0);
+return NotA;
+
+  // Commute the 'or' operands.
+  // ~(A | B) | (~A & B) --> ~A
+  // ~(B | A) | (~A & B) --> ~A
+  // ~(A | B) | (B & ~A) --> ~A
+  // ~(B | A) | (B & ~A) --> ~A
+  if (match(Op1, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
+ m_Value(B))) &&
+  match(Op0, m_Not(m_c_Or(m_Specific(A), m_Specific(B)
+return NotA;
 
   if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, false))
 return V;

diff  --git a/llvm/test/Transforms/InstSimplify/or.ll 
b/llvm/test/Transforms/InstSimplify/or.ll
index 68d2af4a4041..7f347193be9a 100644
--- a/llvm/test/Transforms/InstSimplify/or.ll
+++ b/llvm/test/Transforms/InstSimplify/or.ll
@@ -399,11 +399,7 @@ define i32 @and_or_not_or4_use3(i32 %A, i32 %B) {
 define i32 @and_or_not_or5(i32 %A, i32 %B) {
 ; CHECK-LABEL: @and_or_not_or5(
 ; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:[[I2:%.*]] = and i32 [[B:%.*]], [[I]]
-; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
-; CHECK-NEXT:[[I5:%.*]] = or i32 [[I2]], [[I4]]
-; CHECK-NEXT:ret i32 [[I5]]
+; CHECK-NEXT:ret i32 [[I]]
 ;
   %i = xor i32 %A, -1
   %i2 = and i32 %B, %i
@@ -416,11 +412,7 @@ define i32 @and_or_not_or5(i32 %A, i32 %B) {
 define i32 @and_or_not_or6(i32 %A, i32 %B) {
 ; CHECK-LABEL: @and_or_not_or6(
 ; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[B:%.*]]
-; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
-; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
-; CHECK-NEXT:ret i32 [[I5]]
+; CHECK-NEXT:ret i32 [[I]]
 ;
   %i = xor i32 %A, -1
   %i2 = and i32 %i, %B
@@ -433,11 +425,7 @@ define i32 @and_or_not_or6(i32 %A, i32 %B) {
 define i32 @and_or_not_or7(i32 %A, i32 %B) {
 ; CHECK-LABEL: @and_or_not_or7(
 ; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:[[I2:%.*]] = and i32 [[B:%.*]], [[I]]
-; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
-; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
-; CHECK-NEXT:ret i32 [[I5]]
+; CHECK-NEXT:ret i32 [[I]]
 ;
   %i = xor i32 %A, -1
   %i2 = and i32 %B, %i
@@ -450,11 +438,7 @@ define i32 @and_or_not_or7(i32 %A, i32 %B) {
 define i32 @and_or_not_or8(i32 %A, i32 %B) {
 ; CHECK-LABEL: @and_or_not_or8(
 ; CHECK-NEXT:[[I:%.*]] = xor i32 [[B:%.*]], -1
-; CHECK-NEXT:[[I2:%.*]] = and i32 [[A:%.*]], [[I]]
-; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], 

[llvm-branch-commits] [llvm] 416854d - [InstSimplify] Precommit new testcases; NFC

2021-01-16 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-16T19:11:58+01:00
New Revision: 416854d0f7cda90def07e9b4aee14505f222b0b3

URL: 
https://github.com/llvm/llvm-project/commit/416854d0f7cda90def07e9b4aee14505f222b0b3
DIFF: 
https://github.com/llvm/llvm-project/commit/416854d0f7cda90def07e9b4aee14505f222b0b3.diff

LOG: [InstSimplify] Precommit new testcases; NFC

Added: 


Modified: 
llvm/test/Transforms/InstSimplify/or.ll

Removed: 




diff  --git a/llvm/test/Transforms/InstSimplify/or.ll 
b/llvm/test/Transforms/InstSimplify/or.ll
index 7e7361d12395..68d2af4a4041 100644
--- a/llvm/test/Transforms/InstSimplify/or.ll
+++ b/llvm/test/Transforms/InstSimplify/or.ll
@@ -395,3 +395,71 @@ define i32 @and_or_not_or4_use3(i32 %A, i32 %B) {
   %i5 = or i32 %i4, %i2
   ret i32 %i5
 }
+
+define i32 @and_or_not_or5(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or5(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:[[I2:%.*]] = and i32 [[B:%.*]], [[I]]
+; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
+; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I2]], [[I4]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %B, %i
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i2, %i4
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or6(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or6(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[B:%.*]]
+; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
+; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %i, %B
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or7(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or7(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:[[I2:%.*]] = and i32 [[B:%.*]], [[I]]
+; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
+; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %B, %i
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or8(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or8(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT:[[I2:%.*]] = and i32 [[A:%.*]], [[I]]
+; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
+; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = xor i32 %B, -1
+  %i2 = and i32 %A, %i
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}



___
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] bdd4dda - [InstSimplify] Update comments, remove redundant tests

2021-01-16 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-16T16:31:23+01:00
New Revision: bdd4dda58b0de08bd3474fb8d4589a9ba9349e88

URL: 
https://github.com/llvm/llvm-project/commit/bdd4dda58b0de08bd3474fb8d4589a9ba9349e88
DIFF: 
https://github.com/llvm/llvm-project/commit/bdd4dda58b0de08bd3474fb8d4589a9ba9349e88.diff

LOG: [InstSimplify] Update comments, remove redundant tests

Added: 


Modified: 
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstCombine/or.ll

Removed: 




diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index 6266e922f8c9..73f046dcb8de 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2264,6 +2264,8 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, 
const SimplifyQuery ,
 
   // (~A & B) | ~(A | B) --> ~A
   // (~A & B) | ~(B | A) --> ~A
+  // (B & ~A) | ~(A | B) --> ~A
+  // (B & ~A) | ~(B | A) --> ~A
   if (match(Op0, m_And(m_Not(m_Value(A)), m_Value(B))) &&
   match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)
 return cast(Op0)->getOperand(0);

diff  --git a/llvm/test/Transforms/InstCombine/or.ll 
b/llvm/test/Transforms/InstCombine/or.ll
index 0fc75fe082f8..22ba395ebe9f 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -1369,113 +1369,3 @@ define i32 @test5_use3(i32 %x, i32 %y) {
   %or1 = or i32 %xor, %neg
   ret i32 %or1
 }
-
-define i32 @test6(i32 %A, i32 %B) {
-; CHECK-LABEL: @test6(
-; CHECK-NEXT:[[I:%.*]] = xor i32 [[B:%.*]], -1
-; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[A:%.*]]
-; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
-; CHECK-NEXT:[[I5:%.*]] = or i32 [[I2]], [[I4]]
-; CHECK-NEXT:ret i32 [[I5]]
-;
-  %i = xor i32 %B, -1
-  %i2 = and i32 %i, %A
-  %i3 = or i32 %B, %A
-  %i4 = xor i32 %i3, -1
-  %i5 = or i32 %i2, %i4
-  ret i32 %i5
-}
-
-define i32 @test7(i32 %A, i32 %B) {
-; CHECK-LABEL: @test7(
-; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[B:%.*]]
-; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
-; CHECK-NEXT:[[I5:%.*]] = or i32 [[I2]], [[I4]]
-; CHECK-NEXT:ret i32 [[I5]]
-;
-  %i = xor i32 %A, -1
-  %i2 = and i32 %i, %B
-  %i3 = or i32 %B, %A
-  %i4 = xor i32 %i3, -1
-  %i5 = or i32 %i2, %i4
-  ret i32 %i5
-}
-
-define <4 x i32> @test8_vec(<4 x i32> %A, <4 x i32> %B) {
-; CHECK-LABEL: @test8_vec(
-; CHECK-NEXT:[[I:%.*]] = xor <4 x i32> [[A:%.*]], 
-; CHECK-NEXT:[[I2:%.*]] = and <4 x i32> [[I]], [[B:%.*]]
-; CHECK-NEXT:[[I3:%.*]] = or <4 x i32> [[B]], [[A]]
-; CHECK-NEXT:[[I4:%.*]] = xor <4 x i32> [[I3]], 
-; CHECK-NEXT:[[I5:%.*]] = or <4 x i32> [[I2]], [[I4]]
-; CHECK-NEXT:ret <4 x i32> [[I5]]
-;
-  %i = xor <4 x i32> %A, 
-  %i2 = and <4 x i32> %i, %B
-  %i3 = or <4 x i32> %B, %A
-  %i4 = xor <4 x i32> %i3, 
-  %i5 = or <4 x i32> %i2, %i4
-  ret <4 x i32> %i5
-}
-
-define i32 @test9_use(i32 %A, i32 %B) {
-; CHECK-LABEL: @test9_use(
-; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[B:%.*]]
-; CHECK-NEXT:tail call void @use(i32 [[I2]])
-; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
-; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
-; CHECK-NEXT:[[I5:%.*]] = or i32 [[I2]], [[I4]]
-; CHECK-NEXT:ret i32 [[I5]]
-;
-  %i = xor i32 %A, -1
-  %i2 = and i32 %i, %B
-  tail call void @use(i32 %i2)
-  %i3 = or i32 %B, %A
-  %i4 = xor i32 %i3, -1
-  %i5 = or i32 %i2, %i4
-  ret i32 %i5
-}
-
-define i32 @test9_use2(i32 %A, i32 %B) {
-; CHECK-LABEL: @test9_use2(
-; CHECK-NEXT:[[I:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
-; CHECK-NEXT:[[I2:%.*]] = xor i32 [[I]], -1
-; CHECK-NEXT:tail call void @use(i32 [[I2]])
-; CHECK-NEXT:[[I3:%.*]] = xor i32 [[A]], -1
-; CHECK-NEXT:[[I4:%.*]] = and i32 [[I3]], [[B]]
-; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
-; CHECK-NEXT:ret i32 [[I5]]
-;
-  %i = or i32 %B, %A
-  %i2 = xor i32 %i, -1
-  tail call void @use(i32 %i2)
-  %i3 = xor i32 %A, -1
-  %i4 = and i32 %i3, %B
-  %i5 = or i32 %i4, %i2
-  ret i32 %i5
-}
-
-define i32 @test9_use3(i32 %A, i32 %B) {
-; CHECK-LABEL: @test9_use3(
-; CHECK-NEXT:[[I:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
-; CHECK-NEXT:[[I2:%.*]] = xor i32 [[I]], -1
-; CHECK-NEXT:tail call void @use(i32 [[I2]])
-; CHECK-NEXT:[[I3:%.*]] = xor i32 [[A]], -1
-; CHECK-NEXT:[[I4:%.*]] = and i32 [[I3]], [[B]]
-; CHECK-NEXT:tail call void @use(i32 [[I4]])
-; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
-; CHECK-NEXT:ret i32 [[I5]]
-;
-  %i = or i32 %B, %A
-  %i2 = xor i32 %i, -1
-  tail call void @use(i32 %i2)
-  %i3 = xor i32 %A, -1
-  %i4 = and i32 %i3, %B
-  tail call void @use(i32 %i4)
-  %i5 = or i32 %i4, %i2
-  ret i32 %i5
-}




[llvm-branch-commits] [llvm] a4e2a51 - [InstSimplify] Add (~A & B) | ~(A | B) --> ~A

2021-01-16 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-16T15:43:34+01:00
New Revision: a4e2a5145a29af678139f33e94ab3df0fc973e59

URL: 
https://github.com/llvm/llvm-project/commit/a4e2a5145a29af678139f33e94ab3df0fc973e59
DIFF: 
https://github.com/llvm/llvm-project/commit/a4e2a5145a29af678139f33e94ab3df0fc973e59.diff

LOG: [InstSimplify] Add (~A & B) | ~(A | B) --> ~A

Added: 


Modified: 
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/or.ll

Removed: 




diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index 2ae4228495e3..6266e922f8c9 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2262,6 +2262,12 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, 
const SimplifyQuery ,
match(Op0, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)
 return Op0;
 
+  // (~A & B) | ~(A | B) --> ~A
+  // (~A & B) | ~(B | A) --> ~A
+  if (match(Op0, m_And(m_Not(m_Value(A)), m_Value(B))) &&
+  match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)
+return cast(Op0)->getOperand(0);
+
   if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, false))
 return V;
 

diff  --git a/llvm/test/Transforms/InstSimplify/or.ll 
b/llvm/test/Transforms/InstSimplify/or.ll
index e8284264c612..7e7361d12395 100644
--- a/llvm/test/Transforms/InstSimplify/or.ll
+++ b/llvm/test/Transforms/InstSimplify/or.ll
@@ -301,3 +301,97 @@ define i32 @poison(i32 %x) {
   %v = or i32 %x, poison
   ret i32 %v
 }
+
+declare void @use(i32)
+
+define i32 @and_or_not_or(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT:ret i32 [[I]]
+;
+  %i = xor i32 %B, -1
+  %i2 = and i32 %i, %A
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i2, %i4
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or2(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or2(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:ret i32 [[I]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %i, %B
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i2, %i4
+  ret i32 %i5
+}
+
+define <4 x i32> @and_or_not_or3_vec(<4 x i32> %A, <4 x i32> %B) {
+; CHECK-LABEL: @and_or_not_or3_vec(
+; CHECK-NEXT:[[I:%.*]] = xor <4 x i32> [[A:%.*]], 
+; CHECK-NEXT:ret <4 x i32> [[I]]
+;
+  %i = xor <4 x i32> %A, 
+  %i2 = and <4 x i32> %i, %B
+  %i3 = or <4 x i32> %B, %A
+  %i4 = xor <4 x i32> %i3, 
+  %i5 = or <4 x i32> %i2, %i4
+  ret <4 x i32> %i5
+}
+
+define i32 @and_or_not_or4_use(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or4_use(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[B:%.*]]
+; CHECK-NEXT:tail call void @use(i32 [[I2]])
+; CHECK-NEXT:ret i32 [[I]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %i, %B
+  tail call void @use(i32 %i2)
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i2, %i4
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or4_use2(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or4_use2(
+; CHECK-NEXT:[[I:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT:[[I2:%.*]] = xor i32 [[I]], -1
+; CHECK-NEXT:tail call void @use(i32 [[I2]])
+; CHECK-NEXT:[[I3:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT:ret i32 [[I3]]
+;
+  %i = or i32 %B, %A
+  %i2 = xor i32 %i, -1
+  tail call void @use(i32 %i2)
+  %i3 = xor i32 %A, -1
+  %i4 = and i32 %i3, %B
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}
+
+define i32 @and_or_not_or4_use3(i32 %A, i32 %B) {
+; CHECK-LABEL: @and_or_not_or4_use3(
+; CHECK-NEXT:[[I:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT:[[I2:%.*]] = xor i32 [[I]], -1
+; CHECK-NEXT:tail call void @use(i32 [[I2]])
+; CHECK-NEXT:[[I3:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT:[[I4:%.*]] = and i32 [[I3]], [[B]]
+; CHECK-NEXT:tail call void @use(i32 [[I4]])
+; CHECK-NEXT:ret i32 [[I3]]
+;
+  %i = or i32 %B, %A
+  %i2 = xor i32 %i, -1
+  tail call void @use(i32 %i2)
+  %i3 = xor i32 %A, -1
+  %i4 = and i32 %i3, %B
+  tail call void @use(i32 %i4)
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}



___
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] 9fc814e - [Tests] Added tests for new instcombine or simplification; NFC

2021-01-16 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-16T15:43:33+01:00
New Revision: 9fc814ed59669d8f1d06cde5714c17fac652f2a1

URL: 
https://github.com/llvm/llvm-project/commit/9fc814ed59669d8f1d06cde5714c17fac652f2a1
DIFF: 
https://github.com/llvm/llvm-project/commit/9fc814ed59669d8f1d06cde5714c17fac652f2a1.diff

LOG: [Tests] Added tests for new instcombine or simplification; NFC

Added: 


Modified: 
llvm/test/Transforms/InstCombine/or.ll

Removed: 




diff  --git a/llvm/test/Transforms/InstCombine/or.ll 
b/llvm/test/Transforms/InstCombine/or.ll
index ff6244526563..0fc75fe082f8 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -1370,3 +1370,112 @@ define i32 @test5_use3(i32 %x, i32 %y) {
   ret i32 %or1
 }
 
+define i32 @test6(i32 %A, i32 %B) {
+; CHECK-LABEL: @test6(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[B:%.*]], -1
+; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[A:%.*]]
+; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
+; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I2]], [[I4]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = xor i32 %B, -1
+  %i2 = and i32 %i, %A
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i2, %i4
+  ret i32 %i5
+}
+
+define i32 @test7(i32 %A, i32 %B) {
+; CHECK-LABEL: @test7(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[B:%.*]]
+; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
+; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I2]], [[I4]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %i, %B
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i2, %i4
+  ret i32 %i5
+}
+
+define <4 x i32> @test8_vec(<4 x i32> %A, <4 x i32> %B) {
+; CHECK-LABEL: @test8_vec(
+; CHECK-NEXT:[[I:%.*]] = xor <4 x i32> [[A:%.*]], 
+; CHECK-NEXT:[[I2:%.*]] = and <4 x i32> [[I]], [[B:%.*]]
+; CHECK-NEXT:[[I3:%.*]] = or <4 x i32> [[B]], [[A]]
+; CHECK-NEXT:[[I4:%.*]] = xor <4 x i32> [[I3]], 
+; CHECK-NEXT:[[I5:%.*]] = or <4 x i32> [[I2]], [[I4]]
+; CHECK-NEXT:ret <4 x i32> [[I5]]
+;
+  %i = xor <4 x i32> %A, 
+  %i2 = and <4 x i32> %i, %B
+  %i3 = or <4 x i32> %B, %A
+  %i4 = xor <4 x i32> %i3, 
+  %i5 = or <4 x i32> %i2, %i4
+  ret <4 x i32> %i5
+}
+
+define i32 @test9_use(i32 %A, i32 %B) {
+; CHECK-LABEL: @test9_use(
+; CHECK-NEXT:[[I:%.*]] = xor i32 [[A:%.*]], -1
+; CHECK-NEXT:[[I2:%.*]] = and i32 [[I]], [[B:%.*]]
+; CHECK-NEXT:tail call void @use(i32 [[I2]])
+; CHECK-NEXT:[[I3:%.*]] = or i32 [[B]], [[A]]
+; CHECK-NEXT:[[I4:%.*]] = xor i32 [[I3]], -1
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I2]], [[I4]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = xor i32 %A, -1
+  %i2 = and i32 %i, %B
+  tail call void @use(i32 %i2)
+  %i3 = or i32 %B, %A
+  %i4 = xor i32 %i3, -1
+  %i5 = or i32 %i2, %i4
+  ret i32 %i5
+}
+
+define i32 @test9_use2(i32 %A, i32 %B) {
+; CHECK-LABEL: @test9_use2(
+; CHECK-NEXT:[[I:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT:[[I2:%.*]] = xor i32 [[I]], -1
+; CHECK-NEXT:tail call void @use(i32 [[I2]])
+; CHECK-NEXT:[[I3:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT:[[I4:%.*]] = and i32 [[I3]], [[B]]
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = or i32 %B, %A
+  %i2 = xor i32 %i, -1
+  tail call void @use(i32 %i2)
+  %i3 = xor i32 %A, -1
+  %i4 = and i32 %i3, %B
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}
+
+define i32 @test9_use3(i32 %A, i32 %B) {
+; CHECK-LABEL: @test9_use3(
+; CHECK-NEXT:[[I:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT:[[I2:%.*]] = xor i32 [[I]], -1
+; CHECK-NEXT:tail call void @use(i32 [[I2]])
+; CHECK-NEXT:[[I3:%.*]] = xor i32 [[A]], -1
+; CHECK-NEXT:[[I4:%.*]] = and i32 [[I3]], [[B]]
+; CHECK-NEXT:tail call void @use(i32 [[I4]])
+; CHECK-NEXT:[[I5:%.*]] = or i32 [[I4]], [[I2]]
+; CHECK-NEXT:ret i32 [[I5]]
+;
+  %i = or i32 %B, %A
+  %i2 = xor i32 %i, -1
+  tail call void @use(i32 %i2)
+  %i3 = xor i32 %A, -1
+  %i4 = and i32 %i3, %B
+  tail call void @use(i32 %i4)
+  %i5 = or i32 %i4, %i2
+  ret i32 %i5
+}



___
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] a150010 - [SimplifyCFG] Optimize CFG when null is passed to a function with nonnull argument

2021-01-15 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-15T23:53:43+01:00
New Revision: a1500105ee6074f992f376c916dcfa3a54acb717

URL: 
https://github.com/llvm/llvm-project/commit/a1500105ee6074f992f376c916dcfa3a54acb717
DIFF: 
https://github.com/llvm/llvm-project/commit/a1500105ee6074f992f376c916dcfa3a54acb717.diff

LOG: [SimplifyCFG] Optimize CFG when null is passed to a function with nonnull 
argument

Example:

```
__attribute__((nonnull,noinline)) char * pinc(char *p)  {
  return ++p;
}

char * foo(bool b, char *a) {
   return pinc(b ? 0 : a);

}
```

optimize to

```
char * foo(bool b, char *a) {
   return pinc(a);

}
```

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D94180

Added: 


Modified: 
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll

Removed: 




diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp 
b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 559830ed9a17..7fe33fd3c759 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1345,7 +1345,7 @@ static bool isSafeToHoistInvoke(BasicBlock *BB1, 
BasicBlock *BB2,
   return true;
 }
 
-static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I);
+static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool 
PtrValueMayBeModified = false);
 
 /// Given a conditional branch that goes to BB1 and BB2, hoist any common code
 /// in the two blocks up into the branch block. The caller of this function
@@ -6545,7 +6545,7 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, 
IRBuilder<> ) {
 }
 
 /// Check if passing a value to an instruction will cause undefined behavior.
-static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I) {
+static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool 
PtrValueMayBeModified) {
   Constant *C = dyn_cast(V);
   if (!C)
 return false;
@@ -6568,12 +6568,15 @@ static bool passingValueIsAlwaysUndefined(Value *V, 
Instruction *I) {
 
 // Look through GEPs. A load from a GEP derived from NULL is still 
undefined
 if (GetElementPtrInst *GEP = dyn_cast(Use))
-  if (GEP->getPointerOperand() == I)
-return passingValueIsAlwaysUndefined(V, GEP);
+  if (GEP->getPointerOperand() == I) {
+if (!GEP->isInBounds() || !GEP->hasAllZeroIndices())
+  PtrValueMayBeModified = true;
+return passingValueIsAlwaysUndefined(V, GEP, PtrValueMayBeModified);
+  }
 
 // Look through bitcasts.
 if (BitCastInst *BC = dyn_cast(Use))
-  return passingValueIsAlwaysUndefined(V, BC);
+  return passingValueIsAlwaysUndefined(V, BC, PtrValueMayBeModified);
 
 // Load from null is undefined.
 if (LoadInst *LI = dyn_cast(Use))
@@ -6588,10 +6591,35 @@ static bool passingValueIsAlwaysUndefined(Value *V, 
Instruction *I) {
   SI->getPointerAddressSpace())) &&
SI->getPointerOperand() == I;
 
-// A call to null is undefined.
-if (auto *CB = dyn_cast(Use))
-  return !NullPointerIsDefined(CB->getFunction()) &&
- CB->getCalledOperand() == I;
+if (auto *CB = dyn_cast(Use)) {
+  if (C->isNullValue() && NullPointerIsDefined(CB->getFunction()))
+return false;
+  // A call to null is undefined.
+  if (CB->getCalledOperand() == I)
+return true;
+
+  if (C->isNullValue()) {
+for (const llvm::Use  : CB->args())
+  if (Arg == I) {
+unsigned ArgIdx = CB->getArgOperandNo();
+if (CB->paramHasAttr(ArgIdx, Attribute::NonNull) &&
+CB->paramHasAttr(ArgIdx, Attribute::NoUndef)) {
+  // Passing null to a nonnnull+noundef argument is undefined.
+  return !PtrValueMayBeModified;
+}
+  }
+  } else if (isa(C)) {
+// Passing undef to a noundef argument is undefined.
+for (const llvm::Use  : CB->args())
+  if (Arg == I) {
+unsigned ArgIdx = CB->getArgOperandNo();
+if (CB->paramHasAttr(ArgIdx, Attribute::NoUndef)) {
+  // Passing undef to a noundef argument is undefined.
+  return true;
+}
+  }
+  }
+}
   }
   return false;
 }

diff  --git a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll 
b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
index b3b7abe9ff0d..4c984819cfcf 100644
--- a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
+++ b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
@@ -69,7 +69,6 @@ define void @test5(i1 %cond, i8* %ptr) {
 ; CHECK-NEXT:store i8 2, i8* [[PTR:%.*]], align 8
 ; CHECK-NEXT:ret void
 ;
-
 entry:
   br i1 %cond, label %bb1, label %bb3
 
@@ -88,11 +87,10 @@ bb2:
 define void @test5_no_null_opt(i1 %cond, i8* %ptr) #0 {
 ; CHECK-LABEL: @test5_no_null_opt(
 ; 

[llvm-branch-commits] [llvm] d307d89 - [Tests] Added test for memcpy loop idiom recognization

2021-01-13 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-13T14:55:46+01:00
New Revision: d307d892ade9384a5d8b40ddb6a9c0b2dffbdb81

URL: 
https://github.com/llvm/llvm-project/commit/d307d892ade9384a5d8b40ddb6a9c0b2dffbdb81
DIFF: 
https://github.com/llvm/llvm-project/commit/d307d892ade9384a5d8b40ddb6a9c0b2dffbdb81.diff

LOG: [Tests] Added test for memcpy loop idiom recognization

Added: 
llvm/test/Transforms/LoopIdiom/memcpy.ll

Modified: 


Removed: 




diff  --git a/llvm/test/Transforms/LoopIdiom/memcpy.ll 
b/llvm/test/Transforms/LoopIdiom/memcpy.ll
new file mode 100644
index ..af8dc773c19b
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/memcpy.ll
@@ -0,0 +1,106 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -basic-aa -loop-idiom < %s -S | FileCheck %s
+
+define void @copy_both_noalias(float* noalias nocapture %d, float* noalias 
nocapture readonly %s, i64 %sz) {
+; CHECK-LABEL: @copy_both_noalias(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:[[D1:%.*]] = bitcast float* [[D:%.*]] to i8*
+; CHECK-NEXT:[[S2:%.*]] = bitcast float* [[S:%.*]] to i8*
+; CHECK-NEXT:[[EXITCOND_NOT1:%.*]] = icmp eq i64 [[SZ:%.*]], 0
+; CHECK-NEXT:br i1 [[EXITCOND_NOT1]], label [[FOR_END:%.*]], label 
[[FOR_BODY_PREHEADER:%.*]]
+; CHECK:   for.body.preheader:
+; CHECK-NEXT:[[TMP0:%.*]] = shl nuw i64 [[SZ]], 2
+; CHECK-NEXT:call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[D1]], i8* 
align 4 [[S2]], i64 [[TMP0]], i1 false)
+; CHECK-NEXT:br label [[FOR_BODY:%.*]]
+; CHECK:   for.body:
+; CHECK-NEXT:[[I_04:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, 
[[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT:[[D_ADDR_03:%.*]] = phi float* [ [[INCDEC_PTR1:%.*]], 
[[FOR_BODY]] ], [ [[D]], [[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT:[[S_ADDR_02:%.*]] = phi float* [ [[INCDEC_PTR:%.*]], 
[[FOR_BODY]] ], [ [[S]], [[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT:[[INCDEC_PTR]] = getelementptr inbounds float, float* 
[[S_ADDR_02]], i64 1
+; CHECK-NEXT:[[TMP1:%.*]] = load float, float* [[S_ADDR_02]], align 4
+; CHECK-NEXT:[[INCDEC_PTR1]] = getelementptr inbounds float, float* 
[[D_ADDR_03]], i64 1
+; CHECK-NEXT:[[INC]] = add i64 [[I_04]], 1
+; CHECK-NEXT:[[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[SZ]]
+; CHECK-NEXT:br i1 [[EXITCOND_NOT]], label [[FOR_END_LOOPEXIT:%.*]], label 
[[FOR_BODY]]
+; CHECK:   for.end.loopexit:
+; CHECK-NEXT:br label [[FOR_END]]
+; CHECK:   for.end:
+; CHECK-NEXT:ret void
+;
+entry:
+  %exitcond.not1 = icmp eq i64 %sz, 0
+  br i1 %exitcond.not1, label %for.end, label %for.body.preheader
+
+for.body.preheader:   ; preds = %entry
+  br label %for.body
+
+for.body: ; preds = 
%for.body.preheader, %for.body
+  %i.04 = phi i64 [ %inc, %for.body ], [ 0, %for.body.preheader ]
+  %d.addr.03 = phi float* [ %incdec.ptr1, %for.body ], [ %d, 
%for.body.preheader ]
+  %s.addr.02 = phi float* [ %incdec.ptr, %for.body ], [ %s, 
%for.body.preheader ]
+  %incdec.ptr = getelementptr inbounds float, float* %s.addr.02, i64 1
+  %0 = load float, float* %s.addr.02, align 4
+  %incdec.ptr1 = getelementptr inbounds float, float* %d.addr.03, i64 1
+  store float %0, float* %d.addr.03, align 4
+  %inc = add i64 %i.04, 1
+  %exitcond.not = icmp eq i64 %inc, %sz
+  br i1 %exitcond.not, label %for.end.loopexit, label %for.body
+
+for.end.loopexit: ; preds = %for.body
+  br label %for.end
+
+for.end:  ; preds = %for.end.loopexit, 
%entry
+  ret void
+}
+
+define void @copy_one_noalias(float* nocapture %d, float* noalias nocapture 
readonly %s, i64 %sz) {
+; CHECK-LABEL: @copy_one_noalias(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:[[D1:%.*]] = bitcast float* [[D:%.*]] to i8*
+; CHECK-NEXT:[[S2:%.*]] = bitcast float* [[S:%.*]] to i8*
+; CHECK-NEXT:[[EXITCOND_NOT1:%.*]] = icmp eq i64 [[SZ:%.*]], 0
+; CHECK-NEXT:br i1 [[EXITCOND_NOT1]], label [[FOR_END:%.*]], label 
[[FOR_BODY_PREHEADER:%.*]]
+; CHECK:   for.body.preheader:
+; CHECK-NEXT:[[TMP0:%.*]] = shl nuw i64 [[SZ]], 2
+; CHECK-NEXT:call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[D1]], i8* 
align 4 [[S2]], i64 [[TMP0]], i1 false)
+; CHECK-NEXT:br label [[FOR_BODY:%.*]]
+; CHECK:   for.body:
+; CHECK-NEXT:[[I_04:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, 
[[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT:[[D_ADDR_03:%.*]] = phi float* [ [[INCDEC_PTR1:%.*]], 
[[FOR_BODY]] ], [ [[D]], [[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT:[[S_ADDR_02:%.*]] = phi float* [ [[INCDEC_PTR:%.*]], 
[[FOR_BODY]] ], [ [[S]], [[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT:[[INCDEC_PTR]] = getelementptr inbounds float, float* 
[[S_ADDR_02]], i64 1
+; CHECK-NEXT:[[TMP1:%.*]] = load float, float* [[S_ADDR_02]], align 4
+; CHECK-NEXT:[[INCDEC_PTR1]] = 

[llvm-branch-commits] [llvm] 0529946 - [instCombine] Add (A ^ B) | ~(A | B) -> ~(A & B)

2021-01-12 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-12T19:29:17+01:00
New Revision: 0529946b5bafafd10d77b946ee9fa96f388860ef

URL: 
https://github.com/llvm/llvm-project/commit/0529946b5bafafd10d77b946ee9fa96f388860ef
DIFF: 
https://github.com/llvm/llvm-project/commit/0529946b5bafafd10d77b946ee9fa96f388860ef.diff

LOG: [instCombine] Add (A ^ B) | ~(A | B) -> ~(A & B)

define i32 @src(i32 %x, i32 %y) {
%0:
  %xor = xor i32 %y, %x
  %or = or i32 %y, %x
  %neg = xor i32 %or, 4294967295
  %or1 = or i32 %xor, %neg
  ret i32 %or1
}
=>
define i32 @tgt(i32 %x, i32 %y) {
%0:
  %and = and i32 %x, %y
  %neg = xor i32 %and, 4294967295
  ret i32 %neg
}
Transformation seems to be correct!

https://alive2.llvm.org/ce/z/Cvca4a

Added: 


Modified: 
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/or.ll

Removed: 




diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 15dcf2d19c15..352126fa07ca 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1627,6 +1627,14 @@ static Instruction *foldOrToXor(BinaryOperator ,
 match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)
   return BinaryOperator::CreateNot(Builder.CreateXor(A, B));
 
+  // Operand complexity canonicalization guarantees that the 'xor' is Op0.
+  // (A ^ B) | ~(A | B) --> ~(A & B)
+  // (A ^ B) | ~(B | A) --> ~(A & B)
+  if (Op0->hasOneUse() || Op1->hasOneUse())
+if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
+match(Op1, m_Not(m_c_Or(m_Specific(A), m_Specific(B)
+  return BinaryOperator::CreateNot(Builder.CreateAnd(A, B));
+
   // (A & ~B) | (~A & B) --> A ^ B
   // (A & ~B) | (B & ~A) --> A ^ B
   // (~B & A) | (~A & B) --> A ^ B

diff  --git a/llvm/test/Transforms/InstCombine/or.ll 
b/llvm/test/Transforms/InstCombine/or.ll
index d41b8d53dd40..b5da1734c102 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -1004,10 +1004,8 @@ end:
 
 define i32 @test1(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y]], [[X]]
-; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
-; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:[[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[OR1:%.*]] = xor i32 [[TMP1]], -1
 ; CHECK-NEXT:ret i32 [[OR1]]
 ;
   %xor = xor i32 %y, %x
@@ -1019,13 +1017,11 @@ define i32 @test1(i32 %x, i32 %y) {
 
 define i32 @test2(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
-; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y]], [[X]]
-; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:[[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[OR1:%.*]] = xor i32 [[TMP1]], -1
 ; CHECK-NEXT:ret i32 [[OR1]]
 ;
-  %or = or i32 %y, %x
+  %or = or i32 %x, %y
   %neg = xor i32 %or, -1
   %xor = xor i32 %y, %x
   %or1 = or i32 %xor, %neg
@@ -1034,25 +1030,21 @@ define i32 @test2(i32 %x, i32 %y) {
 
 define i32 @test3(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test3(
-; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
-; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y]], [[X]]
-; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:[[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:[[OR1:%.*]] = xor i32 [[TMP1]], -1
 ; CHECK-NEXT:ret i32 [[OR1]]
 ;
   %or = or i32 %y, %x
   %neg = xor i32 %or, -1
-  %xor = xor i32 %y, %x
+  %xor = xor i32 %x, %y
   %or1 = or i32 %xor, %neg
   ret i32 %or1
 }
 
 define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
 ; CHECK-LABEL: @test4_vec(
-; CHECK-NEXT:[[OR:%.*]] = or <2 x i32> [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:[[NEG:%.*]] = xor <2 x i32> [[OR]], 
-; CHECK-NEXT:[[XOR:%.*]] = xor <2 x i32> [[Y]], [[X]]
-; CHECK-NEXT:[[OR1:%.*]] = or <2 x i32> [[XOR]], [[NEG]]
+; CHECK-NEXT:[[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[OR1:%.*]] = xor <2 x i32> [[TMP1]], 
 ; CHECK-NEXT:ret <2 x i32> [[OR1]]
 ;
   %or = or <2 x i32> %y, %x
@@ -1066,9 +1058,9 @@ define i32 @test5_use(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test5_use(
 ; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
 ; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
-; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y]], [[X]]
 ; CHECK-NEXT:call void @use(i32 [[NEG]])
-; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:[[TMP1:%.*]] = and i32 [[Y]], [[X]]
+; CHECK-NEXT:[[OR1:%.*]] = xor i32 [[TMP1]], -1
 ; CHECK-NEXT:ret i32 [[OR1]]
 ;
   %or = or i32 %y, %x
@@ -1081,11 +1073,10 @@ define i32 @test5_use(i32 

[llvm-branch-commits] [llvm] bb9ebf6 - [Tests] Add tests for new InstCombine OR transformation, NFC

2021-01-12 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2021-01-12T19:29:17+01:00
New Revision: bb9ebf6baf7057d7f2aed90fccbac2414cf9a134

URL: 
https://github.com/llvm/llvm-project/commit/bb9ebf6baf7057d7f2aed90fccbac2414cf9a134
DIFF: 
https://github.com/llvm/llvm-project/commit/bb9ebf6baf7057d7f2aed90fccbac2414cf9a134.diff

LOG: [Tests] Add tests for new InstCombine OR transformation, NFC

Added: 


Modified: 
llvm/test/Transforms/InstCombine/or.ll

Removed: 




diff  --git a/llvm/test/Transforms/InstCombine/or.ll 
b/llvm/test/Transforms/InstCombine/or.ll
index b5e3af2c7652..d41b8d53dd40 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -2,6 +2,7 @@
 ; RUN: opt < %s -instcombine -S | FileCheck %s
 
 target datalayout = 
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n32:64"
+declare void @use(i32)
 
 define i32 @test12(i32 %A) {
 ; Should be eliminated
@@ -1000,3 +1001,116 @@ end:
   %conv8 = zext i1 %t5 to i32
   ret i32 %conv8
 }
+
+define i32 @test1(i32 %x, i32 %y) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y]], [[X]]
+; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
+; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:ret i32 [[OR1]]
+;
+  %xor = xor i32 %y, %x
+  %or = or i32 %y, %x
+  %neg = xor i32 %or, -1
+  %or1 = or i32 %xor, %neg
+  ret i32 %or1
+}
+
+define i32 @test2(i32 %x, i32 %y) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
+; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y]], [[X]]
+; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:ret i32 [[OR1]]
+;
+  %or = or i32 %y, %x
+  %neg = xor i32 %or, -1
+  %xor = xor i32 %y, %x
+  %or1 = or i32 %xor, %neg
+  ret i32 %or1
+}
+
+define i32 @test3(i32 %x, i32 %y) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
+; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y]], [[X]]
+; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:ret i32 [[OR1]]
+;
+  %or = or i32 %y, %x
+  %neg = xor i32 %or, -1
+  %xor = xor i32 %y, %x
+  %or1 = or i32 %xor, %neg
+  ret i32 %or1
+}
+
+define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @test4_vec(
+; CHECK-NEXT:[[OR:%.*]] = or <2 x i32> [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[NEG:%.*]] = xor <2 x i32> [[OR]], 
+; CHECK-NEXT:[[XOR:%.*]] = xor <2 x i32> [[Y]], [[X]]
+; CHECK-NEXT:[[OR1:%.*]] = or <2 x i32> [[XOR]], [[NEG]]
+; CHECK-NEXT:ret <2 x i32> [[OR1]]
+;
+  %or = or <2 x i32> %y, %x
+  %neg = xor <2 x i32> %or, 
+  %xor = xor <2 x i32> %y, %x
+  %or1 = or <2 x i32> %xor, %neg
+  ret <2 x i32> %or1
+}
+
+define i32 @test5_use(i32 %x, i32 %y) {
+; CHECK-LABEL: @test5_use(
+; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
+; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y]], [[X]]
+; CHECK-NEXT:call void @use(i32 [[NEG]])
+; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:ret i32 [[OR1]]
+;
+  %or = or i32 %y, %x
+  %neg = xor i32 %or, -1
+  %xor = xor i32 %y, %x
+  call void @use(i32 %neg)
+  %or1 = or i32 %xor, %neg
+  ret i32 %or1
+}
+
+define i32 @test5_use2(i32 %x, i32 %y) {
+; CHECK-LABEL: @test5_use2(
+; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
+; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y]], [[X]]
+; CHECK-NEXT:call void @use(i32 [[XOR]])
+; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:ret i32 [[OR1]]
+;
+  %or = or i32 %y, %x
+  %neg = xor i32 %or, -1
+  %xor = xor i32 %y, %x
+  call void @use(i32 %xor)
+  %or1 = or i32 %xor, %neg
+  ret i32 %or1
+}
+define i32 @test5_use3(i32 %x, i32 %y) {
+; CHECK-LABEL: @test5_use3(
+; CHECK-NEXT:[[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[NEG:%.*]] = xor i32 [[OR]], -1
+; CHECK-NEXT:call void @use(i32 [[NEG]])
+; CHECK-NEXT:[[XOR:%.*]] = xor i32 [[Y]], [[X]]
+; CHECK-NEXT:call void @use(i32 [[XOR]])
+; CHECK-NEXT:[[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
+; CHECK-NEXT:ret i32 [[OR1]]
+;
+  %or = or i32 %y, %x
+  %neg = xor i32 %or, -1
+  call void @use(i32 %neg)
+  %xor = xor i32 %y, %x
+  call void @use(i32 %xor)
+  %or1 = or i32 %xor, %neg
+  ret i32 %or1
+}
+



___
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] ae69fa9 - [InstCombine] Transform (A + B) - (A & B) to A | B (PR48604)

2020-12-31 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2020-12-31T15:04:32+01:00
New Revision: ae69fa9b9f65f59cc0ca8c47f23748a53c8dbdc5

URL: 
https://github.com/llvm/llvm-project/commit/ae69fa9b9f65f59cc0ca8c47f23748a53c8dbdc5
DIFF: 
https://github.com/llvm/llvm-project/commit/ae69fa9b9f65f59cc0ca8c47f23748a53c8dbdc5.diff

LOG: [InstCombine] Transform (A + B) - (A & B) to A | B (PR48604)

define i32 @src(i32 %x, i32 %y) {
%0:
  %a = add i32 %x, %y
  %o = and i32 %x, %y
  %r = sub i32 %a, %o
  ret i32 %r
}
=>
define i32 @tgt(i32 %x, i32 %y) {
%0:
  %b = or i32 %x, %y
  ret i32 %b
}
Transformation seems to be correct!

https://alive2.llvm.org/ce/z/2fhW6r

Added: 


Modified: 
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/test/Transforms/InstCombine/sub.ll

Removed: 




diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index be145615a241..bacb8689892a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1881,6 +1881,14 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator 
) {
   return BinaryOperator::CreateAnd(A, B);
   }
 
+  // (sub (add A, B) (and A, B)) --> (or A, B)
+  {
+Value *A, *B;
+if (match(Op0, m_Add(m_Value(A), m_Value(B))) &&
+match(Op1, m_c_And(m_Specific(A), m_Specific(B
+  return BinaryOperator::CreateOr(A, B);
+  }
+
   // (sub (and A, B) (or A, B)) --> neg (xor A, B)
   {
 Value *A, *B;

diff  --git a/llvm/test/Transforms/InstCombine/sub.ll 
b/llvm/test/Transforms/InstCombine/sub.ll
index aaac3f23f71f..649d2e8c2848 100644
--- a/llvm/test/Transforms/InstCombine/sub.ll
+++ b/llvm/test/Transforms/InstCombine/sub.ll
@@ -1621,9 +1621,7 @@ define <2 x i8> @and_vec(<2 x i8> %X, <2 x i8> %Y) {
 
 define i32 @or_test(i32 %x, i32 %y) {
 ; CHECK-LABEL: @or_test(
-; CHECK-NEXT:[[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:[[B:%.*]] = and i32 [[X]], [[Y]]
-; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[B]]
+; CHECK-NEXT:[[R:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %a = add i32 %x, %y
@@ -1634,9 +1632,7 @@ define i32 @or_test(i32 %x, i32 %y) {
 
 define i32 @or_test2(i32 %x, i32 %y) {
 ; CHECK-LABEL: @or_test2(
-; CHECK-NEXT:[[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:[[B:%.*]] = and i32 [[Y]], [[X]]
-; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[B]]
+; CHECK-NEXT:[[R:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %a = add i32 %x, %y
@@ -1647,9 +1643,7 @@ define i32 @or_test2(i32 %x, i32 %y) {
 
 define i32 @or_test3(i32 %x, i32 %y) {
 ; CHECK-LABEL: @or_test3(
-; CHECK-NEXT:[[A:%.*]] = add i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:[[B:%.*]] = and i32 [[X]], [[Y]]
-; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[B]]
+; CHECK-NEXT:[[R:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %a = add i32 %y, %x
@@ -1660,9 +1654,7 @@ define i32 @or_test3(i32 %x, i32 %y) {
 
 define <2 x i8> @or_vec(<2 x i8> %X, <2 x i8> %Y) {
 ; CHECK-LABEL: @or_vec(
-; CHECK-NEXT:[[A:%.*]] = add <2 x i8> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:[[B:%.*]] = and <2 x i8> [[X]], [[Y]]
-; CHECK-NEXT:[[R:%.*]] = sub <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:[[R:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:ret <2 x i8> [[R]]
 ;
   %a = add <2 x i8> %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] c1937c2 - [NFC] Added/adjusted tests for PR48604; second pattern

2020-12-31 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2020-12-31T14:59:15+01:00
New Revision: c1937c2af2a03f0b5fda3bbf99e2971ffa04ff0c

URL: 
https://github.com/llvm/llvm-project/commit/c1937c2af2a03f0b5fda3bbf99e2971ffa04ff0c
DIFF: 
https://github.com/llvm/llvm-project/commit/c1937c2af2a03f0b5fda3bbf99e2971ffa04ff0c.diff

LOG: [NFC] Added/adjusted tests for PR48604; second pattern

Added: 


Modified: 
llvm/test/Transforms/InstCombine/and.ll
llvm/test/Transforms/InstCombine/sub.ll

Removed: 




diff  --git a/llvm/test/Transforms/InstCombine/and.ll 
b/llvm/test/Transforms/InstCombine/and.ll
index a3d5932ff140..020dbc483d9d 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -1217,49 +1217,3 @@ define <2 x i8> @flip_masked_bit_nonuniform(<2 x i8> %A) 
{
   %C = and <2 x i8> %B, 
   ret <2 x i8> %C
 }
-
-
-define i32 @and_test(i32 %x, i32 %y) {
-; CHECK-LABEL: @and_test(
-; CHECK-NEXT:[[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:ret i32 [[R]]
-;
-  %a = add i32 %x, %y
-  %o = or i32 %x, %y
-  %r = sub i32 %a, %o
-  ret i32 %r
-}
-
-define i32 @and_test2(i32 %x, i32 %y) {
-; CHECK-LABEL: @and_test2(
-; CHECK-NEXT:[[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:ret i32 [[R]]
-;
-  %a = add i32 %x, %y
-  %o = or i32 %y, %x
-  %r = sub i32 %a, %o
-  ret i32 %r
-}
-
-define i32 @and_test3(i32 %x, i32 %y) {
-; CHECK-LABEL: @and_test3(
-; CHECK-NEXT:[[R:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:ret i32 [[R]]
-;
-  %a = add i32 %y, %x
-  %o = or i32 %x, %y
-  %r = sub i32 %a, %o
-  ret i32 %r
-}
-
-
-define <2 x i8> @and_vec(<2 x i8> %X, <2 x i8> %Y) {
-; CHECK-LABEL: @and_vec(
-; CHECK-NEXT:[[R:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:ret <2 x i8> [[R]]
-;
-  %a = add <2 x i8> %X, %Y
-  %o = or <2 x i8> %X, %Y
-  %r = sub <2 x i8> %a, %o
-  ret <2 x i8> %r
-}

diff  --git a/llvm/test/Transforms/InstCombine/sub.ll 
b/llvm/test/Transforms/InstCombine/sub.ll
index 066085fc2535..aaac3f23f71f 100644
--- a/llvm/test/Transforms/InstCombine/sub.ll
+++ b/llvm/test/Transforms/InstCombine/sub.ll
@@ -1574,3 +1574,99 @@ define i16 @sub_mul_nuw(i16 %x, i16 %y) {
   %r = sub i16 %x8, %y8
   ret i16 %r
 }
+define i32 @and_test(i32 %x, i32 %y) {
+; CHECK-LABEL: @and_test(
+; CHECK-NEXT:[[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %x, %y
+  %o = or i32 %x, %y
+  %r = sub i32 %a, %o
+  ret i32 %r
+}
+
+define i32 @and_test2(i32 %x, i32 %y) {
+; CHECK-LABEL: @and_test2(
+; CHECK-NEXT:[[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %x, %y
+  %o = or i32 %y, %x
+  %r = sub i32 %a, %o
+  ret i32 %r
+}
+
+define i32 @and_test3(i32 %x, i32 %y) {
+; CHECK-LABEL: @and_test3(
+; CHECK-NEXT:[[R:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %y, %x
+  %o = or i32 %x, %y
+  %r = sub i32 %a, %o
+  ret i32 %r
+}
+
+
+define <2 x i8> @and_vec(<2 x i8> %X, <2 x i8> %Y) {
+; CHECK-LABEL: @and_vec(
+; CHECK-NEXT:[[R:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:ret <2 x i8> [[R]]
+;
+  %a = add <2 x i8> %X, %Y
+  %o = or <2 x i8> %X, %Y
+  %r = sub <2 x i8> %a, %o
+  ret <2 x i8> %r
+}
+
+define i32 @or_test(i32 %x, i32 %y) {
+; CHECK-LABEL: @or_test(
+; CHECK-NEXT:[[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:[[B:%.*]] = and i32 [[X]], [[Y]]
+; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[B]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %x, %y
+  %b = and i32 %x, %y
+  %r = sub i32 %a, %b
+  ret i32 %r
+}
+
+define i32 @or_test2(i32 %x, i32 %y) {
+; CHECK-LABEL: @or_test2(
+; CHECK-NEXT:[[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:[[B:%.*]] = and i32 [[Y]], [[X]]
+; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[B]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %x, %y
+  %b = and i32 %y, %x
+  %r = sub i32 %a, %b
+  ret i32 %r
+}
+
+define i32 @or_test3(i32 %x, i32 %y) {
+; CHECK-LABEL: @or_test3(
+; CHECK-NEXT:[[A:%.*]] = add i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[B:%.*]] = and i32 [[X]], [[Y]]
+; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[B]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %y, %x
+  %b = and i32 %x, %y
+  %r = sub i32 %a, %b
+  ret i32 %r
+}
+
+define <2 x i8> @or_vec(<2 x i8> %X, <2 x i8> %Y) {
+; CHECK-LABEL: @or_vec(
+; CHECK-NEXT:[[A:%.*]] = add <2 x i8> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:[[B:%.*]] = and <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:[[R:%.*]] = sub <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:ret <2 x i8> [[R]]
+;
+  %a = add <2 x i8> %X, %Y
+  %b = and <2 x i8> %X, %Y
+  %r = sub <2 x i8> %a, %b
+  ret <2 x i8> %r
+}



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org

[llvm-branch-commits] [llvm] 742ea77 - [InstCombine] Transform (A + B) - (A | B) to A & B (PR48604)

2020-12-31 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2020-12-31T14:03:20+01:00
New Revision: 742ea77ca4c0ea10d8ccd160c7d7f4257d214ed0

URL: 
https://github.com/llvm/llvm-project/commit/742ea77ca4c0ea10d8ccd160c7d7f4257d214ed0
DIFF: 
https://github.com/llvm/llvm-project/commit/742ea77ca4c0ea10d8ccd160c7d7f4257d214ed0.diff

LOG: [InstCombine] Transform (A + B) - (A | B) to A & B (PR48604)

define i32 @src(i32 %x, i32 %y) {
%0:
  %a = add i32 %x, %y
  %o = or i32 %x, %y
  %r = sub i32 %a, %o
  ret i32 %r
}
=>
define i32 @tgt(i32 %x, i32 %y) {
%0:
  %b = and i32 %x, %y
  ret i32 %b
}
Transformation seems to be correct!

https://alive2.llvm.org/ce/z/aQRh2j

Added: 


Modified: 
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/test/Transforms/InstCombine/and.ll

Removed: 




diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index c20861f20f07..be145615a241 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1873,6 +1873,14 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator 
) {
   return BinaryOperator::CreateXor(A, B);
   }
 
+  // (sub (add A, B) (or A, B)) --> (and A, B)
+  {
+Value *A, *B;
+if (match(Op0, m_Add(m_Value(A), m_Value(B))) &&
+match(Op1, m_c_Or(m_Specific(A), m_Specific(B
+  return BinaryOperator::CreateAnd(A, B);
+  }
+
   // (sub (and A, B) (or A, B)) --> neg (xor A, B)
   {
 Value *A, *B;

diff  --git a/llvm/test/Transforms/InstCombine/and.ll 
b/llvm/test/Transforms/InstCombine/and.ll
index 4f054c05889a..a3d5932ff140 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -1221,9 +1221,7 @@ define <2 x i8> @flip_masked_bit_nonuniform(<2 x i8> %A) {
 
 define i32 @and_test(i32 %x, i32 %y) {
 ; CHECK-LABEL: @and_test(
-; CHECK-NEXT:[[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:[[O:%.*]] = or i32 [[X]], [[Y]]
-; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[O]]
+; CHECK-NEXT:[[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %a = add i32 %x, %y
@@ -1234,9 +1232,7 @@ define i32 @and_test(i32 %x, i32 %y) {
 
 define i32 @and_test2(i32 %x, i32 %y) {
 ; CHECK-LABEL: @and_test2(
-; CHECK-NEXT:[[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:[[O:%.*]] = or i32 [[Y]], [[X]]
-; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[O]]
+; CHECK-NEXT:[[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %a = add i32 %x, %y
@@ -1247,9 +1243,7 @@ define i32 @and_test2(i32 %x, i32 %y) {
 
 define i32 @and_test3(i32 %x, i32 %y) {
 ; CHECK-LABEL: @and_test3(
-; CHECK-NEXT:[[A:%.*]] = add i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:[[O:%.*]] = or i32 [[X]], [[Y]]
-; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[O]]
+; CHECK-NEXT:[[R:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
 ; CHECK-NEXT:ret i32 [[R]]
 ;
   %a = add i32 %y, %x
@@ -1261,9 +1255,7 @@ define i32 @and_test3(i32 %x, i32 %y) {
 
 define <2 x i8> @and_vec(<2 x i8> %X, <2 x i8> %Y) {
 ; CHECK-LABEL: @and_vec(
-; CHECK-NEXT:[[A:%.*]] = add <2 x i8> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:[[O:%.*]] = or <2 x i8> [[X]], [[Y]]
-; CHECK-NEXT:[[R:%.*]] = sub <2 x i8> [[A]], [[O]]
+; CHECK-NEXT:[[R:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:ret <2 x i8> [[R]]
 ;
   %a = add <2 x i8> %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] 9b64939 - [NFC] Added tests for PR48604

2020-12-31 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2020-12-31T14:03:20+01:00
New Revision: 9b6493946307c321cacc5d1da53bbae5a1acda24

URL: 
https://github.com/llvm/llvm-project/commit/9b6493946307c321cacc5d1da53bbae5a1acda24
DIFF: 
https://github.com/llvm/llvm-project/commit/9b6493946307c321cacc5d1da53bbae5a1acda24.diff

LOG: [NFC] Added tests for PR48604

Added: 


Modified: 
llvm/test/Transforms/InstCombine/and.ll

Removed: 




diff  --git a/llvm/test/Transforms/InstCombine/and.ll 
b/llvm/test/Transforms/InstCombine/and.ll
index 020dbc483d9d..4f054c05889a 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -1217,3 +1217,57 @@ define <2 x i8> @flip_masked_bit_nonuniform(<2 x i8> %A) 
{
   %C = and <2 x i8> %B, 
   ret <2 x i8> %C
 }
+
+
+define i32 @and_test(i32 %x, i32 %y) {
+; CHECK-LABEL: @and_test(
+; CHECK-NEXT:[[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:[[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[O]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %x, %y
+  %o = or i32 %x, %y
+  %r = sub i32 %a, %o
+  ret i32 %r
+}
+
+define i32 @and_test2(i32 %x, i32 %y) {
+; CHECK-LABEL: @and_test2(
+; CHECK-NEXT:[[A:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:[[O:%.*]] = or i32 [[Y]], [[X]]
+; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[O]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %x, %y
+  %o = or i32 %y, %x
+  %r = sub i32 %a, %o
+  ret i32 %r
+}
+
+define i32 @and_test3(i32 %x, i32 %y) {
+; CHECK-LABEL: @and_test3(
+; CHECK-NEXT:[[A:%.*]] = add i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:[[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:[[R:%.*]] = sub i32 [[A]], [[O]]
+; CHECK-NEXT:ret i32 [[R]]
+;
+  %a = add i32 %y, %x
+  %o = or i32 %x, %y
+  %r = sub i32 %a, %o
+  ret i32 %r
+}
+
+
+define <2 x i8> @and_vec(<2 x i8> %X, <2 x i8> %Y) {
+; CHECK-LABEL: @and_vec(
+; CHECK-NEXT:[[A:%.*]] = add <2 x i8> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:[[O:%.*]] = or <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:[[R:%.*]] = sub <2 x i8> [[A]], [[O]]
+; CHECK-NEXT:ret <2 x i8> [[R]]
+;
+  %a = add <2 x i8> %X, %Y
+  %o = or <2 x i8> %X, %Y
+  %r = sub <2 x i8> %a, %o
+  ret <2 x 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] 5da71a4 - [NFC] Added test for PR33549

2020-12-08 Thread Dávid Bolvanský via llvm-branch-commits

Author: Dávid Bolvanský
Date: 2020-12-09T03:21:52+01:00
New Revision: 5da71a4274acb86d31b74b79490cab30ac96bbf3

URL: 
https://github.com/llvm/llvm-project/commit/5da71a4274acb86d31b74b79490cab30ac96bbf3
DIFF: 
https://github.com/llvm/llvm-project/commit/5da71a4274acb86d31b74b79490cab30ac96bbf3.diff

LOG: [NFC] Added test for PR33549

Added: 
llvm/test/Transforms/GVN/pr33549.ll

Modified: 


Removed: 




diff  --git a/llvm/test/Transforms/GVN/pr33549.ll 
b/llvm/test/Transforms/GVN/pr33549.ll
new file mode 100644
index ..7155ba4c1e3d
--- /dev/null
+++ b/llvm/test/Transforms/GVN/pr33549.ll
@@ -0,0 +1,91 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -gvn -S < %s | FileCheck %s
+
+@Data = common local_unnamed_addr global [32 x i32] zeroinitializer, align 4
+
+; Function Attrs: norecurse nounwind
+define void @testshl() local_unnamed_addr #0 {
+; CHECK-LABEL: @testshl(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:br label [[FOR_BODY:%.*]]
+; CHECK:   for.body:
+; CHECK-NEXT:[[K_031:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[INC9:%.*]], 
[[FOR_INC8:%.*]] ]
+; CHECK-NEXT:[[SHL:%.*]] = shl i32 1, [[K_031]]
+; CHECK-NEXT:[[SHR:%.*]] = ashr exact i32 [[SHL]], 1
+; CHECK-NEXT:[[CMP229:%.*]] = icmp slt i32 [[SHL]], 64
+; CHECK-NEXT:br i1 [[CMP229]], label [[FOR_BODY3_PREHEADER:%.*]], label 
[[FOR_INC8]]
+; CHECK:   for.body3.preheader:
+; CHECK-NEXT:[[DIV:%.*]] = sdiv i32 [[SHR]], 2
+; CHECK-NEXT:br label [[FOR_BODY3:%.*]]
+; CHECK:   for.body3:
+; CHECK-NEXT:[[I_030:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY3]] ], [ 
[[DIV]], [[FOR_BODY3_PREHEADER]] ]
+; CHECK-NEXT:[[ADD:%.*]] = add nsw i32 [[I_030]], [[SHR]]
+; CHECK-NEXT:[[ARRAYIDX:%.*]] = getelementptr inbounds [32 x i32], [32 x 
i32]* @Data, i32 0, i32 [[ADD]]
+; CHECK-NEXT:[[ARRAYIDX4:%.*]] = getelementptr inbounds [32 x i32], [32 x 
i32]* @Data, i32 0, i32 [[I_030]]
+; CHECK-NEXT:[[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, 
[[TBAA3:!tbaa !.*]]
+; CHECK-NEXT:[[TMP1:%.*]] = load i32, i32* [[ARRAYIDX4]], align 4, 
[[TBAA3]]
+; CHECK-NEXT:[[SUB:%.*]] = sub nsw i32 [[TMP1]], [[TMP0]]
+; CHECK-NEXT:store i32 [[SUB]], i32* [[ARRAYIDX]], align 4, [[TBAA3]]
+; CHECK-NEXT:[[ADD7:%.*]] = add nsw i32 [[TMP1]], [[TMP0]]
+; CHECK-NEXT:store i32 [[ADD7]], i32* [[ARRAYIDX4]], align 4, [[TBAA3]]
+; CHECK-NEXT:[[INC]] = add nsw i32 [[I_030]], 1
+; CHECK-NEXT:[[CMP2:%.*]] = icmp slt i32 [[I_030]], 15
+; CHECK-NEXT:br i1 [[CMP2]], label [[FOR_BODY3]], label [[FOR_INC8]]
+; CHECK:   for.inc8:
+; CHECK-NEXT:[[INC9]] = add nuw nsw i32 [[K_031]], 1
+; CHECK-NEXT:[[EXITCOND:%.*]] = icmp eq i32 [[INC9]], 8
+; CHECK-NEXT:br i1 [[EXITCOND]], label [[FOR_END10:%.*]], label 
[[FOR_BODY]]
+; CHECK:   for.end10:
+; CHECK-NEXT:ret void
+;
+entry:
+  br label %for.body
+
+for.body: ; preds = %for.inc8, %entry
+  %k.031 = phi i32 [ 1, %entry ], [ %inc9, %for.inc8 ]
+  %shl = shl i32 1, %k.031
+  %shr = ashr exact i32 %shl, 1
+  %cmp229 = icmp slt i32 %shl, 64
+  br i1 %cmp229, label %for.body3.preheader, label %for.inc8
+
+for.body3.preheader:  ; preds = %for.body
+  %div = sdiv i32 %shr, 2
+  br label %for.body3
+
+for.body3:; preds = 
%for.body3.preheader, %for.body3
+  %i.030 = phi i32 [ %inc, %for.body3 ], [ %div, %for.body3.preheader ]
+  %add = add nsw i32 %i.030, %shr
+  %arrayidx = getelementptr inbounds [32 x i32], [32 x i32]* @Data, i32 0, i32 
%add
+  %arrayidx4 = getelementptr inbounds [32 x i32], [32 x i32]* @Data, i32 0, 
i32 %i.030
+  %0 = load i32, i32* %arrayidx, align 4, !tbaa !3
+  %1 = load i32, i32* %arrayidx4, align 4, !tbaa !3
+  %sub = sub nsw i32 %1, %0
+  store i32 %sub, i32* %arrayidx, align 4, !tbaa !3
+  %2 = load i32, i32* %arrayidx4, align 4, !tbaa !3
+  %add7 = add nsw i32 %2, %0
+  store i32 %add7, i32* %arrayidx4, align 4, !tbaa !3
+  %inc = add nsw i32 %i.030, 1
+  %cmp2 = icmp slt i32 %i.030, 15
+  br i1 %cmp2, label %for.body3, label %for.inc8
+
+for.inc8: ; preds = %for.body3, 
%for.body
+  %inc9 = add nuw nsw i32 %k.031, 1
+  %exitcond = icmp eq i32 %inc9, 8
+  br i1 %exitcond, label %for.end10, label %for.body
+
+for.end10:; preds = %for.inc8
+  ret void
+}
+
+attributes #0 = { norecurse nounwind 
"correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" 
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true" 
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" 
"no-jump-tables"="false" "no-nans-fp-math"="false" 
"no-signed-zeros-fp-math"="false" "no-trapping-math"="false" 
"stack-protector-buffer-size"="8" "target-cpu"="cortex-m7"