forked from OSchip/llvm-project
[SystemZ] Be more careful about inverting CC masks (conditional loads)
Extend r187495 to conditional loads. I split this out because the easiest way seemed to be to force a particular operand order in SystemZISelDAGToDAG.cpp. llvm-svn: 187496
This commit is contained in:
parent
3d768e334b
commit
ee8343822e
|
@ -1012,6 +1012,27 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SystemZISD::SELECT_CCMASK: {
|
||||
SDValue Op0 = Node->getOperand(0);
|
||||
SDValue Op1 = Node->getOperand(1);
|
||||
// Prefer to put any load first, so that it can be matched as a
|
||||
// conditional load.
|
||||
if (Op1.getOpcode() == ISD::LOAD && Op0.getOpcode() != ISD::LOAD) {
|
||||
SDValue CCValid = Node->getOperand(2);
|
||||
SDValue CCMask = Node->getOperand(3);
|
||||
uint64_t ConstCCValid =
|
||||
cast<ConstantSDNode>(CCValid.getNode())->getZExtValue();
|
||||
uint64_t ConstCCMask =
|
||||
cast<ConstantSDNode>(CCMask.getNode())->getZExtValue();
|
||||
// Invert the condition.
|
||||
CCMask = CurDAG->getConstant(ConstCCValid ^ ConstCCMask,
|
||||
CCMask.getValueType());
|
||||
SDValue Op4 = Node->getOperand(4);
|
||||
Node = CurDAG->UpdateNodeOperands(Node, Op1, Op0, CCValid, CCMask, Op4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Select the default instruction
|
||||
|
|
|
@ -735,10 +735,14 @@ class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
|
|||
}
|
||||
|
||||
class CondUnaryRSY<string mnemonic, bits<16> opcode,
|
||||
RegisterOperand cls, bits<5> bytes,
|
||||
AddressingMode mode = bdaddr20only>
|
||||
: InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, cond4:$R3),
|
||||
mnemonic#"$R3\t$R1, $BD2", []>,
|
||||
SDPatternOperator operator, RegisterOperand cls,
|
||||
bits<5> bytes, AddressingMode mode = bdaddr20only>
|
||||
: InstRSY<opcode, (outs cls:$R1),
|
||||
(ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3),
|
||||
mnemonic#"$R3\t$R1, $BD2",
|
||||
[(set cls:$R1,
|
||||
(z_select_ccmask (load bdaddr20only:$BD2), cls:$R1src,
|
||||
cond4:$valid, cond4:$R3))]>,
|
||||
Requires<[FeatureLoadStoreOnCond]> {
|
||||
let Constraints = "$R1 = $R1src";
|
||||
let DisableEncoding = "$R1src";
|
||||
|
|
|
@ -272,15 +272,13 @@ let canFoldAsLoad = 1 in {
|
|||
|
||||
// Load on condition.
|
||||
let isCodeGenOnly = 1, Uses = [CC] in {
|
||||
def LOC : CondUnaryRSY<"loc", 0xEBF2, GR32, 4>;
|
||||
def LOCG : CondUnaryRSY<"locg", 0xEBE2, GR64, 8>;
|
||||
def LOC : CondUnaryRSY<"loc", 0xEBF2, nonvolatile_load, GR32, 4>;
|
||||
def LOCG : CondUnaryRSY<"locg", 0xEBE2, nonvolatile_load, GR64, 8>;
|
||||
}
|
||||
let Uses = [CC] in {
|
||||
def AsmLOC : AsmCondUnaryRSY<"loc", 0xEBF2, GR32, 4>;
|
||||
def AsmLOCG : AsmCondUnaryRSY<"locg", 0xEBE2, GR64, 8>;
|
||||
}
|
||||
defm : CondLoad<LOC, GR32, nonvolatile_load>;
|
||||
defm : CondLoad<LOCG, GR64, nonvolatile_load>;
|
||||
|
||||
// Register stores.
|
||||
let SimpleBDXStore = 1 in {
|
||||
|
|
|
@ -110,15 +110,6 @@ class BDLMode<string type, string bitsize, string dispsize, string suffix,
|
|||
!cast<Immediate>("disp"##dispsize##"imm"##bitsize),
|
||||
!cast<Immediate>("imm"##bitsize))>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Manipulating CC masks
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def INVCC : SDNodeXForm<imm, [{
|
||||
unsigned Value = N->getZExtValue() ^ SystemZ::CCMASK_ANY;
|
||||
return CurDAG->getTargetConstant(Value, MVT::i8);
|
||||
}]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Extracting immediate operands from nodes
|
||||
// These all create MVT::i64 nodes to ensure the value is not sign-extended
|
||||
|
|
|
@ -54,20 +54,6 @@ multiclass RMWIByte<SDPatternOperator operator, AddressingMode mode,
|
|||
def : RMWI<anyextloadi8, operator, truncstorei8, mode, imm64, insn>;
|
||||
}
|
||||
|
||||
// Record that INSN conditionally performs load operation LOAD into a
|
||||
// register of class CLS. The load may trap even if the condition is false.
|
||||
multiclass CondLoad<Instruction insn, RegisterOperand cls,
|
||||
SDPatternOperator load> {
|
||||
def : Pat<(z_select_ccmask (load bdaddr20only:$addr), cls:$new, uimm8zx4,
|
||||
uimm8zx4:$cc),
|
||||
(insn cls:$new, bdaddr20only:$addr, uimm8zx4:$cc)>,
|
||||
Requires<[FeatureLoadStoreOnCond]>;
|
||||
def : Pat<(z_select_ccmask cls:$new, (load bdaddr20only:$addr), uimm8zx4,
|
||||
uimm8zx4:$cc),
|
||||
(insn cls:$new, bdaddr20only:$addr, (INVCC uimm8zx4:$cc))>,
|
||||
Requires<[FeatureLoadStoreOnCond]>;
|
||||
}
|
||||
|
||||
// Record that INSN performs insertion TYPE into a register of class CLS.
|
||||
// The inserted operand is loaded using LOAD from an address of mode MODE.
|
||||
multiclass InsertMem<string type, Instruction insn, RegisterOperand cls,
|
||||
|
|
|
@ -8,7 +8,7 @@ declare i32 @foo(i32 *)
|
|||
define i32 @f1(i32 %easy, i32 *%ptr, i32 %limit) {
|
||||
; CHECK-LABEL: f1:
|
||||
; CHECK: clfi %r4, 42
|
||||
; CHECK: locnl %r2, 0(%r3)
|
||||
; CHECK: loche %r2, 0(%r3)
|
||||
; CHECK: br %r14
|
||||
%cond = icmp ult i32 %limit, 42
|
||||
%other = load i32 *%ptr
|
||||
|
@ -32,7 +32,7 @@ define i32 @f2(i32 %easy, i32 *%ptr, i32 %limit) {
|
|||
define i32 @f3(i32 %easy, i32 *%base, i32 %limit) {
|
||||
; CHECK-LABEL: f3:
|
||||
; CHECK: clfi %r4, 42
|
||||
; CHECK: locnl %r2, 524284(%r3)
|
||||
; CHECK: loche %r2, 524284(%r3)
|
||||
; CHECK: br %r14
|
||||
%ptr = getelementptr i32 *%base, i64 131071
|
||||
%cond = icmp ult i32 %limit, 42
|
||||
|
@ -46,7 +46,7 @@ define i32 @f4(i32 %easy, i32 *%base, i32 %limit) {
|
|||
; CHECK-LABEL: f4:
|
||||
; CHECK: agfi %r3, 524288
|
||||
; CHECK: clfi %r4, 42
|
||||
; CHECK: locnl %r2, 0(%r3)
|
||||
; CHECK: loche %r2, 0(%r3)
|
||||
; CHECK: br %r14
|
||||
%ptr = getelementptr i32 *%base, i64 131072
|
||||
%cond = icmp ult i32 %limit, 42
|
||||
|
@ -59,7 +59,7 @@ define i32 @f4(i32 %easy, i32 *%base, i32 %limit) {
|
|||
define i32 @f5(i32 %easy, i32 *%base, i32 %limit) {
|
||||
; CHECK-LABEL: f5:
|
||||
; CHECK: clfi %r4, 42
|
||||
; CHECK: locnl %r2, -524288(%r3)
|
||||
; CHECK: loche %r2, -524288(%r3)
|
||||
; CHECK: br %r14
|
||||
%ptr = getelementptr i32 *%base, i64 -131072
|
||||
%cond = icmp ult i32 %limit, 42
|
||||
|
@ -73,7 +73,7 @@ define i32 @f6(i32 %easy, i32 *%base, i32 %limit) {
|
|||
; CHECK-LABEL: f6:
|
||||
; CHECK: agfi %r3, -524292
|
||||
; CHECK: clfi %r4, 42
|
||||
; CHECK: locnl %r2, 0(%r3)
|
||||
; CHECK: loche %r2, 0(%r3)
|
||||
; CHECK: br %r14
|
||||
%ptr = getelementptr i32 *%base, i64 -131073
|
||||
%cond = icmp ult i32 %limit, 42
|
||||
|
@ -86,7 +86,7 @@ define i32 @f6(i32 %easy, i32 *%base, i32 %limit) {
|
|||
define i32 @f7(i32 %alt, i32 %limit) {
|
||||
; CHECK-LABEL: f7:
|
||||
; CHECK: brasl %r14, foo@PLT
|
||||
; CHECK: locnl %r2, {{[0-9]+}}(%r15)
|
||||
; CHECK: loche %r2, {{[0-9]+}}(%r15)
|
||||
; CHECK: br %r14
|
||||
%ptr = alloca i32
|
||||
%easy = call i32 @foo(i32 *%ptr)
|
||||
|
@ -100,7 +100,7 @@ define i32 @f7(i32 %alt, i32 %limit) {
|
|||
define i32 @f8(i32 %easy, i32 %limit, i64 %base, i64 %index) {
|
||||
; CHECK-LABEL: f8:
|
||||
; CHECK: clfi %r3, 42
|
||||
; CHECK: locnl %r2, 0({{%r[1-5]}})
|
||||
; CHECK: loche %r2, 0({{%r[1-5]}})
|
||||
; CHECK: br %r14
|
||||
%add = add i64 %base, %index
|
||||
%ptr = inttoptr i64 %add to i32 *
|
||||
|
|
|
@ -8,7 +8,7 @@ declare i64 @foo(i64 *)
|
|||
define i64 @f1(i64 %easy, i64 *%ptr, i64 %limit) {
|
||||
; CHECK-LABEL: f1:
|
||||
; CHECK: clgfi %r4, 42
|
||||
; CHECK: locgnl %r2, 0(%r3)
|
||||
; CHECK: locghe %r2, 0(%r3)
|
||||
; CHECK: br %r14
|
||||
%cond = icmp ult i64 %limit, 42
|
||||
%other = load i64 *%ptr
|
||||
|
@ -32,7 +32,7 @@ define i64 @f2(i64 %easy, i64 *%ptr, i64 %limit) {
|
|||
define i64 @f3(i64 %easy, i64 *%base, i64 %limit) {
|
||||
; CHECK-LABEL: f3:
|
||||
; CHECK: clgfi %r4, 42
|
||||
; CHECK: locgnl %r2, 524280(%r3)
|
||||
; CHECK: locghe %r2, 524280(%r3)
|
||||
; CHECK: br %r14
|
||||
%ptr = getelementptr i64 *%base, i64 65535
|
||||
%cond = icmp ult i64 %limit, 42
|
||||
|
@ -46,7 +46,7 @@ define i64 @f4(i64 %easy, i64 *%base, i64 %limit) {
|
|||
; CHECK-LABEL: f4:
|
||||
; CHECK: agfi %r3, 524288
|
||||
; CHECK: clgfi %r4, 42
|
||||
; CHECK: locgnl %r2, 0(%r3)
|
||||
; CHECK: locghe %r2, 0(%r3)
|
||||
; CHECK: br %r14
|
||||
%ptr = getelementptr i64 *%base, i64 65536
|
||||
%cond = icmp ult i64 %limit, 42
|
||||
|
@ -59,7 +59,7 @@ define i64 @f4(i64 %easy, i64 *%base, i64 %limit) {
|
|||
define i64 @f5(i64 %easy, i64 *%base, i64 %limit) {
|
||||
; CHECK-LABEL: f5:
|
||||
; CHECK: clgfi %r4, 42
|
||||
; CHECK: locgnl %r2, -524288(%r3)
|
||||
; CHECK: locghe %r2, -524288(%r3)
|
||||
; CHECK: br %r14
|
||||
%ptr = getelementptr i64 *%base, i64 -65536
|
||||
%cond = icmp ult i64 %limit, 42
|
||||
|
@ -73,7 +73,7 @@ define i64 @f6(i64 %easy, i64 *%base, i64 %limit) {
|
|||
; CHECK-LABEL: f6:
|
||||
; CHECK: agfi %r3, -524296
|
||||
; CHECK: clgfi %r4, 42
|
||||
; CHECK: locgnl %r2, 0(%r3)
|
||||
; CHECK: locghe %r2, 0(%r3)
|
||||
; CHECK: br %r14
|
||||
%ptr = getelementptr i64 *%base, i64 -65537
|
||||
%cond = icmp ult i64 %limit, 42
|
||||
|
@ -86,7 +86,7 @@ define i64 @f6(i64 %easy, i64 *%base, i64 %limit) {
|
|||
define i64 @f7(i64 %alt, i64 %limit) {
|
||||
; CHECK-LABEL: f7:
|
||||
; CHECK: brasl %r14, foo@PLT
|
||||
; CHECK: locgnl %r2, {{[0-9]+}}(%r15)
|
||||
; CHECK: locghe %r2, {{[0-9]+}}(%r15)
|
||||
; CHECK: br %r14
|
||||
%ptr = alloca i64
|
||||
%easy = call i64 @foo(i64 *%ptr)
|
||||
|
@ -100,7 +100,7 @@ define i64 @f7(i64 %alt, i64 %limit) {
|
|||
define i64 @f8(i64 %easy, i64 %limit, i64 %base, i64 %index) {
|
||||
; CHECK-LABEL: f8:
|
||||
; CHECK: clgfi %r3, 42
|
||||
; CHECK: locgnl %r2, 0({{%r[1-5]}})
|
||||
; CHECK: locghe %r2, 0({{%r[1-5]}})
|
||||
; CHECK: br %r14
|
||||
%add = add i64 %base, %index
|
||||
%ptr = inttoptr i64 %add to i64 *
|
||||
|
|
Loading…
Reference in New Issue