mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-27 13:40:30 +00:00
GlobalISel: disambiguate types when printing MIR
Some generic instructions have multiple types. While in theory these always be discovered by inspecting the single definition of each generic vreg, in practice those definitions won't always be local and traipsing through a big function to find them will not be fun. So this changes MIRPrinter to print out the type of uses as well as defs, if they're known to be different or not known to be the same. On the parsing side, we're a little more flexible: provided each register is given a type in at least one place it's mentioned (and all types are consistent) we accept the MIR. This doesn't introduce ambiguity but makes writing tests manually a bit less painful. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281204 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
217343a63a
commit
7a92e735b6
@ -877,7 +877,7 @@ bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
|
||||
|
||||
bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) {
|
||||
if (!consumeIfPresent(MIToken::kw_tied_def))
|
||||
return error("expected 'tied-def' after '('");
|
||||
return true;
|
||||
if (Token.isNot(MIToken::IntegerLiteral))
|
||||
return error("expected an integer literal after 'tied-def'");
|
||||
if (getUnsigned(TiedDefIdx))
|
||||
@ -957,16 +957,28 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest,
|
||||
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
return error("subregister index expects a virtual register");
|
||||
}
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
if ((Flags & RegState::Define) == 0) {
|
||||
if (consumeIfPresent(MIToken::lparen)) {
|
||||
unsigned Idx;
|
||||
if (parseRegisterTiedDefIndex(Idx))
|
||||
return true;
|
||||
TiedDefIdx = Idx;
|
||||
if (!parseRegisterTiedDefIndex(Idx))
|
||||
TiedDefIdx = Idx;
|
||||
else {
|
||||
// Try a redundant low-level type.
|
||||
LLT Ty;
|
||||
if (parseLowLevelType(Token.location(), Ty))
|
||||
return error("expected tied-def or low-level type after '('");
|
||||
|
||||
if (expectAndConsume(MIToken::rparen))
|
||||
return true;
|
||||
|
||||
if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
|
||||
return error("inconsistent type for generic virtual register");
|
||||
|
||||
MRI.setType(Reg, Ty);
|
||||
}
|
||||
}
|
||||
} else if (consumeIfPresent(MIToken::lparen)) {
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
|
||||
// Virtual registers may have a size with GlobalISel.
|
||||
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
return error("unexpected size on physical register");
|
||||
@ -980,6 +992,9 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest,
|
||||
if (expectAndConsume(MIToken::rparen))
|
||||
return true;
|
||||
|
||||
if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
|
||||
return error("inconsistent type for generic virtual register");
|
||||
|
||||
MRI.setType(Reg, Ty);
|
||||
} else if (PFS.GenericVRegs.count(Reg)) {
|
||||
// Generic virtual registers must have a size.
|
||||
|
@ -415,7 +415,7 @@ bool MIRParserImpl::initializeRegisterInfo(PerFunctionMIParsingState &PFS,
|
||||
if (StringRef(VReg.Class.Value).equals("_")) {
|
||||
// This is a generic virtual register.
|
||||
// The size will be set appropriately when we reach the definition.
|
||||
Reg = RegInfo.createGenericVirtualRegister(LLT::scalar(1));
|
||||
Reg = RegInfo.createGenericVirtualRegister(LLT{});
|
||||
PFS.GenericVRegs.insert(Reg);
|
||||
} else {
|
||||
const auto *RC = getRegClass(MF, VReg.Class.Value);
|
||||
@ -428,7 +428,7 @@ bool MIRParserImpl::initializeRegisterInfo(PerFunctionMIParsingState &PFS,
|
||||
VReg.Class.SourceRange.Start,
|
||||
Twine("use of undefined register class or register bank '") +
|
||||
VReg.Class.Value + "'");
|
||||
Reg = RegInfo.createGenericVirtualRegister(LLT::scalar(1));
|
||||
Reg = RegInfo.createGenericVirtualRegister(LLT{});
|
||||
RegInfo.setRegBank(Reg, *RegBank);
|
||||
PFS.GenericVRegs.insert(Reg);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "MIRPrinter.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
|
||||
#include "llvm/CodeGen/MIRYamlMapping.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
@ -123,7 +124,7 @@ public:
|
||||
void printTargetFlags(const MachineOperand &Op);
|
||||
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
|
||||
unsigned I, bool ShouldPrintRegisterTies,
|
||||
const MachineRegisterInfo *MRI = nullptr, bool IsDef = false);
|
||||
LLT TypeToPrint, bool IsDef = false);
|
||||
void print(const MachineMemOperand &Op);
|
||||
|
||||
void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
|
||||
@ -223,7 +224,7 @@ void MIRPrinter::convert(yaml::MachineFunction &MF,
|
||||
VReg.Class = StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower();
|
||||
else {
|
||||
VReg.Class = std::string("_");
|
||||
assert(RegInfo.getType(Reg).isValid() &&
|
||||
assert((RegInfo.def_empty(Reg) || RegInfo.getType(Reg).isValid()) &&
|
||||
"Generic registers must have a valid type");
|
||||
}
|
||||
unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
|
||||
@ -542,6 +543,27 @@ static bool hasComplexRegisterTies(const MachineInstr &MI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static LLT getTypeToPrint(const MachineInstr &MI, unsigned OpIdx,
|
||||
SmallBitVector &PrintedTypes,
|
||||
const MachineRegisterInfo &MRI) {
|
||||
const MachineOperand &Op = MI.getOperand(OpIdx);
|
||||
if (!Op.isReg())
|
||||
return LLT{};
|
||||
|
||||
if (MI.isVariadic() || OpIdx >= MI.getNumExplicitOperands())
|
||||
return MRI.getType(Op.getReg());
|
||||
|
||||
auto &OpInfo = MI.getDesc().OpInfo[OpIdx];
|
||||
if (!OpInfo.isGenericType())
|
||||
return MRI.getType(Op.getReg());
|
||||
|
||||
if (PrintedTypes[OpInfo.getGenericTypeIndex()])
|
||||
return LLT{};
|
||||
|
||||
PrintedTypes.set(OpInfo.getGenericTypeIndex());
|
||||
return MRI.getType(Op.getReg());
|
||||
}
|
||||
|
||||
void MIPrinter::print(const MachineInstr &MI) {
|
||||
const auto *MF = MI.getParent()->getParent();
|
||||
const auto &MRI = MF->getRegInfo();
|
||||
@ -553,6 +575,7 @@ void MIPrinter::print(const MachineInstr &MI) {
|
||||
if (MI.isCFIInstruction())
|
||||
assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
|
||||
|
||||
SmallBitVector PrintedTypes(8);
|
||||
bool ShouldPrintRegisterTies = hasComplexRegisterTies(MI);
|
||||
unsigned I = 0, E = MI.getNumOperands();
|
||||
for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
|
||||
@ -560,7 +583,8 @@ void MIPrinter::print(const MachineInstr &MI) {
|
||||
++I) {
|
||||
if (I)
|
||||
OS << ", ";
|
||||
print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, &MRI,
|
||||
print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies,
|
||||
getTypeToPrint(MI, I, PrintedTypes, MRI),
|
||||
/*IsDef=*/true);
|
||||
}
|
||||
|
||||
@ -576,7 +600,8 @@ void MIPrinter::print(const MachineInstr &MI) {
|
||||
for (; I < E; ++I) {
|
||||
if (NeedComma)
|
||||
OS << ", ";
|
||||
print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies);
|
||||
print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies,
|
||||
getTypeToPrint(MI, I, PrintedTypes, MRI));
|
||||
NeedComma = true;
|
||||
}
|
||||
|
||||
@ -748,8 +773,8 @@ static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
|
||||
}
|
||||
|
||||
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
|
||||
unsigned I, bool ShouldPrintRegisterTies,
|
||||
const MachineRegisterInfo *MRI, bool IsDef) {
|
||||
unsigned I, bool ShouldPrintRegisterTies, LLT TypeToPrint,
|
||||
bool IsDef) {
|
||||
printTargetFlags(Op);
|
||||
switch (Op.getType()) {
|
||||
case MachineOperand::MO_Register:
|
||||
@ -776,9 +801,8 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
|
||||
OS << '.' << TRI->getSubRegIndexName(Op.getSubReg());
|
||||
if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef())
|
||||
OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")";
|
||||
assert((!IsDef || MRI) && "for IsDef, MRI must be provided");
|
||||
if (IsDef && MRI->getType(Op.getReg()).isValid())
|
||||
OS << '(' << MRI->getType(Op.getReg()) << ')';
|
||||
if (TypeToPrint.isValid())
|
||||
OS << '(' << TypeToPrint << ')';
|
||||
break;
|
||||
case MachineOperand::MO_Immediate:
|
||||
OS << Op.getImm();
|
||||
|
@ -126,8 +126,6 @@ void MachineRegisterInfo::setType(unsigned VReg, LLT Ty) {
|
||||
|
||||
unsigned
|
||||
MachineRegisterInfo::createGenericVirtualRegister(LLT Ty) {
|
||||
assert(Ty.isValid() && "Cannot create empty virtual register");
|
||||
|
||||
// New virtual register number.
|
||||
unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs());
|
||||
VRegInfo.grow(Reg);
|
||||
|
@ -82,8 +82,8 @@ end:
|
||||
;
|
||||
; Check that we emit the correct branch.
|
||||
; CHECK: [[ADDR:%.*]](p0) = COPY %x0
|
||||
; CHECK: [[TST:%.*]](s1) = G_LOAD [[ADDR]]
|
||||
; CHECK: G_BRCOND [[TST]], %[[TRUE]]
|
||||
; CHECK: [[TST:%.*]](s1) = G_LOAD [[ADDR]](p0)
|
||||
; CHECK: G_BRCOND [[TST]](s1), %[[TRUE]]
|
||||
; CHECK: G_BR %[[FALSE]]
|
||||
;
|
||||
; Check that each successor contains the return instruction.
|
||||
@ -269,8 +269,8 @@ define void @trunc(i64 %a) {
|
||||
; CHECK-LABEL: name: load
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[ADDR42:%[0-9]+]](p42) = COPY %x1
|
||||
; CHECK: [[VAL1:%[0-9]+]](s64) = G_LOAD [[ADDR]] :: (load 8 from %ir.addr, align 16)
|
||||
; CHECK: [[VAL2:%[0-9]+]](s64) = G_LOAD [[ADDR42]] :: (load 8 from %ir.addr42)
|
||||
; CHECK: [[VAL1:%[0-9]+]](s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 16)
|
||||
; CHECK: [[VAL2:%[0-9]+]](s64) = G_LOAD [[ADDR42]](p42) :: (load 8 from %ir.addr42)
|
||||
; CHECK: [[SUM:%.*]](s64) = G_ADD [[VAL1]], [[VAL2]]
|
||||
; CHECK: %x0 = COPY [[SUM]]
|
||||
; CHECK: RET_ReallyLR implicit %x0
|
||||
@ -286,8 +286,8 @@ define i64 @load(i64* %addr, i64 addrspace(42)* %addr42) {
|
||||
; CHECK: [[ADDR42:%[0-9]+]](p42) = COPY %x1
|
||||
; CHECK: [[VAL1:%[0-9]+]](s64) = COPY %x2
|
||||
; CHECK: [[VAL2:%[0-9]+]](s64) = COPY %x3
|
||||
; CHECK: G_STORE [[VAL1]], [[ADDR]] :: (store 8 into %ir.addr, align 16)
|
||||
; CHECK: G_STORE [[VAL2]], [[ADDR42]] :: (store 8 into %ir.addr42)
|
||||
; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 16)
|
||||
; CHECK: G_STORE [[VAL2]](s64), [[ADDR42]](p42) :: (store 8 into %ir.addr42)
|
||||
; CHECK: RET_ReallyLR
|
||||
define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) {
|
||||
store i64 %val1, i64* %addr, align 16
|
||||
@ -302,7 +302,7 @@ define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2)
|
||||
; CHECK: [[PTR:%[0-9]+]](p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), 0
|
||||
; CHECK: [[PTR_VEC:%[0-9]+]](p0) = G_FRAME_INDEX %stack.0.ptr.vec
|
||||
; CHECK: [[VEC:%[0-9]+]](<8 x s8>) = G_LOAD [[PTR_VEC]]
|
||||
; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]], [[VEC]], [[PTR]]
|
||||
; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]](<8 x s8>), [[VEC]](<8 x s8>), [[PTR]](p0)
|
||||
; CHECK: RET_ReallyLR
|
||||
declare i8* @llvm.returnaddress(i32)
|
||||
declare void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8>, <8 x i8>, i8*)
|
||||
@ -325,7 +325,7 @@ define void @intrinsics(i32 %cur, i32 %bits) {
|
||||
; CHECK: [[FALSE]]:
|
||||
; CHECK: [[RES2:%[0-9]+]](s32) = G_LOAD
|
||||
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = PHI [[RES1]], %[[TRUE]], [[RES2]], %[[FALSE]]
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]]
|
||||
; CHECK: %w0 = COPY [[RES]]
|
||||
define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) {
|
||||
br i1 %tst, label %true, label %false
|
||||
@ -512,8 +512,8 @@ define i8* @test_constant_null() {
|
||||
|
||||
; CHECK-LABEL: name: test_struct_memops
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[VAL:%[0-9]+]](s64) = G_LOAD [[ADDR]] :: (load 8 from %ir.addr, align 4)
|
||||
; CHECK: G_STORE [[VAL]], [[ADDR]] :: (store 8 into %ir.addr, align 4)
|
||||
; CHECK: [[VAL:%[0-9]+]](s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 4)
|
||||
; CHECK: G_STORE [[VAL]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 4)
|
||||
define void @test_struct_memops({ i8, i32 }* %addr) {
|
||||
%val = load { i8, i32 }, { i8, i32 }* %addr
|
||||
store { i8, i32 } %val, { i8, i32 }* %addr
|
||||
@ -522,8 +522,8 @@ define void @test_struct_memops({ i8, i32 }* %addr) {
|
||||
|
||||
; CHECK-LABEL: name: test_i1_memops
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[VAL:%[0-9]+]](s1) = G_LOAD [[ADDR]] :: (load 1 from %ir.addr)
|
||||
; CHECK: G_STORE [[VAL]], [[ADDR]] :: (store 1 into %ir.addr)
|
||||
; CHECK: [[VAL:%[0-9]+]](s1) = G_LOAD [[ADDR]](p0) :: (load 1 from %ir.addr)
|
||||
; CHECK: G_STORE [[VAL]](s1), [[ADDR]](p0) :: (store 1 into %ir.addr)
|
||||
define void @test_i1_memops(i1* %addr) {
|
||||
%val = load i1, i1* %addr
|
||||
store i1 %val, i1* %addr
|
||||
@ -534,8 +534,8 @@ define void @test_i1_memops(i1* %addr) {
|
||||
; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w0
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = G_ICMP intpred(ne), [[LHS]], [[RHS]]
|
||||
; CHECK: G_STORE [[TST]], [[ADDR]]
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = G_ICMP intpred(ne), [[LHS]](s32), [[RHS]]
|
||||
; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
|
||||
define void @int_comparison(i32 %a, i32 %b, i1* %addr) {
|
||||
%res = icmp ne i32 %a, %b
|
||||
store i1 %res, i1* %addr
|
||||
@ -602,8 +602,8 @@ define float @test_frem(float %arg1, float %arg2) {
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_SADDO [[LHS]], [[RHS]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32
|
||||
; CHECK: G_STORE [[RES]], [[ADDR]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32
|
||||
; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0)
|
||||
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
|
||||
define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
|
||||
%res = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %lhs, i32 %rhs)
|
||||
@ -617,8 +617,8 @@ define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[ZERO:%[0-9]+]](s1) = G_CONSTANT 0
|
||||
; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_UADDE [[LHS]], [[RHS]], [[ZERO]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32
|
||||
; CHECK: G_STORE [[RES]], [[ADDR]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32
|
||||
; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0)
|
||||
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
|
||||
define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
|
||||
%res = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %lhs, i32 %rhs)
|
||||
@ -629,10 +629,10 @@ define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
|
||||
; CHECK-LABEL: name: test_ssub_overflow
|
||||
; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w0
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[SUBR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_SSUBO [[LHS]], [[RHS]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32
|
||||
; CHECK: G_STORE [[RES]], [[SUBR]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32
|
||||
; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0)
|
||||
declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
|
||||
define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
|
||||
%res = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %lhs, i32 %rhs)
|
||||
@ -643,11 +643,11 @@ define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
|
||||
; CHECK-LABEL: name: test_usub_overflow
|
||||
; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w0
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[SUBR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[ZERO:%[0-9]+]](s1) = G_CONSTANT 0
|
||||
; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_USUBE [[LHS]], [[RHS]], [[ZERO]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32
|
||||
; CHECK: G_STORE [[RES]], [[SUBR]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32
|
||||
; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0)
|
||||
declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
|
||||
define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
|
||||
%res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %lhs, i32 %rhs)
|
||||
@ -660,8 +660,8 @@ define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_SMULO [[LHS]], [[RHS]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32
|
||||
; CHECK: G_STORE [[RES]], [[ADDR]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32
|
||||
; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0)
|
||||
declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
|
||||
define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
|
||||
%res = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %lhs, i32 %rhs)
|
||||
@ -674,8 +674,8 @@ define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[VAL:%[0-9]+]](s32), [[OVERFLOW:%[0-9]+]](s1) = G_UMULO [[LHS]], [[RHS]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]], 0, [[OVERFLOW]], 32
|
||||
; CHECK: G_STORE [[RES]], [[ADDR]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_SEQUENCE [[VAL]](s32), 0, [[OVERFLOW]](s1), 32
|
||||
; CHECK: G_STORE [[RES]](s64), [[ADDR]](p0)
|
||||
declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
|
||||
define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
|
||||
%res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs)
|
||||
@ -685,7 +685,7 @@ define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
|
||||
|
||||
; CHECK-LABEL: name: test_extractvalue
|
||||
; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = G_EXTRACT [[STRUCT]], 64
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = G_EXTRACT [[STRUCT]](s128), 64
|
||||
; CHECK: %w0 = COPY [[RES]]
|
||||
%struct.nested = type {i8, { i8, i32 }, i32}
|
||||
define i32 @test_extractvalue(%struct.nested* %addr) {
|
||||
@ -696,7 +696,7 @@ define i32 @test_extractvalue(%struct.nested* %addr) {
|
||||
|
||||
; CHECK-LABEL: name: test_extractvalue_agg
|
||||
; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_EXTRACT [[STRUCT]], 32
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_EXTRACT [[STRUCT]](s128), 32
|
||||
; CHECK: G_STORE [[RES]]
|
||||
define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
|
||||
%struct = load %struct.nested, %struct.nested* %addr
|
||||
@ -708,8 +708,8 @@ define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
|
||||
; CHECK-LABEL: name: test_insertvalue
|
||||
; CHECK: [[VAL:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD
|
||||
; CHECK: [[NEWSTRUCT:%[0-9]+]](s128) = G_INSERT [[STRUCT]], [[VAL]], 64
|
||||
; CHECK: G_STORE [[NEWSTRUCT]],
|
||||
; CHECK: [[NEWSTRUCT:%[0-9]+]](s128) = G_INSERT [[STRUCT]](s128), [[VAL]](s32), 64
|
||||
; CHECK: G_STORE [[NEWSTRUCT]](s128),
|
||||
define void @test_insertvalue(%struct.nested* %addr, i32 %val) {
|
||||
%struct = load %struct.nested, %struct.nested* %addr
|
||||
%newstruct = insertvalue %struct.nested %struct, i32 %val, 1, 1
|
||||
@ -720,8 +720,8 @@ define void @test_insertvalue(%struct.nested* %addr, i32 %val) {
|
||||
; CHECK-LABEL: name: test_insertvalue_agg
|
||||
; CHECK: [[SMALLSTRUCT:%[0-9]+]](s64) = G_LOAD
|
||||
; CHECK: [[STRUCT:%[0-9]+]](s128) = G_LOAD
|
||||
; CHECK: [[RES:%[0-9]+]](s128) = G_INSERT [[STRUCT]], [[SMALLSTRUCT]], 32
|
||||
; CHECK: G_STORE [[RES]]
|
||||
; CHECK: [[RES:%[0-9]+]](s128) = G_INSERT [[STRUCT]](s128), [[SMALLSTRUCT]](s64), 32
|
||||
; CHECK: G_STORE [[RES]](s128)
|
||||
define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
|
||||
%smallstruct = load {i8, i32}, {i8, i32}* %addr2
|
||||
%struct = load %struct.nested, %struct.nested* %addr
|
||||
@ -734,7 +734,7 @@ define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = COPY %w0
|
||||
; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w2
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = G_SELECT [[TST]], [[LHS]], [[RHS]]
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
|
||||
; CHECK: %w0 = COPY [[RES]]
|
||||
define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
|
||||
%res = select i1 %tst, i32 %lhs, i32 %rhs
|
||||
@ -743,8 +743,8 @@ define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
|
||||
|
||||
; CHECK-LABEL: name: test_fptosi
|
||||
; CHECK: [[FPADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[FP:%[0-9]+]](s32) = G_LOAD [[FPADDR]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_FPTOSI [[FP]]
|
||||
; CHECK: [[FP:%[0-9]+]](s32) = G_LOAD [[FPADDR]](p0)
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_FPTOSI [[FP]](s32)
|
||||
; CHECK: %x0 = COPY [[RES]]
|
||||
define i64 @test_fptosi(float* %fp.addr) {
|
||||
%fp = load float, float* %fp.addr
|
||||
@ -754,8 +754,8 @@ define i64 @test_fptosi(float* %fp.addr) {
|
||||
|
||||
; CHECK-LABEL: name: test_fptoui
|
||||
; CHECK: [[FPADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[FP:%[0-9]+]](s32) = G_LOAD [[FPADDR]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_FPTOUI [[FP]]
|
||||
; CHECK: [[FP:%[0-9]+]](s32) = G_LOAD [[FPADDR]](p0)
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_FPTOUI [[FP]](s32)
|
||||
; CHECK: %x0 = COPY [[RES]]
|
||||
define i64 @test_fptoui(float* %fp.addr) {
|
||||
%fp = load float, float* %fp.addr
|
||||
@ -766,8 +766,8 @@ define i64 @test_fptoui(float* %fp.addr) {
|
||||
; CHECK-LABEL: name: test_sitofp
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[IN:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[FP:%[0-9]+]](s64) = G_SITOFP [[IN]]
|
||||
; CHECK: G_STORE [[FP]], [[ADDR]]
|
||||
; CHECK: [[FP:%[0-9]+]](s64) = G_SITOFP [[IN]](s32)
|
||||
; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
|
||||
define void @test_sitofp(double* %addr, i32 %in) {
|
||||
%fp = sitofp i32 %in to double
|
||||
store double %fp, double* %addr
|
||||
@ -777,8 +777,8 @@ define void @test_sitofp(double* %addr, i32 %in) {
|
||||
; CHECK-LABEL: name: test_uitofp
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[IN:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[FP:%[0-9]+]](s64) = G_UITOFP [[IN]]
|
||||
; CHECK: G_STORE [[FP]], [[ADDR]]
|
||||
; CHECK: [[FP:%[0-9]+]](s64) = G_UITOFP [[IN]](s32)
|
||||
; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
|
||||
define void @test_uitofp(double* %addr, i32 %in) {
|
||||
%fp = uitofp i32 %in to double
|
||||
store double %fp, double* %addr
|
||||
@ -787,7 +787,7 @@ define void @test_uitofp(double* %addr, i32 %in) {
|
||||
|
||||
; CHECK-LABEL: name: test_fpext
|
||||
; CHECK: [[IN:%[0-9]+]](s32) = COPY %s0
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_FPEXT [[IN]]
|
||||
; CHECK: [[RES:%[0-9]+]](s64) = G_FPEXT [[IN]](s32)
|
||||
; CHECK: %d0 = COPY [[RES]]
|
||||
define double @test_fpext(float %in) {
|
||||
%res = fpext float %in to double
|
||||
@ -796,7 +796,7 @@ define double @test_fpext(float %in) {
|
||||
|
||||
; CHECK-LABEL: name: test_fptrunc
|
||||
; CHECK: [[IN:%[0-9]+]](s64) = COPY %d0
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = G_FPTRUNC [[IN]]
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = G_FPTRUNC [[IN]](s64)
|
||||
; CHECK: %s0 = COPY [[RES]]
|
||||
define float @test_fptrunc(double %in) {
|
||||
%res = fptrunc double %in to float
|
||||
@ -806,7 +806,7 @@ define float @test_fptrunc(double %in) {
|
||||
; CHECK-LABEL: name: test_constant_float
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[TMP:%[0-9]+]](s32) = G_FCONSTANT float 1.500000e+00
|
||||
; CHECK: G_STORE [[TMP]], [[ADDR]]
|
||||
; CHECK: G_STORE [[TMP]](s32), [[ADDR]](p0)
|
||||
define void @test_constant_float(float* %addr) {
|
||||
store float 1.5, float* %addr
|
||||
ret void
|
||||
@ -816,10 +816,10 @@ define void @test_constant_float(float* %addr) {
|
||||
; CHECK: [[LHSADDR:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[RHSADDR:%[0-9]+]](p0) = COPY %x1
|
||||
; CHECK: [[BOOLADDR:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[LHS:%[0-9]+]](s32) = G_LOAD [[LHSADDR]]
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = G_LOAD [[RHSADDR]]
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = G_FCMP floatpred(oge), [[LHS]], [[RHS]]
|
||||
; CHECK: G_STORE [[TST]], [[BOOLADDR]]
|
||||
; CHECK: [[LHS:%[0-9]+]](s32) = G_LOAD [[LHSADDR]](p0)
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = G_LOAD [[RHSADDR]](p0)
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = G_FCMP floatpred(oge), [[LHS]](s32), [[RHS]]
|
||||
; CHECK: G_STORE [[TST]](s1), [[BOOLADDR]](p0)
|
||||
define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) {
|
||||
%a = load float, float* %a.addr
|
||||
%b = load float, float* %b.addr
|
||||
|
@ -32,7 +32,7 @@ define void @test_simple_arg(i32 %in) {
|
||||
|
||||
; CHECK-LABEL: name: test_indirect_call
|
||||
; CHECK: [[FUNC:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: BLR [[FUNC]], csr_aarch64_aapcs, implicit-def %lr, implicit %sp
|
||||
; CHECK: BLR [[FUNC]](p0), csr_aarch64_aapcs, implicit-def %lr, implicit %sp
|
||||
; CHECK: RET_ReallyLR
|
||||
define void @test_indirect_call(void()* %func) {
|
||||
call void %func()
|
||||
|
@ -30,11 +30,11 @@ body: |
|
||||
%2(s8) = G_TRUNC %0
|
||||
%3(s8) = G_TRUNC %1
|
||||
|
||||
; CHECK: %4(s1) = G_ICMP intpred(sge), %0, %1
|
||||
; CHECK: %4(s1) = G_ICMP intpred(sge), %0(s64), %1
|
||||
%4(s1) = G_ICMP intpred(sge), %0, %1
|
||||
|
||||
; CHECK: [[LHS32:%[0-9]+]](s32) = G_ZEXT %2
|
||||
; CHECK: [[RHS32:%[0-9]+]](s32) = G_ZEXT %3
|
||||
; CHECK: %8(s1) = G_ICMP intpred(ult), [[LHS32]], [[RHS32]]
|
||||
; CHECK: %8(s1) = G_ICMP intpred(ult), [[LHS32]](s32), [[RHS32]]
|
||||
%8(s1) = G_ICMP intpred(ult), %2, %3
|
||||
...
|
||||
|
@ -48,11 +48,11 @@ body: |
|
||||
; Only one of these extracts can be eliminated, the offsets don't match
|
||||
; properly in the other cases.
|
||||
; CHECK-LABEL: name: test_combines
|
||||
; CHECK: %3(s32) = G_SEQUENCE %2, 1
|
||||
; CHECK: %4(s8) = G_EXTRACT %3, 0
|
||||
; CHECK: %3(s32) = G_SEQUENCE %2(s8), 1
|
||||
; CHECK: %4(s8) = G_EXTRACT %3(s32), 0
|
||||
; CHECK-NOT: G_EXTRACT
|
||||
; CHECK: %6(s8) = G_EXTRACT %3, 2
|
||||
; CHECK: %7(s32) = G_ZEXT %2
|
||||
; CHECK: %6(s8) = G_EXTRACT %3(s32), 2
|
||||
; CHECK: %7(s32) = G_ZEXT %2(s8)
|
||||
%3(s32) = G_SEQUENCE %2, 1
|
||||
%4(s8) = G_EXTRACT %3, 0
|
||||
%5(s8) = G_EXTRACT %3, 1
|
||||
@ -60,9 +60,9 @@ body: |
|
||||
%7(s32) = G_ZEXT %5
|
||||
|
||||
; Similarly, here the types don't match.
|
||||
; CHECK: %10(s32) = G_SEQUENCE %8, 0, %9, 16
|
||||
; CHECK: %11(s1) = G_EXTRACT %10, 0
|
||||
; CHECK: %12(s32) = G_EXTRACT %10, 0
|
||||
; CHECK: %10(s32) = G_SEQUENCE %8(s16), 0, %9(s16), 16
|
||||
; CHECK: %11(s1) = G_EXTRACT %10(s32), 0
|
||||
; CHECK: %12(s32) = G_EXTRACT %10(s32), 0
|
||||
%8(s16) = G_TRUNC %0
|
||||
%9(s16) = G_ADD %8, %8
|
||||
%10(s32) = G_SEQUENCE %8, 0, %9, 16
|
||||
@ -74,7 +74,7 @@ body: |
|
||||
%13(s16), %14(s16) = G_EXTRACT %10, 0, 16
|
||||
%15(s16) = G_ADD %13, %14
|
||||
|
||||
; CHECK: %18(<2 x s32>) = G_EXTRACT %17, 0
|
||||
; CHECK: %18(<2 x s32>) = G_EXTRACT %17(s128), 0
|
||||
; CHECK: %19(<2 x s32>) = G_ADD %18, %18
|
||||
%16(s64) = COPY %x0
|
||||
%17(s128) = G_SEQUENCE %16, 0, %16, 64
|
||||
|
@ -27,9 +27,9 @@ body: |
|
||||
%2(s32) = G_TRUNC %0
|
||||
%3(s32) = G_TRUNC %1
|
||||
|
||||
; CHECK: %4(s1) = G_FCMP floatpred(oge), %0, %1
|
||||
; CHECK: %4(s1) = G_FCMP floatpred(oge), %0(s64), %1
|
||||
%4(s1) = G_FCMP floatpred(oge), %0, %1
|
||||
|
||||
; CHECK: %5(s1) = G_FCMP floatpred(uno), %2, %3
|
||||
; CHECK: %5(s1) = G_FCMP floatpred(uno), %2(s32), %3
|
||||
%5(s1) = G_FCMP floatpred(uno), %2, %3
|
||||
...
|
||||
|
@ -28,20 +28,20 @@ body: |
|
||||
; CHECK-LABEL: name: test_load
|
||||
%0(p0) = COPY %x0
|
||||
|
||||
; CHECK: [[BIT8:%[0-9]+]](s8) = G_LOAD %0 :: (load 1 from %ir.addr)
|
||||
; CHECK: [[BIT8:%[0-9]+]](s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr)
|
||||
; CHECK: %1(s1) = G_TRUNC [[BIT8]]
|
||||
%1(s1) = G_LOAD %0 :: (load 1 from %ir.addr)
|
||||
|
||||
; CHECK: %2(s8) = G_LOAD %0 :: (load 1 from %ir.addr)
|
||||
; CHECK: %2(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr)
|
||||
%2(s8) = G_LOAD %0 :: (load 1 from %ir.addr)
|
||||
|
||||
; CHECK: %3(s16) = G_LOAD %0 :: (load 2 from %ir.addr)
|
||||
; CHECK: %3(s16) = G_LOAD %0(p0) :: (load 2 from %ir.addr)
|
||||
%3(s16) = G_LOAD %0 :: (load 2 from %ir.addr)
|
||||
|
||||
; CHECK: %4(s32) = G_LOAD %0 :: (load 4 from %ir.addr)
|
||||
; CHECK: %4(s32) = G_LOAD %0(p0) :: (load 4 from %ir.addr)
|
||||
%4(s32) = G_LOAD %0 :: (load 4 from %ir.addr)
|
||||
|
||||
; CHECK: %5(s64) = G_LOAD %0 :: (load 8 from %ir.addr)
|
||||
; CHECK: %5(s64) = G_LOAD %0(p0) :: (load 8 from %ir.addr)
|
||||
%5(s64) = G_LOAD %0 :: (load 8 from %ir.addr)
|
||||
...
|
||||
|
||||
@ -62,23 +62,23 @@ body: |
|
||||
%0(p0) = COPY %x0
|
||||
%1(s32) = COPY %w1
|
||||
|
||||
; CHECK: [[BIT8:%[0-9]+]](s8) = G_ANYEXT %2
|
||||
; CHECK: G_STORE [[BIT8]], %0 :: (store 1 into %ir.addr)
|
||||
; CHECK: [[BIT8:%[0-9]+]](s8) = G_ANYEXT %2(s1)
|
||||
; CHECK: G_STORE [[BIT8]](s8), %0(p0) :: (store 1 into %ir.addr)
|
||||
%2(s1) = G_TRUNC %1
|
||||
G_STORE %2, %0 :: (store 1 into %ir.addr)
|
||||
|
||||
; CHECK: G_STORE %3, %0 :: (store 1 into %ir.addr)
|
||||
; CHECK: G_STORE %3(s8), %0(p0) :: (store 1 into %ir.addr)
|
||||
%3(s8) = G_TRUNC %1
|
||||
G_STORE %3, %0 :: (store 1 into %ir.addr)
|
||||
|
||||
; CHECK: G_STORE %4, %0 :: (store 2 into %ir.addr)
|
||||
; CHECK: G_STORE %4(s16), %0(p0) :: (store 2 into %ir.addr)
|
||||
%4(s16) = G_TRUNC %1
|
||||
G_STORE %4, %0 :: (store 2 into %ir.addr)
|
||||
|
||||
; CHECK: G_STORE %1, %0 :: (store 4 into %ir.addr)
|
||||
; CHECK: G_STORE %1(s32), %0(p0) :: (store 4 into %ir.addr)
|
||||
G_STORE %1, %0 :: (store 4 into %ir.addr)
|
||||
|
||||
; CHECK: G_STORE %5, %0 :: (store 8 into %ir.addr)
|
||||
%5(s64) = G_PTRTOINT %0
|
||||
; CHECK: G_STORE %5(s64), %0(p0) :: (store 8 into %ir.addr)
|
||||
%5(s64) = G_PTRTOINT %0(p0)
|
||||
G_STORE %5, %0 :: (store 8 into %ir.addr)
|
||||
...
|
||||
|
@ -56,7 +56,7 @@ body: |
|
||||
%2(s64) = G_PTRTOINT %1
|
||||
|
||||
; CHECK: [[TST32:%[0-9]+]](s32) = G_ANYEXT %3
|
||||
; CHECK: G_BRCOND [[TST32]], %bb.1.next
|
||||
; CHECK: G_BRCOND [[TST32]](s32), %bb.1.next
|
||||
%3(s1) = G_TRUNC %0
|
||||
G_BRCOND %3, %bb.1.next
|
||||
|
||||
@ -107,11 +107,11 @@ body: |
|
||||
%23(s64) = G_UITOFP %4
|
||||
%24(s64) = G_SITOFP %0
|
||||
|
||||
; CHECK: %25(s1) = G_SELECT %10, %10, %5
|
||||
; CHECK: %26(s8) = G_SELECT %10, %6, %11
|
||||
; CHECK: %27(s16) = G_SELECT %10, %12, %7
|
||||
; CHECK: %28(s32) = G_SELECT %10, %15, %16
|
||||
; CHECK: %29(s64) = G_SELECT %10, %9, %24
|
||||
; CHECK: %25(s1) = G_SELECT %10(s1), %10, %5
|
||||
; CHECK: %26(s8) = G_SELECT %10(s1), %6, %11
|
||||
; CHECK: %27(s16) = G_SELECT %10(s1), %12, %7
|
||||
; CHECK: %28(s32) = G_SELECT %10(s1), %15, %16
|
||||
; CHECK: %29(s64) = G_SELECT %10(s1), %9, %24
|
||||
%25(s1) = G_SELECT %10, %10, %5
|
||||
%26(s8) = G_SELECT %10, %6, %11
|
||||
%27(s16) = G_SELECT %10, %12, %7
|
||||
|
@ -17,7 +17,7 @@ body: |
|
||||
bb.0.entry:
|
||||
liveins: %rdi
|
||||
|
||||
; CHECK: [[@LINE+1]]:78: expected an integer literal after 'tied-def'
|
||||
; CHECK: [[@LINE+1]]:78: expected tied-def or low-level type after '('
|
||||
INLINEASM $"$foo", 1, 2818058, def %rdi, 2147483657, killed %rdi(tied-def)
|
||||
%rax = COPY killed %rdi
|
||||
RETQ killed %rax
|
||||
|
@ -17,7 +17,7 @@ body: |
|
||||
bb.0.entry:
|
||||
liveins: %rdi
|
||||
|
||||
; CHECK: [[@LINE+1]]:70: expected 'tied-def' after '('
|
||||
; CHECK: [[@LINE+1]]:70: expected tied-def or low-level type after '('
|
||||
INLINEASM $"$foo", 1, 2818058, def %rdi, 2147483657, killed %rdi(3)
|
||||
%rax = COPY killed %rdi
|
||||
RETQ killed %rax
|
||||
|
Loading…
Reference in New Issue
Block a user