mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-04 02:40:34 +00:00
GlobalISel: make truncate/extend casts uniform
They really should have both types represented, but early variants were created before MachineInstrs could have multiple types so they're rather ambiguous. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279567 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4f24b7db0e
commit
2a105605e3
@ -52,6 +52,8 @@ class MachineIRBuilder {
|
||||
return *TII;
|
||||
}
|
||||
|
||||
void validateTruncExt(ArrayRef<LLT> Tys, bool IsExtend);
|
||||
|
||||
public:
|
||||
/// Getter for the function we currently build.
|
||||
MachineFunction &getMF() {
|
||||
@ -144,9 +146,9 @@ public:
|
||||
MachineInstrBuilder buildUAdde(LLT Ty, unsigned Res, unsigned CarryOut,
|
||||
unsigned Op0, unsigned Op1, unsigned CarryIn);
|
||||
|
||||
/// Build and insert \p Res<def> = G_ANYEXTEND \p Ty \p Op0
|
||||
/// Build and insert \p Res<def> = G_ANYEXT \p { DstTy, SrcTy } \p Op0
|
||||
///
|
||||
/// G_ANYEXTEND produces a register of the specified width, with bits 0 to
|
||||
/// G_ANYEXT produces a register of the specified width, with bits 0 to
|
||||
/// sizeof(\p Ty) * 8 set to \p Op. The remaining bits are unspecified
|
||||
/// (i.e. this is neither zero nor sign-extension). For a vector register,
|
||||
/// each element is extended individually.
|
||||
@ -154,7 +156,7 @@ public:
|
||||
/// \pre setBasicBlock or setMI must have been called.
|
||||
///
|
||||
/// \return The newly created instruction.
|
||||
MachineInstrBuilder buildAnyExtend(LLT Ty, unsigned Res, unsigned Op);
|
||||
MachineInstrBuilder buildAnyExt(ArrayRef<LLT> Tys, unsigned Res, unsigned Op);
|
||||
|
||||
/// Build and insert \p Res<def> = G_SEXT \p { DstTy, SrcTy }\p Op
|
||||
///
|
||||
@ -325,16 +327,16 @@ public:
|
||||
MachineInstrBuilder buildIntrinsic(ArrayRef<LLT> Tys, Intrinsic::ID ID,
|
||||
unsigned Res, bool HasSideEffects);
|
||||
|
||||
/// Build and insert \p Res<def> = G_FPTRUNC \p Ty \p Op
|
||||
/// Build and insert \p Res<def> = G_FPTRUNC \p { DstTy, SrcTy } \p Op
|
||||
///
|
||||
/// G_FPTRUNC converts a floating-point value into one with a smaller type.
|
||||
///
|
||||
/// \pre setBasicBlock or setMI must have been called.
|
||||
///
|
||||
/// \return The newly created instruction.
|
||||
MachineInstrBuilder buildFPTrunc(LLT Ty, unsigned Res, unsigned Op);
|
||||
MachineInstrBuilder buildFPTrunc(ArrayRef<LLT> Ty, unsigned Res, unsigned Op);
|
||||
|
||||
/// Build and insert \p Res<def> = G_TRUNC \p Ty \p Op
|
||||
/// Build and insert \p Res<def> = G_TRUNC \p { DstTy, SrcTy } \p Op
|
||||
///
|
||||
/// G_TRUNC extracts the low bits of a type. For a vector type each element is
|
||||
/// truncated independently before being packed into the destination.
|
||||
@ -342,7 +344,7 @@ public:
|
||||
/// \pre setBasicBlock or setMI must have been called.
|
||||
///
|
||||
/// \return The newly created instruction.
|
||||
MachineInstrBuilder buildTrunc(LLT Ty, unsigned Res, unsigned Op);
|
||||
MachineInstrBuilder buildTrunc(ArrayRef<LLT> Tys, unsigned Res, unsigned Op);
|
||||
|
||||
/// Build and insert a G_ICMP
|
||||
///
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
// Extend the underlying scalar type of an operation, leaving the high bits
|
||||
// unspecified.
|
||||
def G_ANYEXTEND : Instruction {
|
||||
def G_ANYEXT : Instruction {
|
||||
let OutOperandList = (outs unknown:$dst);
|
||||
let InOperandList = (ins unknown:$src);
|
||||
let hasSideEffects = 0;
|
||||
|
@ -233,7 +233,7 @@ HANDLE_TARGET_OPCODE(G_INTRINSIC)
|
||||
HANDLE_TARGET_OPCODE(G_INTRINSIC_W_SIDE_EFFECTS)
|
||||
|
||||
/// Generic extension allowing rubbish in high bits.
|
||||
HANDLE_TARGET_OPCODE(G_ANYEXTEND)
|
||||
HANDLE_TARGET_OPCODE(G_ANYEXT)
|
||||
|
||||
/// Generic instruction to discard the high bits of a register. This differs
|
||||
/// from (G_EXTRACT val, 0) on its action on vectors: G_TRUNC will truncate
|
||||
|
@ -141,18 +141,21 @@ MachineInstrBuilder MachineIRBuilder::buildUAdde(LLT Ty, unsigned Res,
|
||||
.addUse(CarryIn);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildAnyExtend(LLT Ty, unsigned Res,
|
||||
unsigned Op) {
|
||||
return buildInstr(TargetOpcode::G_ANYEXTEND, Ty).addDef(Res).addUse(Op);
|
||||
MachineInstrBuilder MachineIRBuilder::buildAnyExt(ArrayRef<LLT> Tys,
|
||||
unsigned Res, unsigned Op) {
|
||||
validateTruncExt(Tys, true);
|
||||
return buildInstr(TargetOpcode::G_ANYEXT, Tys).addDef(Res).addUse(Op);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildSExt(ArrayRef<LLT> Tys, unsigned Res,
|
||||
unsigned Op) {
|
||||
validateTruncExt(Tys, true);
|
||||
return buildInstr(TargetOpcode::G_SEXT, Tys).addDef(Res).addUse(Op);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildZExt(ArrayRef<LLT> Tys, unsigned Res,
|
||||
unsigned Op) {
|
||||
validateTruncExt(Tys, true);
|
||||
return buildInstr(TargetOpcode::G_ZEXT, Tys).addDef(Res).addUse(Op);
|
||||
}
|
||||
|
||||
@ -216,14 +219,16 @@ MachineInstrBuilder MachineIRBuilder::buildIntrinsic(ArrayRef<LLT> Tys,
|
||||
return MIB;
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildTrunc(LLT Ty, unsigned Res,
|
||||
unsigned Op) {
|
||||
return buildInstr(TargetOpcode::G_TRUNC, Ty).addDef(Res).addUse(Op);
|
||||
MachineInstrBuilder MachineIRBuilder::buildTrunc(ArrayRef<LLT> Tys,
|
||||
unsigned Res, unsigned Op) {
|
||||
validateTruncExt(Tys, false);
|
||||
return buildInstr(TargetOpcode::G_TRUNC, Tys).addDef(Res).addUse(Op);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildFPTrunc(LLT Ty, unsigned Res,
|
||||
unsigned Op) {
|
||||
return buildInstr(TargetOpcode::G_FPTRUNC, Ty).addDef(Res).addUse(Op);
|
||||
MachineInstrBuilder MachineIRBuilder::buildFPTrunc(ArrayRef<LLT> Tys,
|
||||
unsigned Res, unsigned Op) {
|
||||
validateTruncExt(Tys, false);
|
||||
return buildInstr(TargetOpcode::G_FPTRUNC, Tys).addDef(Res).addUse(Op);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildICmp(ArrayRef<LLT> Tys,
|
||||
@ -257,3 +262,22 @@ MachineInstrBuilder MachineIRBuilder::buildSelect(LLT Ty, unsigned Res,
|
||||
.addUse(Op0)
|
||||
.addUse(Op1);
|
||||
}
|
||||
|
||||
void MachineIRBuilder::validateTruncExt(ArrayRef<LLT> Tys, bool IsExtend) {
|
||||
assert(Tys.size() == 2 && "cast should have a source and a dest type");
|
||||
LLT DstTy{Tys[0]}, SrcTy{Tys[1]};
|
||||
|
||||
if (DstTy.isVector()) {
|
||||
assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
|
||||
assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
|
||||
"different number of elements in a trunc/ext");
|
||||
} else
|
||||
assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
|
||||
|
||||
if (IsExtend)
|
||||
assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
|
||||
"invalid narrowing extend");
|
||||
else
|
||||
assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
|
||||
"invalid widening trunc");
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ MachineLegalizeHelper::narrowScalar(MachineInstr &MI, unsigned TypeIdx,
|
||||
MachineLegalizeHelper::LegalizeResult
|
||||
MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
|
||||
LLT WideTy) {
|
||||
LLT Ty = MI.getType();
|
||||
unsigned WideSize = WideTy.getSizeInBits();
|
||||
MIRBuilder.setInstr(MI);
|
||||
|
||||
@ -124,34 +125,34 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
|
||||
// original type.
|
||||
unsigned Src1Ext = MRI.createGenericVirtualRegister(WideSize);
|
||||
unsigned Src2Ext = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildAnyExtend(WideTy, Src1Ext, MI.getOperand(1).getReg());
|
||||
MIRBuilder.buildAnyExtend(WideTy, Src2Ext, MI.getOperand(2).getReg());
|
||||
MIRBuilder.buildAnyExt({WideTy, Ty}, Src1Ext, MI.getOperand(1).getReg());
|
||||
MIRBuilder.buildAnyExt({WideTy, Ty}, Src2Ext, MI.getOperand(2).getReg());
|
||||
|
||||
unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildInstr(MI.getOpcode(), WideTy)
|
||||
.addDef(DstExt).addUse(Src1Ext).addUse(Src2Ext);
|
||||
|
||||
MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
|
||||
MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
case TargetOpcode::G_LOAD: {
|
||||
assert(alignTo(MI.getType().getSizeInBits(), 8) == WideSize &&
|
||||
assert(alignTo(Ty.getSizeInBits(), 8) == WideSize &&
|
||||
"illegal to increase number of bytes loaded");
|
||||
|
||||
unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildLoad(WideTy, MI.getType(1), DstExt,
|
||||
MI.getOperand(1).getReg(), **MI.memoperands_begin());
|
||||
MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
|
||||
MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
case TargetOpcode::G_STORE: {
|
||||
assert(alignTo(MI.getType().getSizeInBits(), 8) == WideSize &&
|
||||
assert(alignTo(Ty.getSizeInBits(), 8) == WideSize &&
|
||||
"illegal to increase number of bytes modified by a store");
|
||||
|
||||
unsigned SrcExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildAnyExtend(WideTy, SrcExt, MI.getOperand(0).getReg());
|
||||
MIRBuilder.buildAnyExt({WideTy, Ty}, SrcExt, MI.getOperand(0).getReg());
|
||||
MIRBuilder.buildStore(WideTy, MI.getType(1), SrcExt,
|
||||
MI.getOperand(1).getReg(), **MI.memoperands_begin());
|
||||
MI.eraseFromParent();
|
||||
@ -160,20 +161,20 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
|
||||
case TargetOpcode::G_CONSTANT: {
|
||||
unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildConstant(WideTy, DstExt, MI.getOperand(1).getImm());
|
||||
MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
|
||||
MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
case TargetOpcode::G_FCONSTANT: {
|
||||
unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildFConstant(WideTy, DstExt, *MI.getOperand(1).getFPImm());
|
||||
MIRBuilder.buildFPTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt);
|
||||
MIRBuilder.buildFPTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
case TargetOpcode::G_BRCOND: {
|
||||
unsigned TstExt = MRI.createGenericVirtualRegister(WideSize);
|
||||
MIRBuilder.buildAnyExtend(WideTy, TstExt, MI.getOperand(0).getReg());
|
||||
MIRBuilder.buildAnyExt({WideTy, Ty}, TstExt, MI.getOperand(0).getReg());
|
||||
MIRBuilder.buildBrCond(WideTy, TstExt, *MI.getOperand(1).getMBB());
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
@ -185,7 +186,7 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
|
||||
{WideTy, MI.getType(1)},
|
||||
static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
|
||||
TstExt, MI.getOperand(2).getReg(), MI.getOperand(3).getReg());
|
||||
MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), TstExt);
|
||||
MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), TstExt);
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
} else {
|
||||
|
@ -27,7 +27,7 @@ using namespace llvm;
|
||||
MachineLegalizer::MachineLegalizer() : TablesInitialized(false) {
|
||||
// FIXME: these two can be legalized to the fundamental load/store Jakob
|
||||
// proposed. Once loads & stores are supported.
|
||||
DefaultActions[TargetOpcode::G_ANYEXTEND] = Legal;
|
||||
DefaultActions[TargetOpcode::G_ANYEXT] = Legal;
|
||||
DefaultActions[TargetOpcode::G_TRUNC] = Legal;
|
||||
|
||||
DefaultActions[TargetOpcode::G_INTRINSIC] = Legal;
|
||||
|
@ -52,15 +52,15 @@ body: |
|
||||
bb.0.entry:
|
||||
liveins: %x0, %x1, %x2, %x3
|
||||
; CHECK-LABEL: name: test_scalar_add_small
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXTEND s32 %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXTEND s32 %1
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXT { s32, s8 } %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXT { s32, s8 } %1
|
||||
; CHECK: [[RES:%.*]](32) = G_ADD s32 [[LHS]], [[RHS]]
|
||||
; CHECK: %2(8) = G_TRUNC s8 [[RES]]
|
||||
; CHECK: %2(8) = G_TRUNC { s8, s32 } [[RES]]
|
||||
|
||||
%0(8) = G_TRUNC s8 %x0
|
||||
%1(8) = G_TRUNC s8 %x1
|
||||
%0(8) = G_TRUNC { s8, s64 } %x0
|
||||
%1(8) = G_TRUNC { s8, s64 } %x1
|
||||
%2(8) = G_ADD s8 %0, %1
|
||||
%x0 = G_ANYEXTEND s64 %2
|
||||
%x0 = G_ANYEXT { s64, s8 } %2
|
||||
...
|
||||
|
||||
---
|
||||
|
@ -20,13 +20,13 @@ body: |
|
||||
bb.0.entry:
|
||||
liveins: %x0, %x1, %x2, %x3
|
||||
; CHECK-LABEL: name: test_scalar_and_small
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXTEND s32 %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXTEND s32 %1
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXT { s32, s8 } %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXT { s32, s8 } %1
|
||||
; CHECK: [[RES:%.*]](32) = G_AND s32 [[LHS]], [[RHS]]
|
||||
; CHECK: %2(8) = G_TRUNC s8 [[RES]]
|
||||
; CHECK: %2(8) = G_TRUNC { s8, s32 } [[RES]]
|
||||
|
||||
%0(8) = G_TRUNC s8 %x0
|
||||
%1(8) = G_TRUNC s8 %x1
|
||||
%0(8) = G_TRUNC { s8, s32 } %x0
|
||||
%1(8) = G_TRUNC { s8, s32 } %x1
|
||||
%2(8) = G_AND s8 %0, %1
|
||||
%x0 = G_ANYEXTEND s64 %2
|
||||
%x0 = G_ANYEXT { s64, s8 } %2
|
||||
...
|
||||
|
@ -26,11 +26,11 @@ body: |
|
||||
bb.0.entry:
|
||||
; CHECK-LABEL: name: test_constant
|
||||
; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 0
|
||||
; CHECK: %0(1) = G_TRUNC s1 [[TMP]]
|
||||
; CHECK: %0(1) = G_TRUNC { s1, s32 } [[TMP]]
|
||||
; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 42
|
||||
; CHECK: %1(8) = G_TRUNC s8 [[TMP]]
|
||||
; CHECK: %1(8) = G_TRUNC { s8, s32 } [[TMP]]
|
||||
; CHECK: [[TMP:%[0-9]+]](32) = G_CONSTANT s32 65535
|
||||
; CHECK: %2(16) = G_TRUNC s16 [[TMP]]
|
||||
; CHECK: %2(16) = G_TRUNC { s16, s32 } [[TMP]]
|
||||
; CHECK: %3(32) = G_CONSTANT s32 -1
|
||||
; CHECK: %4(64) = G_CONSTANT s64 1
|
||||
|
||||
@ -54,7 +54,7 @@ body: |
|
||||
; CHECK: %0(32) = G_FCONSTANT s32 float 1.000000e+00
|
||||
; CHECK: %1(64) = G_FCONSTANT s64 double 2.000000e+00
|
||||
; CHECK: [[TMP:%[0-9]+]](32) = G_FCONSTANT s32 half 0xH0000
|
||||
; CHECK; %2(16) = G_FPTRUNC s16 [[TMP]]
|
||||
; CHECK; %2(16) = G_FPTRUNC { s16, s32 } [[TMP]]
|
||||
|
||||
%0(32) = G_FCONSTANT s32 float 1.0
|
||||
%1(64) = G_FCONSTANT s64 double 2.0
|
||||
|
@ -30,7 +30,7 @@ body: |
|
||||
%0(64) = COPY %x0
|
||||
|
||||
; CHECK: [[BIT8:%[0-9]+]](8) = G_LOAD { s8, p0 } %0 :: (load 1 from %ir.addr)
|
||||
; CHECK: %1(1) = G_TRUNC s1 [[BIT8]]
|
||||
; CHECK: %1(1) = G_TRUNC { s1, s8 } [[BIT8]]
|
||||
%1(1) = G_LOAD { s1, p0 } %0 :: (load 1 from %ir.addr)
|
||||
|
||||
; CHECK: %2(8) = G_LOAD { s8, p0 } %0 :: (load 1 from %ir.addr)
|
||||
@ -63,7 +63,7 @@ body: |
|
||||
%0(64) = COPY %x0
|
||||
%1(32) = COPY %w1
|
||||
|
||||
; CHECK: [[BIT8:%[0-9]+]](8) = G_ANYEXTEND s8 %2
|
||||
; CHECK: [[BIT8:%[0-9]+]](8) = G_ANYEXT { s8, s1 } %2
|
||||
; CHECK: G_STORE { s8, p0 } [[BIT8]], %0 :: (store 1 into %ir.addr)
|
||||
%2(1) = G_TRUNC s1 %1
|
||||
G_STORE { s1, p0 } %2, %0 :: (store 1 into %ir.addr)
|
||||
|
@ -20,13 +20,13 @@ body: |
|
||||
bb.0.entry:
|
||||
liveins: %x0, %x1, %x2, %x3
|
||||
; CHECK-LABEL: name: test_scalar_mul_small
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXTEND s32 %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXTEND s32 %1
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXT { s32, s8 } %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXT { s32, s8 } %1
|
||||
; CHECK: [[RES:%.*]](32) = G_MUL s32 [[LHS]], [[RHS]]
|
||||
; CHECK: %2(8) = G_TRUNC s8 [[RES]]
|
||||
; CHECK: %2(8) = G_TRUNC { s8, s32 } [[RES]]
|
||||
|
||||
%0(8) = G_TRUNC s8 %x0
|
||||
%1(8) = G_TRUNC s8 %x1
|
||||
%0(8) = G_TRUNC { s8, s64 } %x0
|
||||
%1(8) = G_TRUNC { s8, s64 } %x1
|
||||
%2(8) = G_MUL s8 %0, %1
|
||||
%x0 = G_ANYEXTEND s64 %2
|
||||
%x0 = G_ANYEXT { s64, s8 } %2
|
||||
...
|
||||
|
@ -20,13 +20,13 @@ body: |
|
||||
bb.0.entry:
|
||||
liveins: %x0, %x1, %x2, %x3
|
||||
; CHECK-LABEL: name: test_scalar_or_small
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXTEND s32 %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXTEND s32 %1
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXT { s32, s8 } %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXT { s32, s8 } %1
|
||||
; CHECK: [[RES:%.*]](32) = G_OR s32 [[LHS]], [[RHS]]
|
||||
; CHECK: %2(8) = G_TRUNC s8 [[RES]]
|
||||
; CHECK: %2(8) = G_TRUNC { s8, s32 } [[RES]]
|
||||
|
||||
%0(8) = G_TRUNC s8 %x0
|
||||
%1(8) = G_TRUNC s8 %x1
|
||||
%0(8) = G_TRUNC { s8, s64 } %x0
|
||||
%1(8) = G_TRUNC { s8, s64 } %x1
|
||||
%2(8) = G_OR s8 %0, %1
|
||||
%x0 = G_ANYEXTEND s64 %2
|
||||
%x0 = G_ANYEXT { s64, s8 } %2
|
||||
...
|
||||
|
@ -30,7 +30,7 @@ body: |
|
||||
%1(64) = G_PTRTOINT { s64, p0 } %0
|
||||
%2(64) = G_INTTOPTR { p0, s64 } %1
|
||||
|
||||
; CHECK: [[TST32:%[0-9]+]](32) = G_ANYEXTEND s32 %3
|
||||
; CHECK: [[TST32:%[0-9]+]](32) = G_ANYEXT { s32, s1 } %3
|
||||
; CHECK: G_BRCOND s32 [[TST32]], %bb.1.next
|
||||
%3(1) = G_TRUNC { s1, s64 } %0
|
||||
G_BRCOND s1 %3, %bb.1.next
|
||||
|
@ -20,13 +20,13 @@ body: |
|
||||
bb.0.entry:
|
||||
liveins: %x0, %x1, %x2, %x3
|
||||
; CHECK-LABEL: name: test_scalar_sub_small
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXTEND s32 %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXTEND s32 %1
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXT { s32, s8 } %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXT { s32, s8 } %1
|
||||
; CHECK: [[RES:%.*]](32) = G_SUB s32 [[LHS]], [[RHS]]
|
||||
; CHECK: %2(8) = G_TRUNC s8 [[RES]]
|
||||
; CHECK: %2(8) = G_TRUNC { s8, s32 } [[RES]]
|
||||
|
||||
%0(8) = G_TRUNC s8 %x0
|
||||
%1(8) = G_TRUNC s8 %x1
|
||||
%0(8) = G_TRUNC { s8, s64 } %x0
|
||||
%1(8) = G_TRUNC { s8, s64 } %x1
|
||||
%2(8) = G_SUB s8 %0, %1
|
||||
%x0 = G_ANYEXTEND s64 %2
|
||||
%x0 = G_ANYEXT { s64, s8 } %2
|
||||
...
|
||||
|
@ -20,13 +20,13 @@ body: |
|
||||
bb.0.entry:
|
||||
liveins: %x0, %x1, %x2, %x3
|
||||
; CHECK-LABEL: name: test_scalar_xor_small
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXTEND s32 %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXTEND s32 %1
|
||||
; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXT { s32, s8 } %0
|
||||
; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXT { s32, s8 } %1
|
||||
; CHECK: [[RES:%.*]](32) = G_XOR s32 [[LHS]], [[RHS]]
|
||||
; CHECK: %2(8) = G_TRUNC s8 [[RES]]
|
||||
; CHECK: %2(8) = G_TRUNC { s8, s32 } [[RES]]
|
||||
|
||||
%0(8) = G_TRUNC s8 %x0
|
||||
%1(8) = G_TRUNC s8 %x1
|
||||
%0(8) = G_TRUNC { s8, s64 } %x0
|
||||
%1(8) = G_TRUNC { s8, s64 } %x1
|
||||
%2(8) = G_XOR s8 %0, %1
|
||||
%x0 = G_ANYEXTEND s64 %2
|
||||
%x0 = G_ANYEXT { s64, s8 } %2
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user