[llvm] decf385 - [RISCV] Teach targetShrinkDemandedConstant to handle OR and XOR.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 17 12:39:57 PDT 2022
Author: Craig Topper
Date: 2022-07-17T12:36:33-07:00
New Revision: decf385c270ed814ac00331410b34fdea4e0b2b1
URL: https://github.com/llvm/llvm-project/commit/decf385c270ed814ac00331410b34fdea4e0b2b1
DIFF: https://github.com/llvm/llvm-project/commit/decf385c270ed814ac00331410b34fdea4e0b2b1.diff
LOG: [RISCV] Teach targetShrinkDemandedConstant to handle OR and XOR.
We were only handling AND before, but SimplifyDemandedBits can
also call it for OR and XOR.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/legalize-fneg.ll
llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 658865703079..382dbb97c728 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -9357,7 +9357,8 @@ bool RISCVTargetLowering::targetShrinkDemandedConstant(
return false;
// Only handle AND for now.
- if (Op.getOpcode() != ISD::AND)
+ unsigned Opcode = Op.getOpcode();
+ if (Opcode != ISD::AND && Opcode != ISD::OR && Opcode != ISD::XOR)
return false;
ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
@@ -9376,12 +9377,13 @@ bool RISCVTargetLowering::targetShrinkDemandedConstant(
auto IsLegalMask = [ShrunkMask, ExpandedMask](const APInt &Mask) -> bool {
return ShrunkMask.isSubsetOf(Mask) && Mask.isSubsetOf(ExpandedMask);
};
- auto UseMask = [Mask, Op, VT, &TLO](const APInt &NewMask) -> bool {
+ auto UseMask = [Mask, Op, &TLO](const APInt &NewMask) -> bool {
if (NewMask == Mask)
return true;
SDLoc DL(Op);
- SDValue NewC = TLO.DAG.getConstant(NewMask, DL, VT);
- SDValue NewOp = TLO.DAG.getNode(ISD::AND, DL, VT, Op.getOperand(0), NewC);
+ SDValue NewC = TLO.DAG.getConstant(NewMask, DL, Op.getValueType());
+ SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), DL, Op.getValueType(),
+ Op.getOperand(0), NewC);
return TLO.CombineTo(Op, NewOp);
};
@@ -9390,18 +9392,21 @@ bool RISCVTargetLowering::targetShrinkDemandedConstant(
if (ShrunkMask.isSignedIntN(12))
return false;
- // Preserve (and X, 0xffff) when zext.h is supported.
- if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) {
- APInt NewMask = APInt(Mask.getBitWidth(), 0xffff);
- if (IsLegalMask(NewMask))
- return UseMask(NewMask);
- }
+ // And has a few special cases for zext.
+ if (Opcode == ISD::AND) {
+ // Preserve (and X, 0xffff) when zext.h is supported.
+ if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) {
+ APInt NewMask = APInt(Mask.getBitWidth(), 0xffff);
+ if (IsLegalMask(NewMask))
+ return UseMask(NewMask);
+ }
- // Try to preserve (and X, 0xffffffff), the (zext_inreg X, i32) pattern.
- if (VT == MVT::i64) {
- APInt NewMask = APInt(64, 0xffffffff);
- if (IsLegalMask(NewMask))
- return UseMask(NewMask);
+ // Try to preserve (and X, 0xffffffff), the (zext_inreg X, i32) pattern.
+ if (VT == MVT::i64) {
+ APInt NewMask = APInt(64, 0xffffffff);
+ if (IsLegalMask(NewMask))
+ return UseMask(NewMask);
+ }
}
// For the remaining optimizations, we need to be able to make a negative
@@ -9414,10 +9419,11 @@ bool RISCVTargetLowering::targetShrinkDemandedConstant(
// Try to make a 12 bit negative immediate. If that fails try to make a 32
// bit negative immediate unless the shrunk immediate already fits in 32 bits.
+ // If we can't create a simm12, we shouldn't change opaque constants.
APInt NewMask = ShrunkMask;
if (MinSignedBits <= 12)
NewMask.setBitsFrom(11);
- else if (MinSignedBits <= 32 && !ShrunkMask.isSignedIntN(32))
+ else if (!C->isOpaque() && MinSignedBits <= 32 && !ShrunkMask.isSignedIntN(32))
NewMask.setBitsFrom(31);
else
return false;
diff --git a/llvm/test/CodeGen/RISCV/legalize-fneg.ll b/llvm/test/CodeGen/RISCV/legalize-fneg.ll
index b35884f8f87c..9037a0021c5f 100644
--- a/llvm/test/CodeGen/RISCV/legalize-fneg.ll
+++ b/llvm/test/CodeGen/RISCV/legalize-fneg.ll
@@ -16,8 +16,7 @@ define void @test1(float* %a, float* %b) nounwind {
; RV64-LABEL: test1:
; RV64: # %bb.0: # %entry
; RV64-NEXT: lw a1, 0(a1)
-; RV64-NEXT: li a2, 1
-; RV64-NEXT: slli a2, a2, 31
+; RV64-NEXT: lui a2, 524288
; RV64-NEXT: xor a1, a1, a2
; RV64-NEXT: sw a1, 0(a0)
; RV64-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll b/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll
index 5bcadf4dce00..ca9f43dd7ad7 100644
--- a/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll
+++ b/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll
@@ -5,7 +5,6 @@
; legalization. There are 2 opportunities on the chain feeding the LHS of the
; shl. And one opportunity on the shift amount. We previously weren't managing
; the DAGCombiner worklist correctly and failed to get the RHS.
-
define i32 @foo(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: foo:
; CHECK: # %bb.0:
@@ -37,3 +36,65 @@ define i64 @mul_self_nsw_sign(i64 %x) {
%b = and i64 %a, 9223372036854775800
ret i64 %b
}
+
+; Make sure we sign extend the constant after type legalization to allow the
+; use of ori.
+define void @ori(ptr nocapture noundef %0) {
+; CHECK-LABEL: ori:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lw a1, 0(a0)
+; CHECK-NEXT: ori a1, a1, -2
+; CHECK-NEXT: sw a1, 0(a0)
+; CHECK-NEXT: ret
+ %2 = load i32, ptr %0, align 4
+ %3 = or i32 %2, -2
+ store i32 %3, ptr %0, align 4
+ ret void
+}
+
+; Make sure we sign extend the constant after type legalization to allow the
+; use of xori.
+define void @xori(ptr nocapture noundef %0) {
+; CHECK-LABEL: xori:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lw a1, 0(a0)
+; CHECK-NEXT: xori a1, a1, -5
+; CHECK-NEXT: sw a1, 0(a0)
+; CHECK-NEXT: ret
+ %2 = load i32, ptr %0, align 4
+ %3 = xor i32 %2, -5
+ store i32 %3, ptr %0, align 4
+ ret void
+}
+
+; Make sure we sign extend the constant after type legalization to allow the
+; shorter constant materialization.
+define void @or_signbit(ptr nocapture noundef %0) {
+; CHECK-LABEL: or_signbit:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lw a1, 0(a0)
+; CHECK-NEXT: lui a2, 524288
+; CHECK-NEXT: or a1, a1, a2
+; CHECK-NEXT: sw a1, 0(a0)
+; CHECK-NEXT: ret
+ %2 = load i32, ptr %0, align 4
+ %3 = or i32 %2, -2147483648
+ store i32 %3, ptr %0, align 4
+ ret void
+}
+
+; Make sure we sign extend the constant after type legalization to allow the
+; shorter constant materialization.
+define void @xor_signbit(ptr nocapture noundef %0) {
+; CHECK-LABEL: xor_signbit:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lw a1, 0(a0)
+; CHECK-NEXT: lui a2, 524288
+; CHECK-NEXT: xor a1, a1, a2
+; CHECK-NEXT: sw a1, 0(a0)
+; CHECK-NEXT: ret
+ %2 = load i32, ptr %0, align 4
+ %3 = xor i32 %2, -2147483648
+ store i32 %3, ptr %0, align 4
+ ret void
+}
More information about the llvm-commits
mailing list