forked from OSchip/llvm-project
[GISel]: Fix generation of illegal COPYs during CallLowering
We end up creating COPY's that are either truncating/extending and this should be illegal. https://reviews.llvm.org/D37640 Patch for X86 and ARM by igorb, rovka llvm-svn: 315240
This commit is contained in:
parent
4d62ca3ae9
commit
c3bfc81a1f
|
@ -160,10 +160,11 @@ unsigned CallLowering::ValueHandler::extendRegister(unsigned ValReg,
|
|||
// FIXME: bitconverting between vector types may or may not be a
|
||||
// nop in big-endian situations.
|
||||
return ValReg;
|
||||
case CCValAssign::AExt:
|
||||
case CCValAssign::AExt: {
|
||||
assert(!VA.getLocVT().isVector() && "unexpected vector extend");
|
||||
// Otherwise, it's a nop.
|
||||
return ValReg;
|
||||
auto MIB = MIRBuilder.buildAnyExt(LocTy, ValReg);
|
||||
return MIB->getOperand(0).getReg();
|
||||
}
|
||||
case CCValAssign::SExt: {
|
||||
unsigned NewReg = MRI.createGenericVirtualRegister(LocTy);
|
||||
MIRBuilder.buildSExt(NewReg, ValReg);
|
||||
|
|
|
@ -70,8 +70,18 @@ struct IncomingArgHandler : public CallLowering::ValueHandler {
|
|||
void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
|
||||
CCValAssign &VA) override {
|
||||
markPhysRegUsed(PhysReg);
|
||||
MIRBuilder.buildCopy(ValVReg, PhysReg);
|
||||
// FIXME: assert extension
|
||||
switch (VA.getLocInfo()) {
|
||||
default:
|
||||
MIRBuilder.buildCopy(ValVReg, PhysReg);
|
||||
break;
|
||||
case CCValAssign::LocInfo::SExt:
|
||||
case CCValAssign::LocInfo::ZExt:
|
||||
case CCValAssign::LocInfo::AExt: {
|
||||
auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
|
||||
MIRBuilder.buildTrunc(ValVReg, Copy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
|
||||
|
|
|
@ -343,13 +343,26 @@ struct IncomingValueHandler : public CallLowering::ValueHandler {
|
|||
assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
|
||||
assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
|
||||
|
||||
assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
|
||||
assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
|
||||
auto ValSize = VA.getValVT().getSizeInBits();
|
||||
auto LocSize = VA.getLocVT().getSizeInBits();
|
||||
|
||||
assert(ValSize <= 64 && "Unsupported value size");
|
||||
assert(LocSize <= 64 && "Unsupported location size");
|
||||
|
||||
// The necessary extensions are handled on the other side of the ABI
|
||||
// boundary.
|
||||
markPhysRegUsed(PhysReg);
|
||||
MIRBuilder.buildCopy(ValVReg, PhysReg);
|
||||
if (ValSize == LocSize) {
|
||||
MIRBuilder.buildCopy(ValVReg, PhysReg);
|
||||
} else {
|
||||
assert(ValSize < LocSize && "Extensions not supported");
|
||||
|
||||
// We cannot create a truncating copy, nor a trunc of a physical register.
|
||||
// Therefore, we need to copy the content of the physical register into a
|
||||
// virtual one and then truncate that.
|
||||
auto PhysRegToVReg =
|
||||
MRI.createGenericVirtualRegister(LLT::scalar(LocSize));
|
||||
MIRBuilder.buildCopy(PhysRegToVReg, PhysReg);
|
||||
MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
|
||||
|
|
|
@ -226,6 +226,28 @@ struct IncomingValueHandler : public CallLowering::ValueHandler {
|
|||
MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
|
||||
}
|
||||
|
||||
void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
|
||||
CCValAssign &VA) override {
|
||||
markPhysRegUsed(PhysReg);
|
||||
switch (VA.getLocInfo()) {
|
||||
default:
|
||||
MIRBuilder.buildCopy(ValVReg, PhysReg);
|
||||
break;
|
||||
case CCValAssign::LocInfo::SExt:
|
||||
case CCValAssign::LocInfo::ZExt:
|
||||
case CCValAssign::LocInfo::AExt: {
|
||||
auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
|
||||
MIRBuilder.buildTrunc(ValVReg, Copy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// How the physical register gets marked varies between formal
|
||||
/// parameters (it's a basic-block live-in), and a call instruction
|
||||
/// (it's an implicit-def of the BL).
|
||||
virtual void markPhysRegUsed(unsigned PhysReg) = 0;
|
||||
|
||||
protected:
|
||||
const DataLayout &DL;
|
||||
};
|
||||
|
@ -235,10 +257,8 @@ struct FormalArgHandler : public IncomingValueHandler {
|
|||
CCAssignFn *AssignFn)
|
||||
: IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
|
||||
|
||||
void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
|
||||
CCValAssign &VA) override {
|
||||
void markPhysRegUsed(unsigned PhysReg) override {
|
||||
MIRBuilder.getMBB().addLiveIn(PhysReg);
|
||||
MIRBuilder.buildCopy(ValVReg, PhysReg);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -247,10 +267,8 @@ struct CallReturnHandler : public IncomingValueHandler {
|
|||
CCAssignFn *AssignFn, MachineInstrBuilder &MIB)
|
||||
: IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
|
||||
|
||||
void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
|
||||
CCValAssign &VA) override {
|
||||
void markPhysRegUsed(unsigned PhysReg) override {
|
||||
MIB.addDef(PhysReg, RegState::Implicit);
|
||||
MIRBuilder.buildCopy(ValVReg, PhysReg);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -70,8 +70,10 @@ define [1 x double] @args_arr([1 x double] %d0) {
|
|||
; CHECK: %w0 = COPY [[ANSWER]]
|
||||
; CHECK: %d0 = COPY [[D_ONE]]
|
||||
; CHECK: %x1 = COPY [[TWELVE]]
|
||||
; CHECK: %w2 = COPY [[THREE]](s8)
|
||||
; CHECK: %w3 = COPY [[ONE]](s16)
|
||||
; CHECK: [[THREE_TMP:%[0-9]+]](s32) = G_ANYEXT [[THREE]]
|
||||
; CHECK: %w2 = COPY [[THREE_TMP]](s32)
|
||||
; CHECK: [[ONE_TMP:%[0-9]+]](s32) = G_ANYEXT [[ONE]]
|
||||
; CHECK: %w3 = COPY [[ONE_TMP]](s32)
|
||||
; CHECK: %w4 = COPY [[FOUR]](s32)
|
||||
; CHECK: %s1 = COPY [[F_ONE]](s32)
|
||||
; CHECK: %d2 = COPY [[TWO]](s64)
|
||||
|
|
|
@ -43,7 +43,7 @@ define [1 x double] @constant() {
|
|||
; The key problem here is that we may fail to create an MBB referenced by a
|
||||
; PHI. If so, we cannot complete the G_PHI and mustn't try or bad things
|
||||
; happen.
|
||||
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: G_STORE %vreg5, %vreg2; mem:ST4[%addr] GPR:%vreg5,%vreg2 (in function: pending_phis)
|
||||
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: cannot select: G_STORE %vreg6, %vreg2; mem:ST4[%addr] GPR:%vreg6,%vreg2 (in function: pending_phis)
|
||||
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for pending_phis
|
||||
; FALLBACK-WITH-REPORT-OUT-LABEL: pending_phis:
|
||||
define i32 @pending_phis(i1 %tst, i32 %val, i32* %addr) {
|
||||
|
|
|
@ -971,7 +971,8 @@ define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
|
|||
}
|
||||
|
||||
; CHECK-LABEL: name: test_select
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = COPY %w0
|
||||
; CHECK: [[TST_C:%[0-9]+]](s32) = COPY %w0
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = G_TRUNC [[TST_C]]
|
||||
; CHECK: [[LHS:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[RHS:%[0-9]+]](s32) = COPY %w2
|
||||
; CHECK: [[RES:%[0-9]+]](s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
|
||||
|
@ -982,7 +983,8 @@ define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
|
|||
}
|
||||
|
||||
; CHECK-LABEL: name: test_select_ptr
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = COPY %w0
|
||||
; CHECK: [[TST_C:%[0-9]+]](s32) = COPY %w0
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = G_TRUNC [[TST_C]]
|
||||
; CHECK: [[LHS:%[0-9]+]](p0) = COPY %x1
|
||||
; CHECK: [[RHS:%[0-9]+]](p0) = COPY %x2
|
||||
; CHECK: [[RES:%[0-9]+]](p0) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
|
||||
|
@ -993,7 +995,8 @@ define i8* @test_select_ptr(i1 %tst, i8* %lhs, i8* %rhs) {
|
|||
}
|
||||
|
||||
; CHECK-LABEL: name: test_select_vec
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = COPY %w0
|
||||
; CHECK: [[TST_C:%[0-9]+]](s32) = COPY %w0
|
||||
; CHECK: [[TST:%[0-9]+]](s1) = G_TRUNC [[TST_C]]
|
||||
; CHECK: [[LHS:%[0-9]+]](<4 x s32>) = COPY %q0
|
||||
; CHECK: [[RHS:%[0-9]+]](<4 x s32>) = COPY %q1
|
||||
; CHECK: [[RES:%[0-9]+]](<4 x s32>) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
|
||||
|
@ -1176,10 +1179,12 @@ declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i32 %align, i1 %volatile)
|
|||
define void @test_memset(i8* %dst, i8 %val, i64 %size) {
|
||||
; CHECK-LABEL: name: test_memset
|
||||
; CHECK: [[DST:%[0-9]+]](p0) = COPY %x0
|
||||
; CHECK: [[SRC:%[0-9]+]](s8) = COPY %w1
|
||||
; CHECK: [[SRC_C:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[SRC:%[0-9]+]](s8) = G_TRUNC [[SRC_C]]
|
||||
; CHECK: [[SIZE:%[0-9]+]](s64) = COPY %x2
|
||||
; CHECK: %x0 = COPY [[DST]]
|
||||
; CHECK: %w1 = COPY [[SRC]]
|
||||
; CHECK: [[SRC_TMP:%[0-9]+]](s32) = G_ANYEXT [[SRC]]
|
||||
; CHECK: %w1 = COPY [[SRC_TMP]]
|
||||
; CHECK: %x2 = COPY [[SIZE]]
|
||||
; CHECK: BL $memset, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %x0, implicit %w1, implicit %x2
|
||||
call void @llvm.memset.p0i8.i64(i8* %dst, i8 %val, i64 %size, i32 1, i1 0)
|
||||
|
|
|
@ -61,7 +61,8 @@ define void @test_multiple_args(i64 %in) {
|
|||
; CHECK-LABEL: name: test_struct_formal
|
||||
; CHECK: [[DBL:%[0-9]+]](s64) = COPY %d0
|
||||
; CHECK: [[I64:%[0-9]+]](s64) = COPY %x0
|
||||
; CHECK: [[I8:%[0-9]+]](s8) = COPY %w1
|
||||
; CHECK: [[I8_C:%[0-9]+]](s32) = COPY %w1
|
||||
; CHECK: [[I8:%[0-9]+]](s8) = G_TRUNC [[I8_C]]
|
||||
; CHECK: [[ADDR:%[0-9]+]](p0) = COPY %x2
|
||||
|
||||
; CHECK: [[UNDEF:%[0-9]+]](s192) = G_IMPLICIT_DEF
|
||||
|
@ -126,7 +127,8 @@ define i64 @test_arr_call([4 x i64]* %addr) {
|
|||
|
||||
; CHECK-LABEL: name: test_abi_exts_call
|
||||
; CHECK: [[VAL:%[0-9]+]](s8) = G_LOAD
|
||||
; CHECK: %w0 = COPY [[VAL]]
|
||||
; CHECK: [[VAL_TMP:%[0-9]+]](s32) = G_ANYEXT [[VAL]]
|
||||
; CHECK: %w0 = COPY [[VAL_TMP]]
|
||||
; CHECK: BL @take_char, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %w0
|
||||
; CHECK: [[SVAL:%[0-9]+]](s32) = G_SEXT [[VAL]](s8)
|
||||
; CHECK: %w0 = COPY [[SVAL]](s32)
|
||||
|
|
|
@ -11,8 +11,10 @@ entry:
|
|||
define signext i1 @test_add_i1(i1 %x, i1 %y) {
|
||||
; CHECK-LABEL: name: test_add_i1
|
||||
; CHECK: liveins: %r0, %r1
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s1) = COPY %r0
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s1) = COPY %r1
|
||||
; CHECK-DAG: [[VREGR0:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s1) = G_TRUNC [[VREGR0]]
|
||||
; CHECK-DAG: [[VREGR1:%[0-9]+]](s32) = COPY %r1
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s1) = G_TRUNC [[VREGR1]]
|
||||
; CHECK: [[SUM:%[0-9]+]](s1) = G_ADD [[VREGX]], [[VREGY]]
|
||||
; CHECK: [[EXT:%[0-9]+]](s32) = G_SEXT [[SUM]]
|
||||
; CHECK: %r0 = COPY [[EXT]](s32)
|
||||
|
@ -25,10 +27,13 @@ entry:
|
|||
define i8 @test_add_i8(i8 %x, i8 %y) {
|
||||
; CHECK-LABEL: name: test_add_i8
|
||||
; CHECK: liveins: %r0, %r1
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s8) = COPY %r0
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s8) = COPY %r1
|
||||
; CHECK-DAG: [[VREGR0:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s8) = G_TRUNC [[VREGR0]]
|
||||
; CHECK-DAG: [[VREGR1:%[0-9]+]](s32) = COPY %r1
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s8) = G_TRUNC [[VREGR1]]
|
||||
; CHECK: [[SUM:%[0-9]+]](s8) = G_ADD [[VREGX]], [[VREGY]]
|
||||
; CHECK: %r0 = COPY [[SUM]](s8)
|
||||
; CHECK: [[SUM_EXT:%[0-9]+]](s32) = G_ANYEXT [[SUM]]
|
||||
; CHECK: %r0 = COPY [[SUM_EXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
entry:
|
||||
%sum = add i8 %x, %y
|
||||
|
@ -38,10 +43,13 @@ entry:
|
|||
define i8 @test_sub_i8(i8 %x, i8 %y) {
|
||||
; CHECK-LABEL: name: test_sub_i8
|
||||
; CHECK: liveins: %r0, %r1
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s8) = COPY %r0
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s8) = COPY %r1
|
||||
; CHECK-DAG: [[VREGR0:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s8) = G_TRUNC [[VREGR0]]
|
||||
; CHECK-DAG: [[VREGR1:%[0-9]+]](s32) = COPY %r1
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s8) = G_TRUNC [[VREGR1]]
|
||||
; CHECK: [[RES:%[0-9]+]](s8) = G_SUB [[VREGX]], [[VREGY]]
|
||||
; CHECK: %r0 = COPY [[RES]](s8)
|
||||
; CHECK: [[RES_EXT:%[0-9]+]](s32) = G_ANYEXT [[RES]]
|
||||
; CHECK: %r0 = COPY [[RES_EXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
entry:
|
||||
%res = sub i8 %x, %y
|
||||
|
@ -51,7 +59,8 @@ entry:
|
|||
define signext i8 @test_return_sext_i8(i8 %x) {
|
||||
; CHECK-LABEL: name: test_return_sext_i8
|
||||
; CHECK: liveins: %r0
|
||||
; CHECK: [[VREG:%[0-9]+]](s8) = COPY %r0
|
||||
; CHECK: [[VREGR0:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK: [[VREG:%[0-9]+]](s8) = G_TRUNC [[VREGR0]]
|
||||
; CHECK: [[VREGEXT:%[0-9]+]](s32) = G_SEXT [[VREG]]
|
||||
; CHECK: %r0 = COPY [[VREGEXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
|
@ -62,10 +71,13 @@ entry:
|
|||
define i16 @test_add_i16(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: name: test_add_i16
|
||||
; CHECK: liveins: %r0, %r1
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s16) = COPY %r0
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s16) = COPY %r1
|
||||
; CHECK-DAG: [[VREGR0:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s16) = G_TRUNC [[VREGR0]]
|
||||
; CHECK-DAG: [[VREGR1:%[0-9]+]](s32) = COPY %r1
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s16) = G_TRUNC [[VREGR1]]
|
||||
; CHECK: [[SUM:%[0-9]+]](s16) = G_ADD [[VREGX]], [[VREGY]]
|
||||
; CHECK: %r0 = COPY [[SUM]](s16)
|
||||
; CHECK: [[SUM_EXT:%[0-9]+]](s32) = G_ANYEXT [[SUM]]
|
||||
; CHECK: %r0 = COPY [[SUM_EXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
entry:
|
||||
%sum = add i16 %x, %y
|
||||
|
@ -75,10 +87,13 @@ entry:
|
|||
define i16 @test_sub_i16(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: name: test_sub_i16
|
||||
; CHECK: liveins: %r0, %r1
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s16) = COPY %r0
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s16) = COPY %r1
|
||||
; CHECK-DAG: [[VREGR0:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK-DAG: [[VREGX:%[0-9]+]](s16) = G_TRUNC [[VREGR0]]
|
||||
; CHECK-DAG: [[VREGR1:%[0-9]+]](s32) = COPY %r1
|
||||
; CHECK-DAG: [[VREGY:%[0-9]+]](s16) = G_TRUNC [[VREGR1]]
|
||||
; CHECK: [[RES:%[0-9]+]](s16) = G_SUB [[VREGX]], [[VREGY]]
|
||||
; CHECK: %r0 = COPY [[RES]](s16)
|
||||
; CHECK: [[RES_EXT:%[0-9]+]](s32) = G_ANYEXT [[RES]]
|
||||
; CHECK: %r0 = COPY [[RES_EXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
entry:
|
||||
%res = sub i16 %x, %y
|
||||
|
@ -88,7 +103,8 @@ entry:
|
|||
define zeroext i16 @test_return_zext_i16(i16 %x) {
|
||||
; CHECK-LABEL: name: test_return_zext_i16
|
||||
; CHECK: liveins: %r0
|
||||
; CHECK: [[VREG:%[0-9]+]](s16) = COPY %r0
|
||||
; CHECK: [[VREGR0:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK: [[VREG:%[0-9]+]](s16) = G_TRUNC [[VREGR0]]
|
||||
; CHECK: [[VREGEXT:%[0-9]+]](s32) = G_ZEXT [[VREG]]
|
||||
; CHECK: %r0 = COPY [[VREGEXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
|
@ -146,12 +162,14 @@ define i16 @test_stack_args_signext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
|
|||
; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
|
||||
; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
|
||||
; CHECK: liveins: %r0, %r1, %r2, %r3
|
||||
; CHECK: [[VREGP1:%[0-9]+]](s16) = COPY %r1
|
||||
; CHECK: [[VREGR1:%[0-9]+]](s32) = COPY %r1
|
||||
; CHECK: [[VREGP1:%[0-9]+]](s16) = G_TRUNC [[VREGR1]]
|
||||
; CHECK: [[FIP5:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
|
||||
; CHECK: [[VREGP5EXT:%[0-9]+]](s32) = G_LOAD [[FIP5]](p0){{.*}}load 4
|
||||
; CHECK: [[VREGP5:%[0-9]+]](s16) = G_TRUNC [[VREGP5EXT]]
|
||||
; CHECK: [[SUM:%[0-9]+]](s16) = G_ADD [[VREGP1]], [[VREGP5]]
|
||||
; CHECK: %r0 = COPY [[SUM]]
|
||||
; CHECK: [[SUM_EXT:%[0-9]+]](s32) = G_ANYEXT [[SUM]]
|
||||
; CHECK: %r0 = COPY [[SUM_EXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
entry:
|
||||
%sum = add i16 %p1, %p5
|
||||
|
@ -165,12 +183,14 @@ define i8 @test_stack_args_zeroext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
|
|||
; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
|
||||
; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
|
||||
; CHECK: liveins: %r0, %r1, %r2, %r3
|
||||
; CHECK: [[VREGP2:%[0-9]+]](s8) = COPY %r2
|
||||
; CHECK: [[VREGR2:%[0-9]+]](s32) = COPY %r2
|
||||
; CHECK: [[VREGP2:%[0-9]+]](s8) = G_TRUNC [[VREGR2]]
|
||||
; CHECK: [[FIP4:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[P4]]
|
||||
; CHECK: [[VREGP4EXT:%[0-9]+]](s32) = G_LOAD [[FIP4]](p0){{.*}}load 4
|
||||
; CHECK: [[VREGP4:%[0-9]+]](s8) = G_TRUNC [[VREGP4EXT]]
|
||||
; CHECK: [[SUM:%[0-9]+]](s8) = G_ADD [[VREGP2]], [[VREGP4]]
|
||||
; CHECK: %r0 = COPY [[SUM]]
|
||||
; CHECK: [[SUM_EXT:%[0-9]+]](s32) = G_ANYEXT [[SUM]]
|
||||
; CHECK: %r0 = COPY [[SUM_EXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
entry:
|
||||
%sum = add i8 %p2, %p4
|
||||
|
@ -184,11 +204,13 @@ define i8 @test_stack_args_noext(i32 %p0, i16 %p1, i8 %p2, i1 %p3,
|
|||
; CHECK-DAG: id: [[P4:[0-9]]]{{.*}}offset: 0{{.*}}size: 1
|
||||
; CHECK-DAG: id: [[P5:[0-9]]]{{.*}}offset: 4{{.*}}size: 2
|
||||
; CHECK: liveins: %r0, %r1, %r2, %r3
|
||||
; CHECK: [[VREGP2:%[0-9]+]](s8) = COPY %r2
|
||||
; CHECK: [[VREGR2:%[0-9]+]](s32) = COPY %r2
|
||||
; CHECK: [[VREGP2:%[0-9]+]](s8) = G_TRUNC [[VREGR2]]
|
||||
; CHECK: [[FIP4:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[P4]]
|
||||
; CHECK: [[VREGP4:%[0-9]+]](s8) = G_LOAD [[FIP4]](p0){{.*}}load 1
|
||||
; CHECK: [[SUM:%[0-9]+]](s8) = G_ADD [[VREGP2]], [[VREGP4]]
|
||||
; CHECK: %r0 = COPY [[SUM]]
|
||||
; CHECK: [[SUM_EXT:%[0-9]+]](s32) = G_ANYEXT [[SUM]]
|
||||
; CHECK: %r0 = COPY [[SUM_EXT]](s32)
|
||||
; CHECK: BX_RET 14, _, implicit %r0
|
||||
entry:
|
||||
%sum = add i8 %p2, %p4
|
||||
|
@ -489,9 +511,12 @@ declare arm_aapcscc signext i16 @ext_target(i8 signext, i8 zeroext, i16 signext,
|
|||
|
||||
define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b, i1 %c) {
|
||||
; CHECK-LABEL: name: test_call_ext_params
|
||||
; CHECK-DAG: [[AVREG:%[0-9]+]](s8) = COPY %r0
|
||||
; CHECK-DAG: [[BVREG:%[0-9]+]](s16) = COPY %r1
|
||||
; CHECK-DAG: [[CVREG:%[0-9]+]](s1) = COPY %r2
|
||||
; CHECK-DAG: [[R0VREG:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK-DAG: [[AVREG:%[0-9]+]](s8) = G_TRUNC [[R0VREG]]
|
||||
; CHECK-DAG: [[R1VREG:%[0-9]+]](s32) = COPY %r1
|
||||
; CHECK-DAG: [[BVREG:%[0-9]+]](s16) = G_TRUNC [[R1VREG]]
|
||||
; CHECK-DAG: [[R2VREG:%[0-9]+]](s32) = COPY %r2
|
||||
; CHECK-DAG: [[CVREG:%[0-9]+]](s1) = G_TRUNC [[R2VREG]]
|
||||
; CHECK: ADJCALLSTACKDOWN 20, 0, 14, _, implicit-def %sp, implicit %sp
|
||||
; CHECK: [[SEXTA:%[0-9]+]](s32) = G_SEXT [[AVREG]](s8)
|
||||
; CHECK: %r0 = COPY [[SEXTA]]
|
||||
|
@ -527,7 +552,8 @@ define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b, i1 %c) {
|
|||
; CHECK: [[ZEXTC:%[0-9]+]](s32) = G_ZEXT [[CVREG]]
|
||||
; CHECK: G_STORE [[ZEXTC]](s32), [[FI5]](p0){{.*}}store 4
|
||||
; CHECK: BLX @ext_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1, implicit %r2, implicit %r3, implicit-def %r0
|
||||
; CHECK: [[RVREG:%[0-9]+]](s16) = COPY %r0
|
||||
; CHECK: [[R0VREG:%[0-9]+]](s32) = COPY %r0
|
||||
; CHECK: [[RVREG:%[0-9]+]](s16) = G_TRUNC [[R0VREG]]
|
||||
; CHECK: ADJCALLSTACKUP 20, 0, 14, _, implicit-def %sp, implicit %sp
|
||||
; CHECK: [[RExtVREG:%[0-9]+]](s32) = G_SEXT [[RVREG]]
|
||||
; CHECK: %r0 = COPY [[RExtVREG]]
|
||||
|
|
|
@ -48,8 +48,8 @@ define i32 @test_add_i32(i32 %arg1, i32 %arg2) {
|
|||
define i16 @test_add_i16(i16 %arg1, i16 %arg2) {
|
||||
; X64-LABEL: test_add_i16:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: # kill: %DI<def> %DI<kill> %RDI<def>
|
||||
; X64-NEXT: # kill: %SI<def> %SI<kill> %RSI<def>
|
||||
; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
|
||||
; X64-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def>
|
||||
; X64-NEXT: leal (%rsi,%rdi), %eax
|
||||
; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
|
||||
; X64-NEXT: retq
|
||||
|
|
|
@ -314,22 +314,28 @@ define void @test_abi_exts_call(i8* %addr) {
|
|||
; X32-NEXT: pushl %ebx
|
||||
; X32-NEXT: .Lcfi7:
|
||||
; X32-NEXT: .cfi_def_cfa_offset 8
|
||||
; X32-NEXT: subl $8, %esp
|
||||
; X32-NEXT: pushl %esi
|
||||
; X32-NEXT: .Lcfi8:
|
||||
; X32-NEXT: .cfi_def_cfa_offset 16
|
||||
; X32-NEXT: .cfi_def_cfa_offset 12
|
||||
; X32-NEXT: pushl %eax
|
||||
; X32-NEXT: .Lcfi9:
|
||||
; X32-NEXT: .cfi_def_cfa_offset 16
|
||||
; X32-NEXT: .Lcfi10:
|
||||
; X32-NEXT: .cfi_offset %esi, -12
|
||||
; X32-NEXT: .Lcfi11:
|
||||
; X32-NEXT: .cfi_offset %ebx, -8
|
||||
; X32-NEXT: movl 16(%esp), %eax
|
||||
; X32-NEXT: movb (%eax), %bl
|
||||
; X32-NEXT: movb %bl, (%esp)
|
||||
; X32-NEXT: movzbl %bl, %esi
|
||||
; X32-NEXT: movl %esi, (%esp)
|
||||
; X32-NEXT: calll take_char
|
||||
; X32-NEXT: movsbl %bl, %eax
|
||||
; X32-NEXT: movl %eax, (%esp)
|
||||
; X32-NEXT: calll take_char
|
||||
; X32-NEXT: movzbl %bl, %eax
|
||||
; X32-NEXT: movl %eax, (%esp)
|
||||
; X32-NEXT: movl %esi, (%esp)
|
||||
; X32-NEXT: calll take_char
|
||||
; X32-NEXT: addl $8, %esp
|
||||
; X32-NEXT: addl $4, %esp
|
||||
; X32-NEXT: popl %esi
|
||||
; X32-NEXT: popl %ebx
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
|
@ -340,13 +346,13 @@ define void @test_abi_exts_call(i8* %addr) {
|
|||
; X64-NEXT: .cfi_def_cfa_offset 16
|
||||
; X64-NEXT: .Lcfi7:
|
||||
; X64-NEXT: .cfi_offset %rbx, -16
|
||||
; X64-NEXT: movb (%rdi), %bl
|
||||
; X64-NEXT: movb (%rdi), %al
|
||||
; X64-NEXT: movzbl %al, %ebx
|
||||
; X64-NEXT: movl %ebx, %edi
|
||||
; X64-NEXT: callq take_char
|
||||
; X64-NEXT: movsbl %bl, %ebx
|
||||
; X64-NEXT: movl %ebx, %edi
|
||||
; X64-NEXT: movsbl %bl, %edi
|
||||
; X64-NEXT: callq take_char
|
||||
; X64-NEXT: movzbl %bl, %edi
|
||||
; X64-NEXT: movl %ebx, %edi
|
||||
; X64-NEXT: callq take_char
|
||||
; X64-NEXT: popq %rbx
|
||||
; X64-NEXT: retq
|
||||
|
@ -362,7 +368,7 @@ define void @test_variadic_call_1(i8** %addr_ptr, i32* %val_ptr) {
|
|||
; X32-LABEL: test_variadic_call_1:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: subl $12, %esp
|
||||
; X32-NEXT: .Lcfi10:
|
||||
; X32-NEXT: .Lcfi12:
|
||||
; X32-NEXT: .cfi_def_cfa_offset 16
|
||||
; X32-NEXT: movl 16(%esp), %eax
|
||||
; X32-NEXT: movl 20(%esp), %ecx
|
||||
|
@ -396,7 +402,7 @@ define void @test_variadic_call_2(i8** %addr_ptr, double* %val_ptr) {
|
|||
; X32-LABEL: test_variadic_call_2:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: subl $12, %esp
|
||||
; X32-NEXT: .Lcfi11:
|
||||
; X32-NEXT: .Lcfi13:
|
||||
; X32-NEXT: .cfi_def_cfa_offset 16
|
||||
; X32-NEXT: movl 16(%esp), %eax
|
||||
; X32-NEXT: movl 20(%esp), %ecx
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
define i64 @test_zext_i1(i8 %a) {
|
||||
; X64-LABEL: test_zext_i1:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: # kill: %DIL<def> %DIL<kill> %RDI<def>
|
||||
; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
|
||||
; X64-NEXT: andq $1, %rdi
|
||||
; X64-NEXT: movq %rdi, %rax
|
||||
; X64-NEXT: retq
|
||||
|
|
|
@ -18,12 +18,18 @@ define i8 @test_i8_args_8(i8 %arg1, i8 %arg2, i8 %arg3, i8 %arg4,
|
|||
; X64-NEXT: isImmutable: true,
|
||||
|
||||
; X64: liveins: %ecx, %edi, %edx, %esi, %r8d, %r9d
|
||||
; X64: [[ARG1:%[0-9]+]](s8) = COPY %edi
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = COPY %esi
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = COPY %edx
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = COPY %ecx
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = COPY %r8d
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = COPY %r9d
|
||||
; X64: [[ARG1_TMP:%[0-9]+]](s32) = COPY %edi
|
||||
; X64: [[ARG1:%[0-9]+]](s8) = G_TRUNC [[ARG1_TMP]](s32)
|
||||
; X64-NEXT: %{{[0-9]+}}(s32) = COPY %esi
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = G_TRUNC %{{[0-9]+}}(s32)
|
||||
; X64-NEXT: %{{[0-9]+}}(s32) = COPY %edx
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = G_TRUNC %{{[0-9]+}}(s32)
|
||||
; X64-NEXT: %{{[0-9]+}}(s32) = COPY %ecx
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = G_TRUNC %{{[0-9]+}}(s32)
|
||||
; X64-NEXT: %{{[0-9]+}}(s32) = COPY %r8d
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = G_TRUNC %{{[0-9]+}}(s32)
|
||||
; X64-NEXT: %{{[0-9]+}}(s32) = COPY %r9d
|
||||
; X64-NEXT: %{{[0-9]+}}(s8) = G_TRUNC %{{[0-9]+}}(s32)
|
||||
; X64-NEXT: [[ARG7_ADDR:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[STACK0]]
|
||||
; X64-NEXT: [[ARG7:%[0-9]+]](s8) = G_LOAD [[ARG7_ADDR]](p0) :: (invariant load 1 from %fixed-stack.[[STACK0]], align 0)
|
||||
; X64-NEXT: [[ARG8_ADDR:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[STACK8]]
|
||||
|
@ -651,23 +657,24 @@ define void @test_abi_exts_call(i8* %addr) {
|
|||
; X32-NEXT: %3(p0) = COPY %esp
|
||||
; X32-NEXT: %4(s32) = G_CONSTANT i32 0
|
||||
; X32-NEXT: %5(p0) = G_GEP %3, %4(s32)
|
||||
; X32-NEXT: G_STORE %2(s8), %5(p0) :: (store 4 into stack, align 0)
|
||||
; X32-NEXT: %6(s32) = G_ANYEXT %2(s8)
|
||||
; X32-NEXT: G_STORE %6(s32), %5(p0) :: (store 4 into stack, align 0)
|
||||
; X32-NEXT: CALLpcrel32 @take_char, csr_32, implicit %esp
|
||||
; X32-NEXT: ADJCALLSTACKUP32 4, 0, implicit-def %esp, implicit-def %eflags, implicit %esp
|
||||
; X32-NEXT: ADJCALLSTACKDOWN32 4, 0, 0, implicit-def %esp, implicit-def %eflags, implicit %esp
|
||||
; X32-NEXT: %6(p0) = COPY %esp
|
||||
; X32-NEXT: %7(s32) = G_CONSTANT i32 0
|
||||
; X32-NEXT: %8(p0) = G_GEP %6, %7(s32)
|
||||
; X32-NEXT: %9(s32) = G_SEXT %2(s8)
|
||||
; X32-NEXT: G_STORE %9(s32), %8(p0) :: (store 4 into stack, align 0)
|
||||
; X32-NEXT: %7(p0) = COPY %esp
|
||||
; X32-NEXT: %8(s32) = G_CONSTANT i32 0
|
||||
; X32-NEXT: %9(p0) = G_GEP %7, %8(s32)
|
||||
; X32-NEXT: %10(s32) = G_SEXT %2(s8)
|
||||
; X32-NEXT: G_STORE %10(s32), %9(p0) :: (store 4 into stack, align 0)
|
||||
; X32-NEXT: CALLpcrel32 @take_char, csr_32, implicit %esp
|
||||
; X32-NEXT: ADJCALLSTACKUP32 4, 0, implicit-def %esp, implicit-def %eflags, implicit %esp
|
||||
; X32-NEXT: ADJCALLSTACKDOWN32 4, 0, 0, implicit-def %esp, implicit-def %eflags, implicit %esp
|
||||
; X32-NEXT: %10(p0) = COPY %esp
|
||||
; X32-NEXT: %11(s32) = G_CONSTANT i32 0
|
||||
; X32-NEXT: %12(p0) = G_GEP %10, %11(s32)
|
||||
; X32-NEXT: %13(s32) = G_ZEXT %2(s8)
|
||||
; X32-NEXT: G_STORE %13(s32), %12(p0) :: (store 4 into stack, align 0)
|
||||
; X32-NEXT: %11(p0) = COPY %esp
|
||||
; X32-NEXT: %12(s32) = G_CONSTANT i32 0
|
||||
; X32-NEXT: %13(p0) = G_GEP %11, %12(s32)
|
||||
; X32-NEXT: %14(s32) = G_ZEXT %2(s8)
|
||||
; X32-NEXT: G_STORE %14(s32), %13(p0) :: (store 4 into stack, align 0)
|
||||
; X32-NEXT: CALLpcrel32 @take_char, csr_32, implicit %esp
|
||||
; X32-NEXT: ADJCALLSTACKUP32 4, 0, implicit-def %esp, implicit-def %eflags, implicit %esp
|
||||
; X32-NEXT: RET 0
|
||||
|
@ -675,19 +682,20 @@ define void @test_abi_exts_call(i8* %addr) {
|
|||
; X64: %0(p0) = COPY %rdi
|
||||
; X64-NEXT: %1(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr)
|
||||
; X64-NEXT: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def %rsp, implicit-def %eflags, implicit %rsp
|
||||
; X64-NEXT: %edi = COPY %1(s8)
|
||||
; X64-NEXT: CALL64pcrel32 @take_char, csr_64, implicit %rsp, implicit %edi
|
||||
; X64-NEXT: ADJCALLSTACKUP64 0, 0, implicit-def %rsp, implicit-def %eflags, implicit %rsp
|
||||
; X64-NEXT: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def %rsp, implicit-def %eflags, implicit %rsp
|
||||
; X64-NEXT: %2(s32) = G_SEXT %1(s8)
|
||||
; X64-NEXT: %2(s32) = G_ANYEXT %1(s8)
|
||||
; X64-NEXT: %edi = COPY %2(s32)
|
||||
; X64-NEXT: CALL64pcrel32 @take_char, csr_64, implicit %rsp, implicit %edi
|
||||
; X64-NEXT: ADJCALLSTACKUP64 0, 0, implicit-def %rsp, implicit-def %eflags, implicit %rsp
|
||||
; X64-NEXT: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def %rsp, implicit-def %eflags, implicit %rsp
|
||||
; X64-NEXT: %3(s32) = G_ZEXT %1(s8)
|
||||
; X64-NEXT: %3(s32) = G_SEXT %1(s8)
|
||||
; X64-NEXT: %edi = COPY %3(s32)
|
||||
; X64-NEXT: CALL64pcrel32 @take_char, csr_64, implicit %rsp, implicit %edi
|
||||
; X64-NEXT: ADJCALLSTACKUP64 0, 0, implicit-def %rsp, implicit-def %eflags, implicit %rsp
|
||||
; X64-NEXT: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def %rsp, implicit-def %eflags, implicit %rsp
|
||||
; X64-NEXT: %4(s32) = G_ZEXT %1(s8)
|
||||
; X64-NEXT: %edi = COPY %4(s32)
|
||||
; X64-NEXT: CALL64pcrel32 @take_char, csr_64, implicit %rsp, implicit %edi
|
||||
; X64-NEXT: ADJCALLSTACKUP64 0, 0, implicit-def %rsp, implicit-def %eflags, implicit %rsp
|
||||
; X64-NEXT: RET 0
|
||||
|
||||
%val = load i8, i8* %addr
|
||||
|
|
Loading…
Reference in New Issue