-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Promote 32bit pseudo instr that infer extsw removal to 64bit in PPCMIPeephole #85451
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-backend-powerpc Author: zhijian lin (diggerlin) ChangesPatch is 49.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85451.diff 12 Files Affected:
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 5f5eb31a5a85fa..0e9bdaf37d079d 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -5219,6 +5219,141 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
// We limit the max depth to track incoming values of PHIs or binary ops
// (e.g. AND) to avoid excessive cost.
const unsigned MAX_BINOP_DEPTH = 1;
+
+void PPCInstrInfo::replaceInstrAfterElimExt32To64(const Register &Reg,
+ MachineRegisterInfo *MRI,
+ unsigned BinOpDepth,
+ LiveVariables *LV) const {
+ if (MRI->getRegClass(Reg) == &PPC::G8RCRegClass)
+ return;
+
+ MachineInstr *MI = MRI->getVRegDef(Reg);
+ if (!MI)
+ return;
+
+ unsigned Opcode = MI->getOpcode();
+ bool IsRelplaceIntr = false;
+ switch (Opcode) {
+ case PPC::OR:
+ case PPC::OR8:
+ case PPC::PHI:
+ case PPC::ISEL:
+ if (BinOpDepth < MAX_BINOP_DEPTH) {
+ if (Opcode == PPC::OR)
+ IsRelplaceIntr = true;
+ unsigned OperandEnd = 3, OperandStride = 1;
+ if (MI->getOpcode() == PPC::PHI) {
+ OperandEnd = MI->getNumOperands();
+ OperandStride = 2;
+ }
+
+ for (unsigned I = 1; I != OperandEnd; I += OperandStride) {
+ assert(MI->getOperand(I).isReg() && "Operand must be register");
+ Register SrcReg = MI->getOperand(I).getReg();
+ replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth + 1, LV);
+ }
+ }
+ break;
+ // case PPC::COPY:
+ case PPC::ORI:
+ case PPC::XORI:
+ case PPC::ORI8:
+ case PPC::XORI8:
+ case PPC::ORIS:
+ case PPC::XORIS:
+ case PPC::ORIS8:
+ case PPC::XORIS8: {
+ if (Opcode == PPC::ORI || Opcode == PPC::XORI || Opcode == PPC::ORIS ||
+ Opcode == PPC::ORIS || Opcode == PPC::XORIS)
+ IsRelplaceIntr = true;
+ Register SrcReg = MI->getOperand(1).getReg();
+ replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth, LV);
+ break;
+ }
+ case PPC::AND:
+ case PPC::AND8: {
+ if (BinOpDepth < MAX_BINOP_DEPTH) {
+ if (Opcode == PPC::AND)
+ IsRelplaceIntr = true;
+ Register SrcReg1 = MI->getOperand(1).getReg();
+ replaceInstrAfterElimExt32To64(SrcReg1, MRI, BinOpDepth, LV);
+ Register SrcReg2 = MI->getOperand(2).getReg();
+ replaceInstrAfterElimExt32To64(SrcReg2, MRI, BinOpDepth, LV);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ const PPCInstrInfo *TII =
+ MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
+ if ((TII->isSExt32To64(Opcode) && !TII->isZExt32To64(Opcode)) ||
+ IsRelplaceIntr) {
+ DebugLoc DL = MI->getDebugLoc();
+ auto MBB = MI->getParent();
+
+ // If the oprand of the instruction is Register which isPPC::GRCRegClass, we
+ // need to promot the Oprande to PPC::G8RCRegClass.
+ DenseMap<unsigned, Register> PromoteRegs;
+ for (unsigned i = 1; i < MI->getNumOperands(); i++) {
+ MachineOperand &Oprand = MI->getOperand(i);
+ if (Oprand.isReg()) {
+ Register OprandReg = Oprand.getReg();
+ if (!OprandReg.isVirtual())
+ continue;
+ if (MRI->getRegClass(OprandReg) == &PPC::GPRCRegClass) {
+ Register TmpReg = MRI->createVirtualRegister(&PPC::G8RCRegClass);
+ Register DstTmpReg = MRI->createVirtualRegister(&PPC::G8RCRegClass);
+
+ BuildMI(*MBB, MI, DL, TII->get(PPC::IMPLICIT_DEF), TmpReg);
+ BuildMI(*MBB, MI, DL, TII->get(PPC::INSERT_SUBREG), DstTmpReg)
+ .addReg(TmpReg)
+ .addReg(OprandReg)
+ .addImm(PPC::sub_32);
+ PromoteRegs[i] = DstTmpReg;
+ } else {
+ PromoteRegs[i] = OprandReg;
+ }
+ }
+ }
+
+ Register NewReg = MRI->createVirtualRegister(&PPC::G8RCRegClass);
+ Register SrcReg = MI->getOperand(0).getReg();
+
+ // Most of the opcode of 64-bit instruction equal to the opcode of 32-bit
+ // version of same instruction plus one. But there are some exception:
+ // PPC::ANDC_rec, PPC::ANDI_rec, PPC::ANDIS_rec.
+ unsigned NewOpcode = Opcode + 1;
+
+ if (Opcode == PPC::ANDC_rec)
+ NewOpcode = PPC::ANDC8_rec;
+ if (Opcode == PPC::ANDI_rec)
+ NewOpcode = PPC::ANDI8_rec;
+ if (Opcode == PPC::ANDIS_rec)
+ NewOpcode = PPC::ANDIS8_rec;
+
+ BuildMI(*MBB, MI, DL, TII->get(NewOpcode), NewReg);
+ MachineBasicBlock::instr_iterator Iter(MI);
+ --Iter;
+ for (unsigned i = 1; i < MI->getNumOperands(); i++)
+ if (PromoteRegs.find(i) != PromoteRegs.end())
+ MachineInstrBuilder(*Iter->getMF(), Iter)
+ .addReg(PromoteRegs[i], RegState::Kill);
+ else
+ Iter->addOperand(MI->getOperand(i));
+
+ for (auto Iter = PromoteRegs.begin(); Iter != PromoteRegs.end(); Iter++)
+ LV->recomputeForSingleDefVirtReg(Iter->second);
+ MI->eraseFromParent();
+ BuildMI(*MBB, ++Iter, DL, TII->get(PPC::COPY), SrcReg)
+ .addReg(NewReg, RegState::Kill, PPC::sub_32);
+ LV->recomputeForSingleDefVirtReg(NewReg);
+ return;
+ }
+ return;
+}
+
// The isSignOrZeroExtended function is recursive. The parameter BinOpDepth
// does not count all of the recursions. The parameter BinOpDepth is incremented
// only when isSignOrZeroExtended calls itself more than once. This is done to
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h
index 045932dc0d3ba1..f6e79707913c7b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h
@@ -17,6 +17,7 @@
#include "PPC.h"
#include "PPCRegisterInfo.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
@@ -610,6 +611,10 @@ class PPCInstrInfo : public PPCGenInstrInfo {
const MachineRegisterInfo *MRI) const {
return isSignOrZeroExtended(Reg, 0, MRI).second;
}
+ void replaceInstrAfterElimExt32To64(const Register &Reg,
+ MachineRegisterInfo *MRI,
+ unsigned BinOpDepth,
+ LiveVariables *LV) const;
bool convertToImmediateForm(MachineInstr &MI,
SmallSet<Register, 4> &RegsToUpdate,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 82da1a3c305983..7c94add841402a 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -2408,7 +2408,7 @@ defm SRW : XForm_6r<31, 536, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
[(set i32:$RA, (PPCsrl i32:$RST, i32:$RB))]>, ZExt32To64;
defm SRAW : XForm_6rc<31, 792, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
"sraw", "$RA, $RST, $RB", IIC_IntShift,
- [(set i32:$RA, (PPCsra i32:$RST, i32:$RB))]>, SExt32To64;
+ [(set i32:$RA, (PPCsra i32:$RST, i32:$RB))]>;
}
def : InstAlias<"mr $rA, $rB", (OR gprc:$rA, gprc:$rB, gprc:$rB)>;
@@ -2423,8 +2423,7 @@ let PPC970_Unit = 1 in { // FXU Operations.
let hasSideEffects = 0 in {
defm SRAWI : XForm_10rc<31, 824, (outs gprc:$RA), (ins gprc:$RST, u5imm:$RB),
"srawi", "$RA, $RST, $RB", IIC_IntShift,
- [(set i32:$RA, (sra i32:$RST, (i32 imm:$RB)))]>,
- SExt32To64;
+ [(set i32:$RA, (sra i32:$RST, (i32 imm:$RB)))]>;
defm CNTLZW : XForm_11r<31, 26, (outs gprc:$RA), (ins gprc:$RST),
"cntlzw", "$RA, $RST", IIC_IntGeneral,
[(set i32:$RA, (ctlz i32:$RST))]>, ZExt32To64;
diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
index 494e4b52a5b5eb..76b9c19db2b3eb 100644
--- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -1037,6 +1037,7 @@ bool PPCMIPeephole::simplifyCode() {
TII->isSignExtended(NarrowReg, MRI)) {
// We can eliminate EXTSW if the input is known to be already
// sign-extended.
+ TII->replaceInstrAfterElimExt32To64(NarrowReg, MRI, 0, LV);
LLVM_DEBUG(dbgs() << "Removing redundant sign-extension\n");
Register TmpReg =
MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
diff --git a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir
index dfbf412a939212..bcc1d29a3f6ea3 100644
--- a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir
+++ b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs-out-of-range.mir
@@ -604,7 +604,7 @@ body: |
%2 = LI 48
%5 = COPY %0.sub_32
%8 = SRW killed %5, killed %2
- ; CHECK: LI 0
+ ; CHECK: LI8 0
; CHECK-LATE: li 3, 0
$x3 = EXTSW_32_64 %8
BLR8 implicit $lr8, implicit $rm, implicit $x3
diff --git a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
index 761316ed7726d7..f095ffa85f02db 100644
--- a/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
+++ b/llvm/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
@@ -1348,7 +1348,7 @@ body: |
%1 = LI 77
%2 = ADDI killed %1, 44
%3 = EXTSW_32_64 killed %2
- ; CHECK: LI 121
+ ; CHECK: LI8 121
; CHECK-LATE: li 3, 121
$x3 = COPY %3
BLR8 implicit $lr8, implicit $rm, implicit $x3
@@ -3573,7 +3573,7 @@ body: |
%0 = LI 777
%1 = ORI %0, 88
- ; CHECK: LI 857
+ ; CHECK: LI8 857
; CHECK-LATE: li 3, 857
$x3 = EXTSW_32_64 %1
BLR8 implicit $lr8, implicit $rm, implicit $x3
@@ -4145,7 +4145,7 @@ body: |
%3 = IMPLICIT_DEF
%2 = LI 17
%4 = RLWINM killed %2, 4, 20, 27
- ; CHECK: LI 272
+ ; CHECK: LI8 272
; CHECK-LATE: li 3, 272
$x3 = EXTSW_32_64 %4
BLR8 implicit $lr8, implicit $rm, implicit $x3
@@ -6456,7 +6456,7 @@ body: |
%0 = LI 871
%1 = XORI %0, 17
- ; CHECK: LI 886
+ ; CHECK: LI8 886
; CHECK-LATE: li 3, 886
$x3 = EXTSW_32_64 %1
BLR8 implicit $lr8, implicit $rm, implicit $x3
diff --git a/llvm/test/CodeGen/PowerPC/peephole-replaceInstr-after-eliminate-extsw.mir b/llvm/test/CodeGen/PowerPC/peephole-replaceInstr-after-eliminate-extsw.mir
new file mode 100644
index 00000000000000..1b54ba7a38b816
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/peephole-replaceInstr-after-eliminate-extsw.mir
@@ -0,0 +1,698 @@
+# RUN: llc -run-pass=ppc-mi-peepholes -mtriple powerpc64-ibm-aix-xcoff %s -o - \
+# RUN: -verify-machineinstrs | FileCheck %s
+
+--- |
+ ; ModuleID = '71030_tmp_reduce-O2.ll'
+ source_filename = "71030_tmp_reduce.c"
+ target datalayout = "E-m:a-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512"
+ target triple = "powerpc64-ibm-aix-xcoff"
+
+ @globalShortValue = local_unnamed_addr global i16 1, align 2
+ @globalCharValue = local_unnamed_addr global i8 0, align 1
+ @largeNumber = local_unnamed_addr global i64 -3664682556119382352, align 8
+ @someIntValue = local_unnamed_addr global i32 378441747, align 4
+ @unitIncrement = local_unnamed_addr global i32 1, align 4
+ @computedResultUll = local_unnamed_addr global i64 0, align 8
+ @computedResultShort = local_unnamed_addr global i16 0, align 2
+ @computedResultUChar = local_unnamed_addr global i8 0, align 1
+ @computedResultBool = local_unnamed_addr global i8 0, align 1
+ @computedResultChar = local_unnamed_addr global i8 0, align 1
+ @shortArray = local_unnamed_addr global [8 x i16] zeroinitializer, align 2
+ @charArray = local_unnamed_addr global [8 x [8 x [8 x i8]]] zeroinitializer, align 1
+ @longArray = local_unnamed_addr global [8 x [8 x i64]] zeroinitializer, align 8
+ @resultArray = local_unnamed_addr global [8 x [8 x i16]] zeroinitializer, align 2
+ @ullArray = local_unnamed_addr global [8 x i64] zeroinitializer, align 8
+ @intArray = local_unnamed_addr global [8 x [8 x [8 x i32]]] zeroinitializer, align 4
+ @_MergedGlobals = private constant <{ [29 x i8], [46 x i8] }> <{ [29 x i8] c"Computed Result (ULL): %llx\0A\00", [46 x i8] c"Computed convert largeNumber&&&& (ULL): %llx\0A\00" }>, align 1
+
+ @.str.1 = private alias [29 x i8], ptr @_MergedGlobals
+ @.str = private alias [46 x i8], getelementptr inbounds (<{ [29 x i8], [46 x i8] }>, ptr @_MergedGlobals, i32 0, i32 1)
+
+ ; Function Attrs: nofree nounwind
+ define noundef signext i32 @main() local_unnamed_addr #0 {
+ entry:
+ store i16 -1, ptr getelementptr inbounds ([8 x i16], ptr @shortArray, i64 0, i64 3), align 2, !tbaa !3
+ %0 = load i64, ptr @largeNumber, align 8, !tbaa !7
+ %conv = trunc i64 %0 to i32
+ %sext = shl i32 %conv, 16
+ %conv1 = ashr exact i32 %sext, 16
+ %sub = add nsw i32 %conv1, -1705
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) getelementptr inbounds (<{ [29 x i8], [46 x i8] }>, ptr @_MergedGlobals, i32 0, i32 1), i32 noundef signext %sub)
+ %1 = load i16, ptr @globalShortValue, align 2, !tbaa !3
+ %2 = load i32, ptr @someIntValue, align 4, !tbaa !9
+ %3 = trunc i32 %2 to i8
+ %conv20 = add i8 %3, -19
+ %4 = load i32, ptr @unitIncrement, align 4
+ %5 = load i8, ptr @globalCharValue, align 1
+ %conv45 = sext i8 %5 to i32
+ %computedResultShort.promoted = load i16, ptr @computedResultShort, align 2, !tbaa !3
+ %resultArray.promoted = load i16, ptr @resultArray, align 2, !tbaa !3
+ %computedResultChar.promoted149 = load i8, ptr @computedResultChar, align 1, !tbaa !11
+ %6 = sext i8 %conv20 to i64
+ %7 = load i16, ptr getelementptr inbounds ([8 x i16], ptr @shortArray, i64 0, i64 3), align 2, !tbaa !3
+ %8 = load i16, ptr getelementptr inbounds ([8 x i16], ptr @shortArray, i64 0, i64 2), align 2
+ %conv46 = sext i16 %8 to i32
+ %cond54 = tail call i32 @llvm.smin.i32(i32 %conv45, i32 %conv46)
+ %tobool = icmp ne i32 %cond54, 0
+ %conv55 = zext i1 %tobool to i8
+ %9 = load i64, ptr getelementptr inbounds ([8 x i64], ptr @ullArray, i64 0, i64 3), align 8
+ %tobool72 = icmp ne i64 %9, 0
+ %frombool = zext i1 %tobool72 to i8
+ %smax = tail call i64 @llvm.smax.i64(i64 %6, i64 4)
+ %10 = add nuw nsw i64 %smax, 3
+ %11 = sub i64 %10, %6
+ %12 = lshr i64 %11, 2
+ %13 = add nuw nsw i64 %12, 1
+ %n.vec = and i64 %13, 9223372036854775806
+ %14 = shl i64 %n.vec, 2
+ %ind.end = add i64 %14, %6
+ %15 = shl i64 %6, 2
+ %16 = shl i64 %6, 3
+ %17 = add nsw i64 %16, -64
+ %scevgep30 = getelementptr i8, ptr @longArray, i64 %17
+ %18 = add nsw i64 %15, 64
+ %scevgep31 = getelementptr i8, ptr @intArray, i64 %18
+ %19 = lshr i64 %13, 1
+ %20 = shl nuw nsw i64 %19, 1
+ %21 = add nsw i64 %20, -2
+ %22 = lshr i64 %21, 1
+ %23 = add nuw i64 %22, 1
+ br label %for.body16
+
+ for.cond.cleanup15: ; preds = %for.cond.cleanup25
+ %24 = tail call i16 @llvm.smin.i16(i16 %1, i16 %7)
+ %conv11.le = sext i16 %24 to i64
+ store i64 %conv11.le, ptr @computedResultUll, align 8, !tbaa !7
+ %call97 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @_MergedGlobals, i64 noundef %conv11.le)
+ ret i32 0
+
+ for.body16: ; preds = %for.cond.cleanup25, %entry
+ %lsr.iv29 = phi i32 [ %lsr.iv.next, %for.cond.cleanup25 ], [ 8, %entry ]
+ %conv36.lcssa132140 = phi i16 [ %computedResultShort.promoted, %entry ], [ %conv36.lcssa131, %for.cond.cleanup25 ]
+ %and.lcssa135139 = phi i16 [ %resultArray.promoted, %entry ], [ %and.lcssa134, %for.cond.cleanup25 ]
+ %conv81118.lcssa.lcssa137138 = phi i8 [ %computedResultChar.promoted149, %entry ], [ %conv81118.lcssa.lcssa136, %for.cond.cleanup25 ]
+ %25 = icmp slt i8 %conv20, 8
+ br i1 %25, label %for.body31.lr.ph, label %for.cond.cleanup25
+
+ for.body31.lr.ph: ; preds = %for.body16
+ %26 = icmp ult i64 %11, 4
+ store i8 %conv55, ptr @computedResultUChar, align 1, !tbaa !11
+ br i1 %26, label %for.body31.preheader, label %vector.body.preheader
+
+ vector.body.preheader: ; preds = %for.body31.lr.ph
+ call void @llvm.set.loop.iterations.i64(i64 %23)
+ br label %vector.body
+
+ vector.body: ; preds = %vector.body.preheader, %vector.body
+ %vec.phi = phi i16 [ %44, %vector.body ], [ %conv36.lcssa132140, %vector.body.preheader ]
+ %vec.phi159 = phi i16 [ %45, %vector.body ], [ 0, %vector.body.preheader ]
+ %vec.phi160 = phi i16 [ %46, %vector.body ], [ %and.lcssa135139, %vector.body.preheader ]
+ %vec.phi161 = phi i16 [ %47, %vector.body ], [ -1, %vector.body.preheader ]
+ %vec.phi162 = phi i8 [ %48, %vector.body ], [ %conv81118.lcssa.lcssa137138, %vector.body.preheader ]
+ %vec.phi163 = phi i8 [ %49, %vector.body ], [ 0, %vector.body.preheader ]
+ %27 = phi ptr [ %scevgep30, %vector.body.preheader ], [ %31, %vector.body ]
+ %28 = phi ptr [ %scevgep31, %vector.body.preheader ], [ %29, %vector.body ]
+ %29 = getelementptr i8, ptr %28, i64 32
+ %30 = getelementptr i8, ptr %29, i64 16
+ %31 = getelementptr i8, ptr %27, i64 64
+ %32 = getelementptr i8, ptr %31, i64 32
+ %33 = trunc i32 %4 to i16
+ %34 = load i64, ptr %31, align 8, !tbaa !7
+ %35 = load i64, ptr %32, align 8, !tbaa !7
+ %36 = trunc i64 %34 to i16
+ %37 = trunc i64 %35 to i16
+ %38 = load i32, ptr %29, align 4, !tbaa !9
+ %39 = load i32, ptr %30, align 4, !tbaa !9
+ %40 = trunc i32 %38 to i8
+ %41 = trunc i32 %39 to i8
+ %42 = mul i8 %40, -6
+ %43 = mul i8 %41, -6
+ %44 = sub i16 %vec.phi, %33
+ %45 = sub i16 %vec.phi159, %33
+ %46 = and i16 %vec.phi160, %36
+ %47 = and i16 %vec.phi161, %37
+ %48 = add i8 %42, %vec.phi162
+ %49 = add i8 %43, %vec.phi163
+ %50 = call i1 @llvm.loop.decrement.i64(i64 1)
+ br i1 %50, label %vector.body, label %middle.block, !llvm.loop !12
+
+ middle.block: ; preds = %vector.body
+ %51 = icmp eq i64 %13, %n.vec
+ %bin.rdx = add i16 %45, %44
+ %bin.rdx164 = and i16 %47, %46
+ %bin.rdx165 = add i8 %49, %48
+ br i1 %51, label %for.cond21.for.cond.cleanup25_crit_edge, label %for.body31.preheader
+
+ for.body31.preheader: ; preds = %middle.block, %for.body31.lr.ph
+ %indvars.iv.ph = phi i64 [ %6, %for.body31.lr.ph ], [ %ind.end, %middle.block ]
+ %conv36121128.ph = phi i16 [ %conv36.lcssa132140, %for.body31.lr.ph ], [ %bin.rdx, %middle.block ]
+ %and122127.ph = phi i16 [ %and.lcssa135139, %for.body31.lr.ph ], [ %bin.rdx164, %middle.block ]
+ %conv81118.lcssa124126.ph = phi i8 [ %conv81118.lcssa.lcssa137138, %for.body31.lr.ph ], [ %bin.rdx165, %middle.block ]
+ %52 = shl i64 %indvars.iv.ph, 2
+ %53 = shl i64 %indvars.iv.ph, 3
+ %scevgep = getelementptr i8, ptr getelementptr ([8 x [8 x i64]], ptr @longArray, i64 -1, i64 7, i64 4), i64 %53
+ %scevgep32 = getelementptr i8, ptr getelementptr inbounds ([8 x [8 x [8 x i32]]], ptr @intArray, i64 0, i64 0, i64 2, i64 4), i64 %52
+ %smax33 = call i64 @llvm.smax.i64(i64 %indvars.iv.ph, i64 4)
+ %54 = add i64 %smax33, 3
+ %55 = sub i64 %54, %indvars.iv.ph
+ %56 = lshr i64 %55, 2
+ %57 = add nuw nsw i64 %56, 1
+ call void @llvm.set.loop.iterations.i64(i64 %57)
+ br label %for.body31
+
+ for.cond21.for.cond.cleanup25_crit_edge: ; preds = %for.body31, %middle.block
+ %conv36.lcssa = phi i16 [ %bin.rdx, %middle.block ], [ %conv36, %for.body31 ]
+ %and.lcssa = phi i16 [ %bin.rdx164, %middle.block ], [ %and, %for.body31 ]
+ %.lcssa = phi i8 [ %bin.rdx165, %middle.block ], [ %67, %for.body31 ]
+ %58 = trunc i16 %1 to i8
+ store i16 %conv36.lcssa, ptr @computedResultShort, align 2, !tbaa !3
+ store i8 %58, ptr getelementptr inbounds ([8 x [8 x [8 x i8]]], ptr @charArray, i64 0, i64 2, i64 0, i64 3), align 1, !tbaa !11
+ store i16 %and.lcssa, ptr @resultArray, align 2, !tbaa !3
+ store i8 %frombool, ptr @computedResultBool, align 1, !tbaa !16
+ store i8 %.lcssa, ptr @computedResultChar, align...
[truncated]
|
54fad33
to
680bcf6
Compare
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.
Initial review, and I plan to review again.
return; | ||
|
||
unsigned Opcode = MI->getOpcode(); | ||
bool IsRelplaceIntr = false; |
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.
bool IsRelplaceIntr = false; | |
bool IsReplaceInstr = false; |
Do we mean this?
DenseMap<unsigned, Register> PromoteRegs; | ||
DenseMap<unsigned, Register> ReCalRegs; | ||
for (unsigned i = 1; i < MI->getNumOperands(); i++) { | ||
MachineOperand &Oprand = MI->getOperand(i); |
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.
MachineOperand &Oprand = MI->getOperand(i); | |
MachineOperand &Operand = MI->getOperand(i); |
I think we can use Operand
instead of Oprand
here and below.
@@ -2408,7 +2408,7 @@ defm SRW : XForm_6r<31, 536, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB), | |||
[(set i32:$RA, (PPCsrl i32:$RST, i32:$RB))]>, ZExt32To64; | |||
defm SRAW : XForm_6rc<31, 792, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB), | |||
"sraw", "$RA, $RST, $RB", IIC_IntShift, | |||
[(set i32:$RA, (PPCsra i32:$RST, i32:$RB))]>, SExt32To64; | |||
[(set i32:$RA, (PPCsra i32:$RST, i32:$RB))]>; |
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.
May I ask why SExt32To64
is removed from just SRAW
and SRAWI
?
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.
there is no 64bit pseudo-code instruction for SRAW and SRAWI , that there is no SRAW8
and SRAWI8
pseudo-code instruction
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.
Group code review comment:
Is the removal of the SExt32To64
flag truly correct? We're not sure if this instruction really makes sense in 32-bit mode. The sign extend flag should depend on the behaviour of the instruction itself (if the instruction is meant to sign extend, then presumably the flag should still be present).
It would be good investigate this.
I think it would be worthwhile investigating whether this can be accomplished significantly more easily and succinctly by implementing another |
I added a
|
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.
It would good to update the title and description, rather than "fix a bug".
@@ -0,0 +1,702 @@ | |||
# RUN: llc -run-pass=ppc-mi-peepholes -mtriple powerpc64-ibm-aix-xcoff %s -o - \ |
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.
Could we commit this test case first before this patch? Then, it will be easier to see how this patch changes the test case.
@@ -2408,7 +2408,7 @@ defm SRW : XForm_6r<31, 536, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB), | |||
[(set i32:$RA, (PPCsrl i32:$RST, i32:$RB))]>, ZExt32To64; | |||
defm SRAW : XForm_6rc<31, 792, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB), | |||
"sraw", "$RA, $RST, $RB", IIC_IntShift, | |||
[(set i32:$RA, (PPCsra i32:$RST, i32:$RB))]>, SExt32To64; | |||
[(set i32:$RA, (PPCsra i32:$RST, i32:$RB))]>; |
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.
Group code review comment:
Is the removal of the SExt32To64
flag truly correct? We're not sure if this instruction really makes sense in 32-bit mode. The sign extend flag should depend on the behaviour of the instruction itself (if the instruction is meant to sign extend, then presumably the flag should still be present).
It would be good investigate this.
llvm/lib/Target/PowerPC/PPC.td
Outdated
let RowFields = ["Inst"]; | ||
// Instructions with the same Interpretation64Bit value form a column. | ||
let ColFields = ["Interpretation64Bit"]; | ||
// The key column are not the Interpretation64Bit-form instructions. |
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.
// The key column are not the Interpretation64Bit-form instructions. | |
// The key column are not the Interpretation64Bit-form instructions. |
extsw
instruction in PPCMIPeepholes optimization
extsw
instruction in PPCMIPeepholes optimization extsw
instruction in PPCMIPeepholes optimization
dc3948a
to
217a293
Compare
Add pre-commit MIR test for PR "[Promote Pseudo Opcode from 32-bit to 64-bit after eliminating the extsw instruction in PPCMIPeepholes optimization](#85451)" which fixes bug reported in the issue "[Inconsistent Output at -O1 and -O2 Optimization Levels on PowerPC64 Due to Complex Type Casting and Nested Loop Structure](#71030)".
…w instruction in PPCMIPeepholes optimization
217a293
to
79aaf13
Compare
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.
Some group code review comments.
@@ -1051,6 +1051,7 @@ bool PPCMIPeephole::simplifyCode() { | |||
TII->isSignExtended(NarrowReg, MRI)) { | |||
// We can eliminate EXTSW if the input is known to be already | |||
// sign-extended. | |||
TII->replaceInstrAfterElimExt32To64(NarrowReg, MRI, 0, LV); |
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.
A couple comments regarding this line:
- This call does not make sense with the comment on 1052-1053. It would be better to put this call above the comment.
- The naming of the function seems unclear. We can consider renaming the function from
replaceInstrAfter
topromoteInstrBefore
, or something similar. - Add new documentation for the function.
@@ -5234,6 +5234,218 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const { | |||
// We limit the max depth to track incoming values of PHIs or binary ops | |||
// (e.g. AND) to avoid excessive cost. | |||
const unsigned MAX_BINOP_DEPTH = 1; | |||
|
|||
void PPCInstrInfo::replaceInstrAfterElimExt32To64(const Register &Reg, |
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.
Please add a comment to describe this function.
OperandStride = 2; | ||
} | ||
|
||
for (unsigned I = 1; I != OperandEnd; I += OperandStride) { |
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.
It would be better to use <
instead of !=
here.
return; | ||
|
||
unsigned Opcode = MI->getOpcode(); | ||
bool IsReplaceInstr = false; |
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 we update the name of this variable? Something like IsPromotedInstr
?
Co-authored-by: Amy Kwan <[email protected]>
…omoteInstr32To64ForElimEXTSW
default: | ||
break; |
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.
Not needed since it doesn't do anything.
// extended within the function PPCInstrInfo::isSignOrZeroExtended. | ||
// Additionally, the `promoteInstr32To64ForElimEXTSW` function is recursive. | ||
// BinOpDepth does not count all of the recursions. The parameter BinOpDepth is | ||
// incremented only when `promoteInstr32To64ForElimEXTSW` calls itself more |
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.
From what I can see below, BinOpDepth
is only ever used for AND8 and PHI instr processing and only ever incremented when processing a PHI. Maybe I am missing something or this documentation need to be updated to be more clear. Do we not care to track how many times it calls itself for other instructions?
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.
Good Catch for AND8 . the logic of BinOpDepth is come from function isSignOrZeroExtended(), when the instructions(e.g., AND, PHI, OR) which has two or more source registers , the instructions which defines these source registers also need to be promoted and so on , without increase the BinOpDepth , it maybe have 2 * 2 * 2 * 2.... recursions of promoteInstr32To64ForElimEXTSW.
[[fallthrough]]; | ||
case PPC::XORIS: | ||
CheckAndSetNewOpcode(PPC::XORIS8); | ||
[[fallthrough]]; |
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.
This big switch stmt makes things a bit confusing. See comment above about replacing the lambda func CheckAndSetNewOpcode
with a static helper function.
return; | ||
|
||
unsigned Opcode = MI->getOpcode(); | ||
bool IsNonSignedExtInstrNeedPromoted = false; |
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.
instead of having a flag here, maybe we can setup a static function instead to replace the lambda CheckAndSetNewOpcod
// switch stmt to check opcode and set to new if needed and return true or false
static bool SignedExtInstrPromotion(unsigned int &Opcode) {
switch (Opcode) {
default: return false;
case ....
return true;
}
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.
instead of using static helper function and I do not want a duplication code, I use a Macro definition to achieve it.
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.
IMHO the macro seem more confusing to me.
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.
OK, I change to another way
|
||
const PPCInstrInfo *TII = | ||
MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo(); | ||
if (TII->isSExt32To64(Opcode) || IsNonSignedExtInstrNeedPromoted) { |
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.
opt for early exit
if (! TII->isSExt32To64(Opcode) && ! IsNonSignedExtInstrNeedPromoted)
return;
DenseMap<unsigned, Register> PromoteRegs; | ||
for (unsigned i = 1; i < MI->getNumOperands(); i++) { | ||
MachineOperand &Operand = MI->getOperand(i); | ||
if (Operand.isReg()) { |
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.
early exit
if (Operand.isReg()) { | |
if (!Operand.isReg()) | |
continue; |
|
||
for (unsigned i = 1; i < Iter->getNumOperands(); i++) { | ||
MachineOperand &Operand = Iter->getOperand(i); | ||
if (Operand.isReg()) { |
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.
opt for early exit
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.
Please try to keep your title with 80 chars and do not use hypertext in your PR discription.
nit: "Summary" is also not needed in the description as that is implied.
case PPC::ISEL: | ||
case PPC::OR8: | ||
case PPC::PHI: | ||
if (BinOpDepth < MAX_BINOP_DEPTH) { |
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.
early exit
if (BinOpDepth < MAX_BINOP_DEPTH) { | |
if (BinOpDepth >= MAX_BINOP_DEPTH) | |
break; |
break; | ||
} | ||
case PPC::AND: | ||
case PPC::AND8: { |
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.
brace not needed here.
Register SrcReg1 = MI->getOperand(1).getReg(); | ||
promoteInstr32To64ForElimEXTSW(SrcReg1, MRI, BinOpDepth + 1, LV); | ||
Register SrcReg2 = MI->getOperand(2).getReg(); | ||
promoteInstr32To64ForElimEXTSW(SrcReg2, MRI, BinOpDepth + 1, LV); |
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.
tmp var SrcReg[12]
is not needed. Prefer to inline it into the call.
case PPC::ORIS8: | ||
case PPC::XORIS8: { | ||
Register SrcReg = MI->getOperand(1).getReg(); | ||
promoteInstr32To64ForElimEXTSW(SrcReg, MRI, BinOpDepth, LV); |
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.
no need for tmp var. Can inline into call.
return; | ||
|
||
unsigned Opcode = MI->getOpcode(); | ||
bool IsNonSignedExtInstrNeedPromoted = false; |
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.
This var is a bit of a mouth full and took me a few tries to understand what it means. Maybe a simpler var name: PromoteNonSignedExtInstr
?
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 it maybe better to change to HasNonSignedExtInstrPromoted
return; | ||
|
||
unsigned Opcode = MI->getOpcode(); | ||
bool IsNonSignedExtInstrNeedPromoted = false; |
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.
IMHO the macro seem more confusing to me.
const TargetRegisterClass *RC = MRI->getRegClass(Reg); | ||
|
||
if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass) | ||
return; |
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.
Is Reg
updated anywhere above? I don't see seem to see any updates so am a bit confused why this check is here vs at the top. Can we add a comment here as to why we are exiting earlier?
nit: remove empty line 5350
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.
we can not move the checking to top, because even the RegClass of the reg
is PPC::G8RCRegClass
or PPC::G8RC_and_G8RC_NOX0RegClass
, we still need to check whether we need to logic in the switch
statement
for example, COPY
from PPC::GPRCRegClass to PPC::G8RCRegClass, we still need to do promoteInstr32To64ForElimEXTSW
// Check if the Opcode is in the map. | ||
auto It = OpcodeMap.find(Opcode); | ||
if (It != OpcodeMap.end()) { | ||
// Set the new opcode to the mapped 64-bit version. | ||
NewOpcode = It->second; | ||
HasNonSignedExtInstrPromoted = true; | ||
} |
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.
Since this is not neeed until line 5346, why not move it down there and combine with code on line 5358. That way probably don't even need HasNonSignedExtInstrPromoted
.
std::unordered_map<unsigned, unsigned> OpcodeMap = { | ||
{PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8}, | ||
{PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8}, | ||
{PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8}, | ||
{PPC::AND, PPC::AND8}}; |
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 we document what this list is? As in why this list and how to determine what should be included?
{PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8}, | ||
{PPC::AND, PPC::AND8}}; | ||
|
||
// Check if the Opcode is in the map. |
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.
This comment just document exactly what it being coded below. Please explain what the intent is.
Maybe something to the extent of "Return 64bit equivalent opcodes for ....."
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 add the comment in above
- // Map the opcode of instructions (which are not sign- or zero-extended
- // themselves,but have operands that are destination registers of sign- or
- // zero-extended instructions) to their 64-bit equivalents.
I think it is clear enough to explain it, I delete the comment here.
return; | ||
|
||
unsigned Opcode = MI->getOpcode(); | ||
|
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.
nit: remove empty line
auto It = OpcodeMap.find(Opcode); | ||
if (It != OpcodeMap.end()) { | ||
// Set the new opcode to the mapped 64-bit version. | ||
NewOpcode = It->second; | ||
HasNonSignedExtInstrPromoted = true; | ||
} | ||
|
||
const PPCInstrInfo *TII = | ||
MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo(); | ||
if (!TII->isSExt32To64(Opcode) && !HasNonSignedExtInstrPromoted) | ||
return; | ||
|
||
const TargetRegisterClass *RC = MRI->getRegClass(Reg); | ||
if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass) | ||
return; | ||
|
||
// The TableGen function `get64BitInstrFromSignedExt32BitInstr` is used to | ||
// map the 32-bit instruction with the `SExt32To64` flag to the 64-bit | ||
// instruction with the same opcode. | ||
if (!HasNonSignedExtInstrPromoted) | ||
NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode); | ||
|
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 don't see a real need for this boolean flag HasNonSignedExtInstrPromoted
. I feel if we simplify it thus the intention is more clear.
auto It = OpcodeMap.find(Opcode); | |
if (It != OpcodeMap.end()) { | |
// Set the new opcode to the mapped 64-bit version. | |
NewOpcode = It->second; | |
HasNonSignedExtInstrPromoted = true; | |
} | |
const PPCInstrInfo *TII = | |
MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo(); | |
if (!TII->isSExt32To64(Opcode) && !HasNonSignedExtInstrPromoted) | |
return; | |
const TargetRegisterClass *RC = MRI->getRegClass(Reg); | |
if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass) | |
return; | |
// The TableGen function `get64BitInstrFromSignedExt32BitInstr` is used to | |
// map the 32-bit instruction with the `SExt32To64` flag to the 64-bit | |
// instruction with the same opcode. | |
if (!HasNonSignedExtInstrPromoted) | |
NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode); | |
int NewOpcode; | |
auto It = OpcodeMap.find(Opcode); | |
// Promote to 64bit instruction. | |
if (It != OpcodeMap.end()) | |
NewOpcode = It->second; | |
else { | |
if (!MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo()->isSExt32To64(Opcode)) | |
return; | |
// TableGen function `get64BitInstrFromSignedExt32BitInstr` can be used to | |
// obtain the equivalent 64bit instructions for 32bit instructions tagged with the `SExt32To64` flag. | |
NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode); | |
} | |
# please doc why we want to return here for R0? | |
const TargetRegisterClass *RC = MRI->getRegClass(Reg); | |
if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass) | |
return; |
// Map the opcode of instructions (which are not sign- or zero-extended | ||
// themselves,but have operands that are destination registers of sign- or | ||
// zero-extended instructions) to their 64-bit equivalents. |
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.
// Map the opcode of instructions (which are not sign- or zero-extended | |
// themselves,but have operands that are destination registers of sign- or | |
// zero-extended instructions) to their 64-bit equivalents. | |
// Map the 32bit to 64bit opcodes for instructions that are not signed or zero extended | |
// themselves, but may have operands who's destination registers are of signed or | |
// zero extended instructions. |
} | ||
} | ||
|
||
Register NewDefinedReg = MRI->createVirtualRegister(NewRC); |
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 the indentation from here to return
is a bit off.
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.
This LGTM. Thanks for addressing all the comments.
int NewOpcode = -1; | ||
|
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.
nit: maybe move this down to where it's being assigned... line 5345.
…Peephole (llvm#85451) Fixes: llvm#71030 Bug only happens in 64bit involving spills. Since we don't know when the spill will happen, all instructions in the chain used to deduce sign extension for eliminating 'extsw' will need to be promoted to 64-bit pseudo instructions. The following instruction will promoted in PPCMIPeepholes: EXTSH, LHA, ISEL to EXTSH8, LHA8, ISEL8
…Peephole (llvm#85451) Fixes: llvm#71030 Bug only happens in 64bit involving spills. Since we don't know when the spill will happen, all instructions in the chain used to deduce sign extension for eliminating 'extsw' will need to be promoted to 64-bit pseudo instructions. The following instruction will promoted in PPCMIPeepholes: EXTSH, LHA, ISEL to EXTSH8, LHA8, ISEL8
Fixes: #71030
Bug only happens in 64bit involving spills. Since we don't know when the spill will happen, all instructions in the chain used to deduce sign extension for eliminating 'extsw' will need to be promoted to 64-bit pseudo instructions.
The following instruction will promoted in PPCMIPeepholes: EXTSH, LHA, ISEL to EXTSH8, LHA8, ISEL8