================
@@ -2479,6 +2479,39 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) {
if (isBoolNot(previous))
return previous.getInput();
+ // Fold constant unary operations.
+ if (auto srcConst = getInput().getDefiningOp<cir::ConstantOp>()) {
----------------
andykaylor wrote:
I implemented this change, and it looks much better for this PR, but I found
that it leaves behind more dead constants when I use `createOrFold` during
codegen. For instance, this:
```
short s = +(-3);
```
results in this before I explicitly delete the dead constants during
canonicalization:
```
%19 = cir.const #cir.int<3> : !s32i
%20 = cir.const #cir.int<-3> : !s32i
%21 = cir.const #cir.int<-3> : !s32i
%22 = cir.const #cir.int<-3> : !s16i
cir.store align(2) %22, %1 : !s16i, !cir.ptr<!s16i>
```
This is because (1) we emit a constant 3 as the operand to the unary minus, (2)
we fold the unary minus into a constant -3, (3) we fold the unary plus into
another constant -3, and (4) we fold the implicit cast into the last constant
-3. It all makes sense, but it was a bit shocking to see in the output.
My previous implementation did some of that, but it didn't introduce the
duplicate constants in the cases where the folder is just returning the input
value. If we return the actual input value, `createOrFold` will just use it,
but if we return the attribute from the adaptor, it materializes a new
constant. When the folder runs during the canonicalize pass, this isn't a
problem because the folder doesn't materialize things in the middle of the
process, but during codegen we materialize at each step.
I'm going to go with a hybrid approach where I look for the cases where we fold
to the input value explicitly, and otherwise fold via the adaptor.
https://github.com/llvm/llvm-project/pull/174882
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits