-
Notifications
You must be signed in to change notification settings - Fork 15k
[GlobalISel] Transform anyext(freeze(trunc(x))) to freeze(x) #165679
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
We already have a transform for (anyext (trunc x)) -> x, this adds an extended version for (anyext (freeze (trunc x))) -> (freeze x). As we treat freeze i8 and i16 as legal this can help reduce the number of extends in the code.
|
@llvm/pr-subscribers-llvm-globalisel Author: David Green (davemgreen) ChangesWe already have a transform for (anyext (trunc x)) -> x, this adds an extended version for (anyext (freeze (trunc x))) -> (freeze x). As we treat freeze i8 and i16 as legal this can help reduce the number of extends in the code. Full diff: https://github.com/llvm/llvm-project/pull/165679.diff 2 Files Affected:
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 119695e53c3cb..a102e3f0c6a47 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -805,16 +805,28 @@ def redundant_sext_inreg: GICombineRule <
(defs root:$root),
(match (wip_match_opcode G_SEXT_INREG):$root,
[{ return Helper.matchRedundantSExtInReg(*${root}); }]),
- (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
-// Fold (anyext (trunc x)) -> x if the source type is same as
-// the destination type.
+// Fold (anyext (trunc x)) -> x if the source type is same as the destination
+// type.
def anyext_trunc_fold: GICombineRule <
- (defs root:$root, register_matchinfo:$matchinfo),
- (match (wip_match_opcode G_ANYEXT):$root,
- [{ return Helper.matchCombineAnyExtTrunc(*${root}, ${matchinfo}); }]),
- (apply [{ Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+ (defs root:$root),
+ (match (G_TRUNC $x, $src),
+ (G_ANYEXT $dst, $x):$root,
+ [{ return MRI.getType(${dst}.getReg()) == MRI.getType(${src}.getReg()); }]),
+ (apply (GIReplaceReg $dst, $src))
+>;
+
+// Fold (anyext (freeze (trunc x))) -> (freeze x) if the source type is same as
+// the destination type.
+def anyext_freeze_trunc_fold: GICombineRule <
+ (defs root:$root),
+ (match (G_TRUNC $x, $src),
+ (G_FREEZE $y, $x),
+ (G_ANYEXT $dst, $y):$root,
+ [{ return MRI.getType(${dst}.getReg()) == MRI.getType(${src}.getReg()); }]),
+ (apply (G_FREEZE $dst, $src))
>;
// Fold (zext (trunc x)) -> x if the source type is same as the destination type
@@ -2084,7 +2096,7 @@ def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
binop_same_val, binop_left_to_zero,
binop_right_to_zero, p2i_to_i2p,
- i2p_to_p2i, anyext_trunc_fold,
+ i2p_to_p2i, anyext_trunc_fold, anyext_freeze_trunc_fold,
fneg_fneg_fold, right_identity_one,
add_sub_reg, buildvector_identity_fold,
trunc_buildvector_fold,
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-ext.mir
index 629238126380c..2b24a8920e0e0 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-ext.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-ext.mir
@@ -385,8 +385,8 @@ body: |
; CHECK: liveins: $h0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
- ; CHECK-NEXT: %2:_(s64) = nneg G_ZEXT [[COPY]](s16)
- ; CHECK-NEXT: $x0 = COPY %2(s64)
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = nneg G_ZEXT [[COPY]](s16)
+ ; CHECK-NEXT: $x0 = COPY [[ZEXT]](s64)
%0:_(s16) = COPY $h0
%1:_(s32) = G_ANYEXT %0(s16)
%2:_(s64) = nneg G_ZEXT %1(s32)
@@ -401,10 +401,27 @@ body: |
; CHECK: liveins: $h0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
- ; CHECK-NEXT: %2:_(s64) = nneg G_ZEXT [[COPY]](s16)
- ; CHECK-NEXT: $x0 = COPY %2(s64)
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = nneg G_ZEXT [[COPY]](s16)
+ ; CHECK-NEXT: $x0 = COPY [[ZEXT]](s64)
%0:_(s16) = COPY $h0
%1:_(s32) = nneg G_ZEXT %0(s16)
%2:_(s64) = G_ANYEXT %1(s32)
$x0 = COPY %2(s64)
...
+---
+name: test_combine_anyext_freeze_trunc
+body: |
+ bb.1:
+ liveins: $x0
+ ; CHECK-LABEL: name: test_combine_anyext_freeze_trunc
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY]]
+ ; CHECK-NEXT: $x1 = COPY [[FREEZE]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s32) = G_TRUNC %0(s64)
+ %2:_(s32) = G_FREEZE %1(s32)
+ %3:_(s64) = G_ANYEXT %2(s32)
+ $x1 = COPY %3(s64)
+...
|
|
@llvm/pr-subscribers-backend-aarch64 Author: David Green (davemgreen) ChangesWe already have a transform for (anyext (trunc x)) -> x, this adds an extended version for (anyext (freeze (trunc x))) -> (freeze x). As we treat freeze i8 and i16 as legal this can help reduce the number of extends in the code. Full diff: https://github.com/llvm/llvm-project/pull/165679.diff 2 Files Affected:
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 119695e53c3cb..a102e3f0c6a47 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -805,16 +805,28 @@ def redundant_sext_inreg: GICombineRule <
(defs root:$root),
(match (wip_match_opcode G_SEXT_INREG):$root,
[{ return Helper.matchRedundantSExtInReg(*${root}); }]),
- (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+ (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
>;
-// Fold (anyext (trunc x)) -> x if the source type is same as
-// the destination type.
+// Fold (anyext (trunc x)) -> x if the source type is same as the destination
+// type.
def anyext_trunc_fold: GICombineRule <
- (defs root:$root, register_matchinfo:$matchinfo),
- (match (wip_match_opcode G_ANYEXT):$root,
- [{ return Helper.matchCombineAnyExtTrunc(*${root}, ${matchinfo}); }]),
- (apply [{ Helper.replaceSingleDefInstWithReg(*${root}, ${matchinfo}); }])
+ (defs root:$root),
+ (match (G_TRUNC $x, $src),
+ (G_ANYEXT $dst, $x):$root,
+ [{ return MRI.getType(${dst}.getReg()) == MRI.getType(${src}.getReg()); }]),
+ (apply (GIReplaceReg $dst, $src))
+>;
+
+// Fold (anyext (freeze (trunc x))) -> (freeze x) if the source type is same as
+// the destination type.
+def anyext_freeze_trunc_fold: GICombineRule <
+ (defs root:$root),
+ (match (G_TRUNC $x, $src),
+ (G_FREEZE $y, $x),
+ (G_ANYEXT $dst, $y):$root,
+ [{ return MRI.getType(${dst}.getReg()) == MRI.getType(${src}.getReg()); }]),
+ (apply (G_FREEZE $dst, $src))
>;
// Fold (zext (trunc x)) -> x if the source type is same as the destination type
@@ -2084,7 +2096,7 @@ def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
binop_same_val, binop_left_to_zero,
binop_right_to_zero, p2i_to_i2p,
- i2p_to_p2i, anyext_trunc_fold,
+ i2p_to_p2i, anyext_trunc_fold, anyext_freeze_trunc_fold,
fneg_fneg_fold, right_identity_one,
add_sub_reg, buildvector_identity_fold,
trunc_buildvector_fold,
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-ext.mir
index 629238126380c..2b24a8920e0e0 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-ext.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-ext.mir
@@ -385,8 +385,8 @@ body: |
; CHECK: liveins: $h0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
- ; CHECK-NEXT: %2:_(s64) = nneg G_ZEXT [[COPY]](s16)
- ; CHECK-NEXT: $x0 = COPY %2(s64)
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = nneg G_ZEXT [[COPY]](s16)
+ ; CHECK-NEXT: $x0 = COPY [[ZEXT]](s64)
%0:_(s16) = COPY $h0
%1:_(s32) = G_ANYEXT %0(s16)
%2:_(s64) = nneg G_ZEXT %1(s32)
@@ -401,10 +401,27 @@ body: |
; CHECK: liveins: $h0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
- ; CHECK-NEXT: %2:_(s64) = nneg G_ZEXT [[COPY]](s16)
- ; CHECK-NEXT: $x0 = COPY %2(s64)
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = nneg G_ZEXT [[COPY]](s16)
+ ; CHECK-NEXT: $x0 = COPY [[ZEXT]](s64)
%0:_(s16) = COPY $h0
%1:_(s32) = nneg G_ZEXT %0(s16)
%2:_(s64) = G_ANYEXT %1(s32)
$x0 = COPY %2(s64)
...
+---
+name: test_combine_anyext_freeze_trunc
+body: |
+ bb.1:
+ liveins: $x0
+ ; CHECK-LABEL: name: test_combine_anyext_freeze_trunc
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY]]
+ ; CHECK-NEXT: $x1 = COPY [[FREEZE]](s64)
+ %0:_(s64) = COPY $x0
+ %1:_(s32) = G_TRUNC %0(s64)
+ %2:_(s32) = G_FREEZE %1(s32)
+ %3:_(s64) = G_ANYEXT %2(s32)
+ $x1 = COPY %3(s64)
+...
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is OK but DAGCombiner seems to not have this one
| %2:_(s32) = G_FREEZE %1(s32) | ||
| %3:_(s64) = G_ANYEXT %2(s32) | ||
| $x1 = COPY %3(s64) | ||
| ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add the negative test where the types mismatch? Also test multiple uses of the inner op
We already have a transform for (anyext (trunc x)) -> x, this adds an extended version for (anyext (freeze (trunc x))) -> (freeze x). As we treat freeze i8 and i16 as legal this can help reduce the number of extends in the code.