[clang] [llvm] [LLVM] Add IRNormalizer Pass (PR #68176)

2024-09-18 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Ping @plotfi @nikic for review.

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [LLVM] Add IRNormalizer Pass (PR #68176)

2024-09-15 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Ping @plotfi @nikic for review. 

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [NVPTX] Remove nvvm.bitcast.* intrinsics (PR #107936)

2024-09-10 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

> can you point me to an analogous change I could use as an example?

[[LLD] Add CLASS syntax to 
SECTIONS](https://github.com/llvm/llvm-project/commit/7e8a9020b1ae3dea28c19f0cd68743482dca13d9#diff-96d3595c06280d8c10f2687758a9e7bb5a0f3552fd53e552a1490411870c3500)
[[LLVM] Add IRNormalizer 
Pass](https://github.com/llvm/llvm-project/pull/68176/files#diff-a7085286edacbd0cdfabdd7382565889ff52dc9013a847d960d148ff4ad2eff8)

https://github.com/llvm/llvm-project/pull/107936
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [LLVM] Add IRNormalizer Pass (PR #68176)

2024-09-07 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Hi @plotfi, thanks for pinging me on this! Generally speaking, two things 
deserve additional focus:

- UX testing to find:
  - Improvements to existing features 
  -  New features to add
- Additional testing to ensure that the pass preserves the semantics of the IR. 
  - e.g. I want to add this pass to the `nvcc` optimization pipeline and run it 
on NVIDIA's internal test suite. 
  - If Meta has similar test suites, it would be great to see if this pass 
introduces any functional issues on it. 

---

> I cannot reproduce these failures on my x86 machine.

Big thanks to @dtcxzyw for running the test-suite. Since @dtcxzyw did not find 
any test failures, this MR is ready for another round of review. 

If things look good to @plotfi and @nikic, then we should be good to get this 
merged!  

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [NVPTX] Add conversion intrinsics from/to fp8 types (e4m3, e5m2) (PR #102969)

2024-08-19 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

> How do I actually upstream it? 

Here is the documentation on how to [obtain commit 
access](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access). 
It's a relatively quick process. 

However, if you don't want to go through that process, you can just ask for it 
to be committed, and someone will do it on your behalf. 

https://github.com/llvm/llvm-project/pull/102969
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [LLVM] Add IRNormalizer Pass (PR #68176)

2024-06-18 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Hi @dtcxzyw, thanks for reaching out! 

This MR is blocked because I cannot reproduce the failures @nikic found 
[here](https://github.com/llvm/llvm-project/pull/68176#issuecomment-1836365664).
 (See [this 
comment](https://github.com/llvm/llvm-project/pull/68176#issuecomment-1818308163)
 to understand the problem I'm running into.)  

The other things that I've mentioned should be easy to fix. 

If you (or anyone else who's interested in helping) can reproduce/debug the 
failure @nikic found, that'd be a big help toward getting this PR over the 
line. 

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [LLVM] Add IRNormalizer Pass (PR #68176)

2024-05-28 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

TODO: Sort function order

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[mlir] [clang] [clang-tools-extra] [llvm] [mlir] Declare promised interfaces for all dialects [2/3] (PR #78368)

2024-01-27 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/78368

>From 7edcf1ad0820457cc2c6530668dd30a758cf42f7 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Thu, 11 Jan 2024 20:00:53 -0800
Subject: [PATCH 1/6] Declare Affine Interfaces

---
 mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 4 
 1 file changed, 4 insertions(+)

diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp 
b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
index d5be2e906989fa..72ac9f30c2af54 100644
--- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
@@ -8,6 +8,7 @@
 
 #include "mlir/Dialect/Affine/IR/AffineOps.h"
 #include "mlir/Dialect/Affine/IR/AffineValueMap.h"
+#include "mlir/Interfaces/ValueBoundsOpInterface.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
 #include "mlir/Dialect/UB/IR/UBOps.h"
 #include "mlir/IR/AffineExprVisitor.h"
@@ -220,6 +221,9 @@ void AffineDialect::initialize() {
 #include "mlir/Dialect/Affine/IR/AffineOps.cpp.inc"
 >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 /// Materialize a single constant operation from a given attribute value with

>From fcee97c95daea0687cbbfc2e9d40e9bec089bf21 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Tue, 16 Jan 2024 15:58:28 -0800
Subject: [PATCH 2/6] Declare most other dialect interface implementations

---
 mlir/lib/Dialect/Arith/IR/ArithDialect.cpp| 13 +
 .../Bufferization/IR/BufferizationDialect.cpp |  4 ++
 .../Dialect/ControlFlow/IR/ControlFlowOps.cpp |  7 +++
 mlir/lib/Dialect/GPU/IR/GPUDialect.cpp|  2 +
 mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp  |  5 ++
 mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp  | 22 +
 mlir/lib/Dialect/SCF/IR/SCF.cpp   | 15 ++
 mlir/lib/Dialect/Shape/IR/Shape.cpp   |  3 ++
 .../SparseTensor/IR/SparseTensorDialect.cpp   | 25 ++
 mlir/lib/Dialect/Tensor/IR/TensorDialect.cpp  | 47 +++
 mlir/lib/Dialect/Vector/IR/VectorOps.cpp  | 17 +++
 11 files changed, 160 insertions(+)

diff --git a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp 
b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
index ed4b91cbe516c9..fea7ab05a69418 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
@@ -7,7 +7,10 @@
 
//===--===//
 
 #include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
+#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/Dialect/UB/IR/UBOps.h"
+#include "mlir/Interfaces/ValueBoundsOpInterface.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/DialectImplementation.h"
 #include "mlir/Transforms/InliningUtils.h"
@@ -44,6 +47,16 @@ void arith::ArithDialect::initialize() {
 #include "mlir/Dialect/Arith/IR/ArithOpsAttributes.cpp.inc"
   >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 /// Materialize an integer or floating point constant.
diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp 
b/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
index e5a0c3c45b09e2..d8a38868ac862a 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
@@ -10,6 +10,7 @@
 #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/Dialect/Bufferization/IR/Bufferization.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/Tensor/IR/Tensor.h"
 #include "mlir/Interfaces/FunctionInterfaces.h"
 #include "mlir/Transforms/InliningUtils.h"
@@ -63,6 +64,9 @@ void mlir::bufferization::BufferizationDialect::initialize() {
 #include "mlir/Dialect/Bufferization/IR/BufferizationOps.cpp.inc"
   >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 LogicalResult BufferizationDialect::verifyRegionArgAttribute(
diff --git a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp 
b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
index fab6f341699908..6bbfb37d988549 100644
--- a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
+++ b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
@@ -9,6 +9,8 @@
 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
 
 #include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
+#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/IR/AffineExpr.h"
 #include "mlir/IR/AffineMap.h"
 #include "mlir/IR/Builders.h"
@@ -67,6 +69,11 @@ void Control

[mlir] [clang-tools-extra] [llvm] [clang] [mlir] Declare promised interfaces for all dialects [2/3] (PR #78368)

2024-01-27 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/78368
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[mlir] [clang-tools-extra] [llvm] [clang] [mlir] Declare promised interfaces for all dialects [2/3] (PR #78368)

2024-01-27 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/78368
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[mlir] [clang-tools-extra] [llvm] [clang] [mlir] Declare promised interfaces for all dialects (PR #78368)

2024-01-27 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Open question: where should I declare promised interfaces for the `builtin` 
Dialect? 

https://github.com/llvm/llvm-project/pull/78368
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[mlir] [clang-tools-extra] [llvm] [clang] [mlir] Declare promised interfaces for all dialects (PR #78368)

2024-01-27 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/78368
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[mlir] [clang-tools-extra] [clang] [llvm] Jf/promise interfaces (PR #78368)

2024-01-27 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/78368

>From 7edcf1ad0820457cc2c6530668dd30a758cf42f7 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Thu, 11 Jan 2024 20:00:53 -0800
Subject: [PATCH 1/5] Declare Affine Interfaces

---
 mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 4 
 1 file changed, 4 insertions(+)

diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp 
b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
index d5be2e906989fa..72ac9f30c2af54 100644
--- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
@@ -8,6 +8,7 @@
 
 #include "mlir/Dialect/Affine/IR/AffineOps.h"
 #include "mlir/Dialect/Affine/IR/AffineValueMap.h"
+#include "mlir/Interfaces/ValueBoundsOpInterface.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
 #include "mlir/Dialect/UB/IR/UBOps.h"
 #include "mlir/IR/AffineExprVisitor.h"
@@ -220,6 +221,9 @@ void AffineDialect::initialize() {
 #include "mlir/Dialect/Affine/IR/AffineOps.cpp.inc"
 >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 /// Materialize a single constant operation from a given attribute value with

>From fcee97c95daea0687cbbfc2e9d40e9bec089bf21 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Tue, 16 Jan 2024 15:58:28 -0800
Subject: [PATCH 2/5] Declare most other dialect interface implementations

---
 mlir/lib/Dialect/Arith/IR/ArithDialect.cpp| 13 +
 .../Bufferization/IR/BufferizationDialect.cpp |  4 ++
 .../Dialect/ControlFlow/IR/ControlFlowOps.cpp |  7 +++
 mlir/lib/Dialect/GPU/IR/GPUDialect.cpp|  2 +
 mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp  |  5 ++
 mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp  | 22 +
 mlir/lib/Dialect/SCF/IR/SCF.cpp   | 15 ++
 mlir/lib/Dialect/Shape/IR/Shape.cpp   |  3 ++
 .../SparseTensor/IR/SparseTensorDialect.cpp   | 25 ++
 mlir/lib/Dialect/Tensor/IR/TensorDialect.cpp  | 47 +++
 mlir/lib/Dialect/Vector/IR/VectorOps.cpp  | 17 +++
 11 files changed, 160 insertions(+)

diff --git a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp 
b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
index ed4b91cbe516c9..fea7ab05a69418 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
@@ -7,7 +7,10 @@
 
//===--===//
 
 #include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
+#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/Dialect/UB/IR/UBOps.h"
+#include "mlir/Interfaces/ValueBoundsOpInterface.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/DialectImplementation.h"
 #include "mlir/Transforms/InliningUtils.h"
@@ -44,6 +47,16 @@ void arith::ArithDialect::initialize() {
 #include "mlir/Dialect/Arith/IR/ArithOpsAttributes.cpp.inc"
   >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 /// Materialize an integer or floating point constant.
diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp 
b/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
index e5a0c3c45b09e2..d8a38868ac862a 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
@@ -10,6 +10,7 @@
 #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/Dialect/Bufferization/IR/Bufferization.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/Tensor/IR/Tensor.h"
 #include "mlir/Interfaces/FunctionInterfaces.h"
 #include "mlir/Transforms/InliningUtils.h"
@@ -63,6 +64,9 @@ void mlir::bufferization::BufferizationDialect::initialize() {
 #include "mlir/Dialect/Bufferization/IR/BufferizationOps.cpp.inc"
   >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 LogicalResult BufferizationDialect::verifyRegionArgAttribute(
diff --git a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp 
b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
index fab6f341699908..6bbfb37d988549 100644
--- a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
+++ b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
@@ -9,6 +9,8 @@
 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
 
 #include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
+#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/IR/AffineExpr.h"
 #include "mlir/IR/AffineMap.h"
 #include "mlir/IR/Builders.h"
@@ -67,6 +69,11 @@ void Control

[libc] [llvm] [compiler-rt] [libcxx] [lld] [lldb] [flang] [clang-tools-extra] [libcxxabi] [clang] [NVPTX] Improve lowering of v4i8 (PR #67866)

2024-01-25 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/67866
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [libcxx] [libc] [clang] [flang] [compiler-rt] [libcxxabi] [lldb] [clang-tools-extra] [lld] [NVPTX] Improve lowering of v4i8 (PR #67866)

2024-01-24 Thread Justin Fargnoli via cfe-commits


@@ -2110,6 +2214,29 @@ def : Pat<(seteq Int1Regs:$a, Int1Regs:$b),
 def : Pat<(setueq Int1Regs:$a, Int1Regs:$b),
   (NOT1 (XORb1rr Int1Regs:$a, Int1Regs:$b))>;
 
+// comparisons of i8 extracted with BFE as i32
+def: Pat<(setgt (sext_inreg (trunc Int32Regs:$a), i8), (sext_inreg (trunc 
Int32Regs:$b), i8)),
+ (SETP_s32rr Int32Regs:$a, Int32Regs:$b, CmpGT)>;
+def: Pat<(setge (sext_inreg (trunc Int32Regs:$a), i8), (sext_inreg (trunc 
Int32Regs:$b), i8)),
+ (SETP_s32rr Int32Regs:$a, Int32Regs:$b, CmpGE)>;
+def: Pat<(setlt (sext_inreg (trunc Int32Regs:$a), i8), (sext_inreg (trunc 
Int32Regs:$b), i8)),
+ (SETP_s32rr Int32Regs:$a, Int32Regs:$b, CmpLT)>;
+def: Pat<(setle (sext_inreg (trunc Int32Regs:$a), i8), (sext_inreg (trunc 
Int32Regs:$b), i8)),
+ (SETP_s32rr Int32Regs:$a, Int32Regs:$b, CmpLE)>;
+
+def: Pat<(setugt (i16 (and (trunc Int32Regs:$a), 255)), (i16 (and (trunc 
Int32Regs:$b), 255))),
+ (SETP_u32rr Int32Regs:$a, Int32Regs:$b, CmpHI)>;
+def: Pat<(setuge (i16 (and (trunc Int32Regs:$a), 255)), (i16 (and (trunc 
Int32Regs:$b), 255))),
+ (SETP_u32rr Int32Regs:$a, Int32Regs:$b, CmpHS)>;
+def: Pat<(setult (i16 (and (trunc Int32Regs:$a), 255)), (i16 (and (trunc 
Int32Regs:$b), 255))),
+ (SETP_u32rr Int32Regs:$a, Int32Regs:$b, CmpLO)>;
+def: Pat<(setule (i16 (and (trunc Int32Regs:$a), 255)), (i16 (and (trunc 
Int32Regs:$b), 255))),
+ (SETP_u32rr Int32Regs:$a, Int32Regs:$b, CmpLS)>;
+def: Pat<(seteq (i16 (and (trunc Int32Regs:$a), 255)), (i16 (and (trunc 
Int32Regs:$b), 255))),
+ (SETP_u32rr Int32Regs:$a, Int32Regs:$b, CmpEQ)>;
+def: Pat<(setne (i16 (and (trunc Int32Regs:$a), 255)), (i16 (and (trunc 
Int32Regs:$b), 255))),
+ (SETP_u32rr Int32Regs:$a, Int32Regs:$b, CmpNE)>;

justinfargnoli wrote:

Hi @Artem-B, I believe that these patterns are not correct.

Doing the comparison, without first ensuring that the value only uses the lower 
8 bits, can lead to incorrect results. For example, when %a := Ox100 and %b := 
Ox1,
setugt (i16 (and (trunc Int32Regs:$a), 255)), (i16 (and (trunc Int32Regs:$b), 
255))) produces a false predicate. Whereas SETP_u32rr Int32Regs:$a, 
Int32Regs:$b, CmpHI will produce a true predicate.

(I'm not super familiar with the pattern syntax through, so please correct me 
if I'm misunderstanding something.)

https://github.com/llvm/llvm-project/pull/67866
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [mlir] [llvm] [clang] Jf/promise interfaces (PR #78368)

2024-01-16 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/78368

>From 7edcf1ad0820457cc2c6530668dd30a758cf42f7 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Thu, 11 Jan 2024 20:00:53 -0800
Subject: [PATCH 1/4] Declare Affine Interfaces

---
 mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 4 
 1 file changed, 4 insertions(+)

diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp 
b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
index d5be2e906989fa..72ac9f30c2af54 100644
--- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
@@ -8,6 +8,7 @@
 
 #include "mlir/Dialect/Affine/IR/AffineOps.h"
 #include "mlir/Dialect/Affine/IR/AffineValueMap.h"
+#include "mlir/Interfaces/ValueBoundsOpInterface.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
 #include "mlir/Dialect/UB/IR/UBOps.h"
 #include "mlir/IR/AffineExprVisitor.h"
@@ -220,6 +221,9 @@ void AffineDialect::initialize() {
 #include "mlir/Dialect/Affine/IR/AffineOps.cpp.inc"
 >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 /// Materialize a single constant operation from a given attribute value with

>From fcee97c95daea0687cbbfc2e9d40e9bec089bf21 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Tue, 16 Jan 2024 15:58:28 -0800
Subject: [PATCH 2/4] Declare most other dialect interface implementations

---
 mlir/lib/Dialect/Arith/IR/ArithDialect.cpp| 13 +
 .../Bufferization/IR/BufferizationDialect.cpp |  4 ++
 .../Dialect/ControlFlow/IR/ControlFlowOps.cpp |  7 +++
 mlir/lib/Dialect/GPU/IR/GPUDialect.cpp|  2 +
 mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp  |  5 ++
 mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp  | 22 +
 mlir/lib/Dialect/SCF/IR/SCF.cpp   | 15 ++
 mlir/lib/Dialect/Shape/IR/Shape.cpp   |  3 ++
 .../SparseTensor/IR/SparseTensorDialect.cpp   | 25 ++
 mlir/lib/Dialect/Tensor/IR/TensorDialect.cpp  | 47 +++
 mlir/lib/Dialect/Vector/IR/VectorOps.cpp  | 17 +++
 11 files changed, 160 insertions(+)

diff --git a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp 
b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
index ed4b91cbe516c9..fea7ab05a69418 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
@@ -7,7 +7,10 @@
 
//===--===//
 
 #include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
+#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/Dialect/UB/IR/UBOps.h"
+#include "mlir/Interfaces/ValueBoundsOpInterface.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/DialectImplementation.h"
 #include "mlir/Transforms/InliningUtils.h"
@@ -44,6 +47,16 @@ void arith::ArithDialect::initialize() {
 #include "mlir/Dialect/Arith/IR/ArithOpsAttributes.cpp.inc"
   >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 /// Materialize an integer or floating point constant.
diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp 
b/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
index e5a0c3c45b09e2..d8a38868ac862a 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
@@ -10,6 +10,7 @@
 #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/Dialect/Bufferization/IR/Bufferization.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/Tensor/IR/Tensor.h"
 #include "mlir/Interfaces/FunctionInterfaces.h"
 #include "mlir/Transforms/InliningUtils.h"
@@ -63,6 +64,9 @@ void mlir::bufferization::BufferizationDialect::initialize() {
 #include "mlir/Dialect/Bufferization/IR/BufferizationOps.cpp.inc"
   >();
   addInterfaces();
+  declarePromisedInterface();
+  declarePromisedInterface();
+  declarePromisedInterface();
 }
 
 LogicalResult BufferizationDialect::verifyRegionArgAttribute(
diff --git a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp 
b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
index fab6f341699908..6bbfb37d988549 100644
--- a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
+++ b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
@@ -9,6 +9,8 @@
 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
 
 #include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
+#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/IR/AffineExpr.h"
 #include "mlir/IR/AffineMap.h"
 #include "mlir/IR/Builders.h"
@@ -67,6 +69,11 @@ void Control

[clang-tools-extra] [clang] [llvm] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-30 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Unless other comments brought up, I'll plan on merging this on Monday the 4th. 

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-25 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Pinging @nikic for another round of review. 

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-19 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

> I would recommend trying to run this pass (with all options enabled) over all 
> existing tests to make sure that it doesn't cause any crashes/verifier 
> failures. You're moving instructions around, and it's easy to get that wrong 
> when invoke, callbr or catchswitch are involved.

Thanks for this suggestion! It helped iron out a lot of bugs in the 
implementation. 

> I would also try to add this pass at the end of the clang pipeline and run 
> llvm-test-suite to verify that the normalization this does is indeed 
> semantics-preserving.

I'm running into some linking errors when trying to build 
[`llvm-test-suite`](https://github.com/llvm/llvm-test-suite/tree/main). Pinging 
for another round of review in the meantime. 

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [llvm] [clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-19 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang-tools-extra] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-19 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang-tools-extra] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-11 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang-tools-extra] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-11 Thread Justin Fargnoli via cfe-commits


@@ -0,0 +1,637 @@
+//===--- IRNormalizer.cpp - IR Normalizer ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRNormalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The normalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/Transforms/Utils/IRNormalizer.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "normalize"
+
+using namespace llvm;
+
+namespace {
+/// IRNormalizer aims to transform LLVM IR into canonical form.
+class IRNormalizer {
+public:
+  /// \name Normalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  bool runOnFunction(Function &F);
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+  DenseSet NamedInstructions;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+cl::opt IRNormalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRNormalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRNormalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds all regular instructions (including pre-outputs)"));
+cl::opt IRNormalizer::ReorderOperands(
+"reorder-operands", cl::Hidden,
+cl::desc("Sorts and reorders operands in commutative instructions"));
+
+/// Entry method to the IRNormalizer.
+///
+/// \param M Module to normalize.
+bool IRNormalizer::runOnFunction(Function &F) {
+  nameFunctionArguments(F);
+  nameBasicBlocks(F);
+
+  SmallVector Outputs = collectOutputInstructions(F);
+
+  if (!PreserveOrder)
+reorderInstructions(Outputs);
+
+  for (auto &I : Outputs)
+nameInstruction(I);
+
+  for (auto &I : instructions(F)) {
+if (!PreserveOrder) {
+  if (ReorderOperands && I.isCommutative())
+reorderInstructionOperandsByNames(&I);
+
+  if (auto *PN = dyn_cast(&I))
+reorderPHIIncomingValues(PN);
+}
+
+foldInstructionName(&I);
+  }
+
+  return true;
+}
+
+/// Numbers arguments.
+///
+/// \param F Function whose arguments will be renamed.
+void IRNormalizer::nameFunctionArguments(Function &F) {
+  int ArgumentCounter = 0;
+  for (auto &A : F.args()) {
+if (RenameAll || A.getName().empty()) {
+  A.setName("a" + Twine(ArgumentCounter));
+  ++ArgumentCounter;
+}
+  }
+}
+
+/// Names basic blocks using a generated hash for each basic block in
+/// a function considering the opcode and the order of output instructions.
+///
+/// \param F Function containing basic blocks to rename.
+void IRNormalizer::nameBasicBlocks(Function &F) {
+  for (auto &B : F) {
+

[llvm] [clang-tools-extra] [clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-11 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/31] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[llvm] [clang-tools-extra] [clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-10 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/30] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[llvm] [clang-tools-extra] [clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-10 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/29] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang] [clang-tools-extra] [llvm] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-10 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/28] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang-tools-extra] [llvm] [clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-10 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/26] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[llvm] [clang-tools-extra] [clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-11-10 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/25] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[llvm] [clang] [clang-tools-extra] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-10-31 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Ping for another round of review. 

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [MLIR][scf.parallel] Don't allow a tile size of 0 (PR #68762)

2023-10-23 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli closed 
https://github.com/llvm/llvm-project/pull/68762
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [MLIR][scf.parallel] Don't allow a tile size of 0 (PR #68762)

2023-10-22 Thread Justin Fargnoli via cfe-commits


@@ -0,0 +1,8 @@
+// RUN: mlir-opt %s 
-pass-pipeline='builtin.module(func.func(scf-parallel-loop-tiling{parallel-loop-tile-sizes=0,0}))'
 -split-input-file -verify-diagnostics
+
+// XFAIL: *

justinfargnoli wrote:

It looks like it isn't possible to use `expected-error` to check for an error 
at an `UnknownLoc`. If this is true, am I good to go forward with using 
`XFAIL`? 

https://github.com/llvm/llvm-project/pull/68762
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [mlir][DeadCodeAnalysis] Don't Require `RegionBranchTerminatorOpInterface` in `visitRegionTerminator()` (PR #69043)

2023-10-22 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli closed 
https://github.com/llvm/llvm-project/pull/69043
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [mlir][DeadCodeAnalysis] Don't Require `RegionBranchTerminatorOpInterface` in `visitRegionTerminator()` (PR #69043)

2023-10-21 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/69043

>From 8f8b644792d5e26f76d98bd8ba45440443f9a260 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Fri, 13 Oct 2023 18:16:45 -0700
Subject: [PATCH 1/4] Initial commit

---
 .../mlir/Analysis/DataFlow/DeadCodeAnalysis.h|  2 +-
 mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp  | 12 +++-
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h 
b/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h
index 7a6fea8326a58b8..ce262c3ac5291ff 100644
--- a/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h
@@ -208,7 +208,7 @@ class DeadCodeAnalysis : public DataFlowAnalysis {
   /// Visit the given terminator operation that exits a region under an
   /// operation with control-flow semantics. These are terminators with no CFG
   /// successors.
-  void visitRegionTerminator(RegionBranchTerminatorOpInterface op,
+  void visitRegionTerminator(Operation *op,
  RegionBranchOpInterface branch);
 
   /// Visit the given terminator operation that exits a callable region. These
diff --git a/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp 
b/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp
index d423d37b9770c69..30a862fa048f97a 100644
--- a/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp
@@ -259,8 +259,7 @@ LogicalResult DeadCodeAnalysis::visit(ProgramPoint point) {
   if (isRegionOrCallableReturn(op)) {
 if (auto branch = dyn_cast(op->getParentOp())) {
   // Visit the exiting terminator of a region.
-  visitRegionTerminator(cast(op),
-branch);
+  visitRegionTerminator(op, branch);
 } else if (auto callable =
dyn_cast(op->getParentOp())) {
   // Visit the exiting terminator of a callable.
@@ -379,14 +378,17 @@ void DeadCodeAnalysis::visitRegionBranchOperation(
   }
 }
 
-void DeadCodeAnalysis::visitRegionTerminator(
-RegionBranchTerminatorOpInterface op, RegionBranchOpInterface branch) {
+void DeadCodeAnalysis::visitRegionTerminator(Operation *op, 
+ RegionBranchOpInterface branch) {
   std::optional> operands = getOperandValues(op);
   if (!operands)
 return;
 
   SmallVector successors;
-  op.getSuccessorRegions(*operands, successors);
+  if (auto terminator = dyn_cast(op))
+terminator.getSuccessorRegions(*operands, successors);
+  else
+branch.getSuccessorRegions(op->getParentRegion(), successors);
 
   // Mark successor region entry blocks as executable and add this op to the
   // list of predecessors.

>From ec79bc71013c8433a83948a256b313a0f93cf826 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Fri, 13 Oct 2023 18:34:11 -0700
Subject: [PATCH 2/4] Add test

---
 .../DataFlow/test-dead-code-analysis-regression.mlir | 5 +
 1 file changed, 5 insertions(+)
 create mode 100644 
mlir/test/Analysis/DataFlow/test-dead-code-analysis-regression.mlir

diff --git 
a/mlir/test/Analysis/DataFlow/test-dead-code-analysis-regression.mlir 
b/mlir/test/Analysis/DataFlow/test-dead-code-analysis-regression.mlir
new file mode 100644
index 000..70c44970519cc24
--- /dev/null
+++ b/mlir/test/Analysis/DataFlow/test-dead-code-analysis-regression.mlir
@@ -0,0 +1,5 @@
+// RUN: mlir-opt -int-range-optimizations %s 
+
+%0 = scf.execute_region -> tensor<5x16xi16> {
+  llvm.unreachable
+}

>From 56b7099c7648be1fe22268bbeb311c9773a2f894 Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 14 Oct 2023 17:20:15 -0400
Subject: [PATCH 3/4] clang-format changes

---
 mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h | 3 +--
 mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp| 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h 
b/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h
index ce262c3ac5291ff..10ef8b6ba5843a9 100644
--- a/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/DeadCodeAnalysis.h
@@ -208,8 +208,7 @@ class DeadCodeAnalysis : public DataFlowAnalysis {
   /// Visit the given terminator operation that exits a region under an
   /// operation with control-flow semantics. These are terminators with no CFG
   /// successors.
-  void visitRegionTerminator(Operation *op,
- RegionBranchOpInterface branch);
+  void visitRegionTerminator(Operation *op, RegionBranchOpInterface branch);
 
   /// Visit the given terminator operation that exits a callable region. These
   /// are terminators with no CFG successors.
diff --git a/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp 
b/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp
index 30a862fa048f97a..07f9705912260a4 100644
--- a/mlir/lib/Analysis/DataFlow/DeadCodeAnaly

[clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-10-21 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/20] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang-tools-extra] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-10-21 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/20] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-10-21 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/20] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-10-15 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/19] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang-tools-extra] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-10-14 Thread Justin Fargnoli via cfe-commits

justinfargnoli wrote:

Renamed to IRNormalizer. Requesting another round of review. 

https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-10-14 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/18] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang-tools-extra] [LLVM] Add IRNormalizer Pass (PR #68176)

2023-10-14 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [LLVM] Add Normalizer Pass (PR #68176)

2023-10-14 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [LLVM] Add Normalizer Pass (PR #68176)

2023-10-14 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli edited 
https://github.com/llvm/llvm-project/pull/68176
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] llvm-canon (PR #68176)

2023-10-14 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/17] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang-tools-extra] llvm-canon (PR #68176)

2023-10-04 Thread Justin Fargnoli via cfe-commits


@@ -0,0 +1,638 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include "llvm/Transforms/Utils/IRCanonicalizer.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer {
+public:
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  bool runOnFunction(Function &F);
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+  DenseSet NamedInstructions;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds all regular instructions (including pre-outputs)"));
+cl::opt IRCanonicalizer::ReorderOperands(
+"reorder-operands", cl::Hidden,
+cl::desc("Sorts and reorders operands in commutative instructions"));
+
+/// Entry method to the IRCanonicalizer.
+///
+/// \param M Module to canonicalize.
+bool IRCanonicalizer::runOnFunction(Function &F) {
+  nameFunctionArguments(F);
+  nameBasicBlocks(F);
+
+  SmallVector Outputs = collectOutputInstructions(F);
+
+  if (!PreserveOrder)
+reorderInstructions(Outputs);
+
+  for (auto &I : Outputs)
+nameInstruction(I);
+
+  for (auto &I : instructions(F)) {
+if (!PreserveOrder) {
+  if (ReorderOperands && I.isCommutative())
+reorderInstructionOperandsByNames(&I);
+
+  if (auto *PN = dyn_cast(&I))
+reorderPHIIncomingValues(PN);
+}
+
+foldInstructionName(&I);
+  }
+
+  return true;
+}
+
+/// Numbers arguments.
+///
+/// \param F Function whose arguments will be renamed.
+void IRCanonicalizer::nameFunctionArguments(Function &F) {
+  int ArgumentCounter = 0;
+  for (auto &A : F.args()) {
+if (RenameAll || A.getName().empty()) {
+  A.setName("a" + Twine(ArgumentCounter));
+  ++ArgumentCounter;
+}
+  }
+}
+
+/// Names basic blocks using a generated hash for each basic block in
+/// a function considering the opcode and the order of output instructions.
+///
+/// \param F Function containing basic blocks to rename.
+void IRCanonicalizer::nameBas

[clang] llvm-canon (PR #68176)

2023-10-04 Thread Justin Fargnoli via cfe-commits


@@ -0,0 +1,638 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include "llvm/Transforms/Utils/IRCanonicalizer.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer {
+public:
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  bool runOnFunction(Function &F);
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+  DenseSet NamedInstructions;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds all regular instructions (including pre-outputs)"));
+cl::opt IRCanonicalizer::ReorderOperands(
+"reorder-operands", cl::Hidden,
+cl::desc("Sorts and reorders operands in commutative instructions"));
+
+/// Entry method to the IRCanonicalizer.
+///
+/// \param M Module to canonicalize.
+bool IRCanonicalizer::runOnFunction(Function &F) {
+  nameFunctionArguments(F);
+  nameBasicBlocks(F);
+
+  SmallVector Outputs = collectOutputInstructions(F);
+
+  if (!PreserveOrder)
+reorderInstructions(Outputs);
+
+  for (auto &I : Outputs)
+nameInstruction(I);
+
+  for (auto &I : instructions(F)) {
+if (!PreserveOrder) {
+  if (ReorderOperands && I.isCommutative())
+reorderInstructionOperandsByNames(&I);
+
+  if (auto *PN = dyn_cast(&I))
+reorderPHIIncomingValues(PN);
+}
+
+foldInstructionName(&I);
+  }
+
+  return true;
+}
+
+/// Numbers arguments.
+///
+/// \param F Function whose arguments will be renamed.
+void IRCanonicalizer::nameFunctionArguments(Function &F) {
+  int ArgumentCounter = 0;
+  for (auto &A : F.args()) {
+if (RenameAll || A.getName().empty()) {
+  A.setName("a" + Twine(ArgumentCounter));
+  ++ArgumentCounter;
+}
+  }
+}
+
+/// Names basic blocks using a generated hash for each basic block in
+/// a function considering the opcode and the order of output instructions.
+///
+/// \param F Function containing basic blocks to rename.
+void IRCanonicalizer::nameBas

[clang-tools-extra] llvm-canon (PR #68176)

2023-10-04 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/16] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang] llvm-canon (PR #68176)

2023-10-04 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/16] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang-tools-extra] llvm-canon (PR #68176)

2023-10-03 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/15] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang] llvm-canon (PR #68176)

2023-10-03 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli updated 
https://github.com/llvm/llvm-project/pull/68176

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/15] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &Visited);
+  void reorderInstructionOperandsByNames(Instruction *I);
+  void reorderPHIIncomingValues(PHINode *PN);
+  /// @}
+
+  /// \name Utility methods.
+  /// @{
+  SmallVector collectOutputInstructions(Function &F);
+  bool isOutput(const Instruction *I);
+  bool isInitialInstruction(const Instruction *I);
+  bool hasOnlyImmediateOperands(const Instruction *I);
+  SetVector
+  getOutputFootprint(Instruction *I,
+ SmallPtrSet &Visited);
+  /// @}
+};
+} // namespace
+
+char IRCanonicalizer::ID = 0;
+static RegisterPass X("canon", "Canonicalize the IR",
+   false /* Only looks at CFG */,
+   false /* Analysis Pass */);
+
+cl::opt IRCanonicalizer::PreserveOrder(
+"preserve-order", cl::Hidden,
+cl::desc("Preserves original instruction order"));
+cl::opt IRCanonicalizer::RenameAll(
+"rename-all", cl::Hidden,
+cl::desc("Renames all instructions (including user-named)"));
+cl::opt IRCanonicalizer::FoldPreoutputs(
+"fold-all", cl::Hidden,
+cl::desc("Folds 

[clang] llvm-canon (PR #68176)

2023-10-03 Thread Justin Fargnoli via cfe-commits

https://github.com/justinfargnoli created 
https://github.com/llvm/llvm-project/pull/68176

Add the llvm-canon tool. Description from the [original 
PR](https://reviews.llvm.org/D66029#change-wZv3yOpDdxIu):

> Added a new llvm-canon tool which aims to transform LLVM Modules into a 
> canonical form by reordering and renaming instructions while preserving the 
> same semantics. This tool makes it easier to spot semantic differences while 
> diffing two modules which have undergone different transformation passes.

This code was originally written by @michalpaszkowski and [submitted to 
mainline 
LLVM](https://reviews.llvm.org/rG14d358537f124a732adad1ec6edf3981dc9baece). 
However, it was quickly 
[reverted](https://reviews.llvm.org/rG335de55fa3384946f1e62050f2545c0966163236) 
to do some BuildBot errors. 

@AidanGoldfarb and I ported the code to the new pass manager, added more tests, 
and fixed some bugs related to PHI nodes that may have been the root cause of 
the BuildBot errors that caused the patch to be reverted. 

Note that this is @AidanGoldfarb and I's first time submitting to LLVM. Please 
liberally critique the PR! 

CC @plotfi for initial review. 

>From f792a030ac1761a96176332fea906cd2d1826c7b Mon Sep 17 00:00:00 2001
From: justinfargnoli 
Date: Sat, 12 Aug 2023 10:58:45 -0700
Subject: [PATCH 01/14] Add IRCanonicalizer.cpp

---
 llvm/lib/Transforms/Utils/CMakeLists.txt  |   1 +
 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp | 632 ++
 2 files changed, 633 insertions(+)
 create mode 100644 llvm/lib/Transforms/Utils/IRCanonicalizer.cpp

diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt 
b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a870071f3f641dc..7866e7a8c09c3be 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_component_library(LLVMTransformUtils
   InjectTLIMappings.cpp
   InstructionNamer.cpp
   IntegerDivision.cpp
+  IRCanonicalizer.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
   Local.cpp
diff --git a/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp 
b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
new file mode 100644
index 000..58e2dce0b96685b
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/IRCanonicalizer.cpp
@@ -0,0 +1,632 @@
+//===--- IRCanonicalizer.cpp - IR Canonicalizer 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+/// \file
+/// This file implements the IRCanonicalizer class which aims to transform LLVM
+/// Modules into a canonical form by reordering and renaming instructions while
+/// preserving the same semantics. The canonicalizer makes it easier to spot
+/// semantic differences while diffing two modules which have undergone
+/// different passes.
+///
+//===--===//
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/Utils.h"
+#include 
+#include 
+
+#define DEBUG_TYPE "canon"
+
+using namespace llvm;
+
+namespace {
+/// IRCanonicalizer aims to transform LLVM IR into canonical form.
+class IRCanonicalizer : public FunctionPass {
+public:
+  static char ID;
+
+  /// \name Canonicalizer flags.
+  /// @{
+  /// Preserves original order of instructions.
+  static cl::opt PreserveOrder;
+  /// Renames all instructions (including user-named).
+  static cl::opt RenameAll;
+  /// Folds all regular instructions (including pre-outputs).
+  static cl::opt FoldPreoutputs;
+  /// Sorts and reorders operands in commutative instructions.
+  static cl::opt ReorderOperands;
+  /// @}
+
+  /// Constructor for the IRCanonicalizer.
+  IRCanonicalizer() : FunctionPass(ID) {}
+
+  bool runOnFunction(Function &F) override;
+
+private:
+  // Random constant for hashing, so the state isn't zero.
+  const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
+
+  /// \name Naming.
+  /// @{
+  void nameFunctionArguments(Function &F);
+  void nameBasicBlocks(Function &F);
+  void nameInstruction(Instruction *I);
+  void nameAsInitialInstruction(Instruction *I);
+  void nameAsRegularInstruction(Instruction *I);
+  void foldInstructionName(Instruction *I);
+  /// @}
+
+  /// \name Reordering.
+  /// @{
+  void reorderInstructions(SmallVector &Outputs);
+  void reorderInstruction(Instruction *Used, Instruction *User,
+  SmallPtrSet &