-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[GISel] Convert zext nneg to sext if it is cheaper #93842
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
Conversation
@llvm/pr-subscribers-llvm-globalisel Author: Yingwei Zheng (dtcxzyw) ChangesThe logic is copied from SelectionDAGBuilder: llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Lines 3829 to 3836 in 32546bd
Full diff: https://github.com/llvm/llvm-project/pull/93842.diff 3 Files Affected:
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 5289b993476db..d5138c68218c1 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1569,6 +1569,17 @@ bool IRTranslator::translateCast(unsigned Opcode, const User &U,
Register Op = getOrCreateVReg(*U.getOperand(0));
Register Res = getOrCreateVReg(U);
+
+ // Convert zext nneg to sext if it is preferred form for the target.
+ if (Opcode == TargetOpcode::G_ZEXT && (Flags & MachineInstr::NonNeg)) {
+ EVT SrcVT = TLI->getValueType(*DL, U.getOperand(0)->getType());
+ EVT DstVT = TLI->getValueType(*DL, U.getType());
+ if (TLI->isSExtCheaperThanZExt(SrcVT, DstVT)) {
+ Opcode = TargetOpcode::G_SEXT;
+ Flags = 0;
+ }
+ }
+
MIRBuilder.buildInstr(Opcode, {Res}, {Op}, Flags);
return true;
}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
index d4acca17930d5..fd80afce6510e 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip-rv64.ll
@@ -101,3 +101,13 @@ entry:
%0 = urem i64 %a, %b
ret i64 %0
}
+
+define i64 @zext_nneg_i32_i64(i32 %a) {
+; RV64IM-LABEL: zext_nneg_i32_i64:
+; RV64IM: # %bb.0: # %entry
+; RV64IM-NEXT: sext.w a0, a0
+; RV64IM-NEXT: ret
+entry:
+ %b = zext nneg i32 %a to i64
+ ret i64 %b
+}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/zext-nneg-rv64.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/zext-nneg-rv64.ll
new file mode 100644
index 0000000000000..2e37da0c03a51
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/zext-nneg-rv64.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I %s
+
+define i64 @zext_nneg_i32_i64(i32 %a) {
+ ; RV64I-LABEL: name: zext_nneg_i32_i64
+ ; RV64I: bb.1.entry:
+ ; RV64I-NEXT: liveins: $x10
+ ; RV64I-NEXT: {{ $}}
+ ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; RV64I-NEXT: [[SEXT:%[0-9]+]]:_(s64) = G_SEXT [[TRUNC]](s32)
+ ; RV64I-NEXT: $x10 = COPY [[SEXT]](s64)
+ ; RV64I-NEXT: PseudoRET implicit $x10
+entry:
+ %b = zext nneg i32 %a to i64
+ ret i64 %b
+}
|
Why is the DAG doing this transform in the builder and not in the combiner?
|
|
I really do not like these optimizations getting snuck into the DAG builder / IRTranslator. They should do their best to preserve the original IR |
Alright, I will post an alternative patch as @tschuett suggested. |
The pattern goes in Combine.td. The C++ goes into CombinerHelper. Ping me. |
Closing in favor of #93856. |
The logic is copied from SelectionDAGBuilder:
llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Lines 3829 to 3836 in 32546bd