mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[SystemZ] Fix TMHH and TMHL usage for z10 with -O0
I've no idea why I decided to handle TMxx differently from all the other high/low logic operations, but it was a stupid thing to do. The high registers aren't available as separate 32-bit registers on z10, so subreg_h32 can't be used on a GR64 there. I've normally been testing with z196 and with -O3 and so hadn't noticed this until now. llvm-svn: 195473
This commit is contained in:
parent
749aa1e00d
commit
d5298a3795
@ -29,19 +29,29 @@ using namespace llvm;
|
||||
// Return an RI instruction like MI with opcode Opcode, but with the
|
||||
// GR64 register operands turned into GR32s.
|
||||
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
|
||||
return MCInstBuilder(Opcode)
|
||||
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
|
||||
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
|
||||
.addImm(MI->getOperand(2).getImm());
|
||||
if (MI->isCompare())
|
||||
return MCInstBuilder(Opcode)
|
||||
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
|
||||
.addImm(MI->getOperand(1).getImm());
|
||||
else
|
||||
return MCInstBuilder(Opcode)
|
||||
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
|
||||
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
|
||||
.addImm(MI->getOperand(2).getImm());
|
||||
}
|
||||
|
||||
// Return an RI instruction like MI with opcode Opcode, but with the
|
||||
// GR64 register operands turned into GRH32s.
|
||||
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
|
||||
return MCInstBuilder(Opcode)
|
||||
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
|
||||
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
|
||||
.addImm(MI->getOperand(2).getImm());
|
||||
if (MI->isCompare())
|
||||
return MCInstBuilder(Opcode)
|
||||
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
|
||||
.addImm(MI->getOperand(1).getImm());
|
||||
else
|
||||
return MCInstBuilder(Opcode)
|
||||
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
|
||||
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
|
||||
.addImm(MI->getOperand(2).getImm());
|
||||
}
|
||||
|
||||
// Return an RI instruction like MI with opcode Opcode, but with the
|
||||
@ -112,6 +122,8 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
|
||||
LOWER_LOW(IILL);
|
||||
LOWER_LOW(IILH);
|
||||
LOWER_LOW(TMLL);
|
||||
LOWER_LOW(TMLH);
|
||||
LOWER_LOW(NILL);
|
||||
LOWER_LOW(NILH);
|
||||
LOWER_LOW(NILF);
|
||||
@ -127,6 +139,8 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
|
||||
LOWER_HIGH(IIHL);
|
||||
LOWER_HIGH(IIHH);
|
||||
LOWER_HIGH(TMHL);
|
||||
LOWER_HIGH(TMHH);
|
||||
LOWER_HIGH(NIHL);
|
||||
LOWER_HIGH(NIHH);
|
||||
LOWER_HIGH(NIHF);
|
||||
|
@ -1588,6 +1588,13 @@ class BinaryAliasRIL<SDPatternOperator operator, RegisterOperand cls,
|
||||
let Constraints = "$R1 = $R1src";
|
||||
}
|
||||
|
||||
// An alias of a CompareRI, but with different register sizes.
|
||||
class CompareAliasRI<SDPatternOperator operator, RegisterOperand cls,
|
||||
Immediate imm>
|
||||
: Alias<4, (outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> {
|
||||
let isCompare = 1;
|
||||
}
|
||||
|
||||
// An alias of a RotateSelectRIEf, but with different register sizes.
|
||||
class RotateSelectAliasRIEf<RegisterOperand cls1, RegisterOperand cls2>
|
||||
: Alias<6, (outs cls1:$R1),
|
||||
|
@ -1176,12 +1176,13 @@ let Defs = [CC] in {
|
||||
def TMHL : CompareRI<"tmhl", 0xA73, z_tm_reg, GRH32, imm32ll16>;
|
||||
def TMHH : CompareRI<"tmhh", 0xA72, z_tm_reg, GRH32, imm32lh16>;
|
||||
|
||||
def TMLL64 : CompareAliasRI<z_tm_reg, GR64, imm64ll16>;
|
||||
def TMLH64 : CompareAliasRI<z_tm_reg, GR64, imm64lh16>;
|
||||
def TMHL64 : CompareAliasRI<z_tm_reg, GR64, imm64hl16>;
|
||||
def TMHH64 : CompareAliasRI<z_tm_reg, GR64, imm64hh16>;
|
||||
|
||||
defm TM : CompareSIPair<"tm", 0x91, 0xEB51, z_tm_mem, anyextloadi8, imm32zx8>;
|
||||
}
|
||||
def : CompareGR64RI<TMLL, z_tm_reg, imm64ll16, subreg_l32>;
|
||||
def : CompareGR64RI<TMLH, z_tm_reg, imm64lh16, subreg_l32>;
|
||||
def : CompareGR64RI<TMHL, z_tm_reg, imm64hl16, subreg_h32>;
|
||||
def : CompareGR64RI<TMHH, z_tm_reg, imm64hh16, subreg_h32>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Prefetch
|
||||
|
@ -112,14 +112,6 @@ multiclass CondStores64<Instruction insn, Instruction insninv,
|
||||
uimm8zx4:$valid, uimm8zx4:$cc)>;
|
||||
}
|
||||
|
||||
// INSN performs a comparison between a 32-bit register and a constant.
|
||||
// Record that it is equivalent to comparing subreg SUBREG of a GR64 with IMM.
|
||||
class CompareGR64RI<Instruction insn, SDPatternOperator compare,
|
||||
Immediate imm, SubRegIndex subreg>
|
||||
: Pat<(compare GR64:$R1, imm:$I2),
|
||||
(insn (EXTRACT_SUBREG GR64:$R1, subreg),
|
||||
(imm.OperandTransform imm:$I2))>;
|
||||
|
||||
// Try to use MVC instruction INSN for a load of type LOAD followed by a store
|
||||
// of the same size. VT is the type of the intermediate (legalized) value and
|
||||
// LENGTH is the number of bytes loaded by LOAD.
|
||||
|
@ -1,5 +1,6 @@
|
||||
; Test the use of TEST UNDER MASK for 64-bit operations.
|
||||
;
|
||||
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
|
||||
|
||||
@g = global i32 0
|
||||
|
49
test/CodeGen/SystemZ/int-cmp-49.ll
Normal file
49
test/CodeGen/SystemZ/int-cmp-49.ll
Normal file
@ -0,0 +1,49 @@
|
||||
; That that we don't try to use z196 instructions on z10 for TMHH and TMHL.
|
||||
;
|
||||
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -O0 | FileCheck %s
|
||||
|
||||
@g = global i32 0
|
||||
|
||||
; Check the lowest useful TMHL value.
|
||||
define void @f1(i64 %a) {
|
||||
; CHECK-LABEL: f1:
|
||||
; CHECK-NOT: risblg
|
||||
; CHECK-NOT: risbhg
|
||||
; CHECK: tmhl {{%r[0-5]}}, 1
|
||||
; CHECK-NOT: risblg
|
||||
; CHECK-NOT: risbhg
|
||||
; CHECK: br %r14
|
||||
entry:
|
||||
%and = and i64 %a, 4294967296
|
||||
%cmp = icmp eq i64 %and, 0
|
||||
br i1 %cmp, label %exit, label %store
|
||||
|
||||
store:
|
||||
store i32 1, i32 *@g
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check the lowest useful TMHH value.
|
||||
define void @f2(i64 %a) {
|
||||
; CHECK-LABEL: f2:
|
||||
; CHECK-NOT: risblg
|
||||
; CHECK-NOT: risbhg
|
||||
; CHECK: tmhh {{%r[0-5]}}, 1
|
||||
; CHECK-NOT: risblg
|
||||
; CHECK-NOT: risbhg
|
||||
; CHECK: br %r14
|
||||
entry:
|
||||
%and = and i64 %a, 281474976710656
|
||||
%cmp = icmp ne i64 %and, 0
|
||||
br i1 %cmp, label %exit, label %store
|
||||
|
||||
store:
|
||||
store i32 1, i32 *@g
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user