Index: include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h =================================================================== --- include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -543,6 +543,10 @@ /// /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildCopy(unsigned Res, unsigned Op); + template + MachineInstrBuilder buildCopy(DstType &&Res, SrcType &&Src) { + return buildCopy(getDestFromArg(Res), getRegFromArg(Src)); + } /// Build and insert `Res = G_LOAD Addr, MMO`. /// @@ -660,6 +664,10 @@ /// /// \return The newly created instruction. MachineInstrBuilder buildTrunc(unsigned Res, unsigned Op); + template + MachineInstrBuilder buildTrunc(DstType &&Res, SrcType &&Src) { + return buildTrunc(getDestFromArg(Res), getRegFromArg(Src)); + } /// Build and insert a \p Res = G_ICMP \p Pred, \p Op0, \p Op1 /// Index: lib/CodeGen/GlobalISel/CallLowering.cpp =================================================================== --- lib/CodeGen/GlobalISel/CallLowering.cpp +++ lib/CodeGen/GlobalISel/CallLowering.cpp @@ -160,10 +160,11 @@ // 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); Index: lib/Target/AArch64/AArch64CallLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64CallLowering.cpp +++ lib/Target/AArch64/AArch64CallLowering.cpp @@ -70,8 +70,18 @@ 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, Index: lib/Target/ARM/ARMCallLowering.cpp =================================================================== --- lib/Target/ARM/ARMCallLowering.cpp +++ lib/Target/ARM/ARMCallLowering.cpp @@ -343,13 +343,25 @@ 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, Index: lib/Target/X86/X86CallLowering.cpp =================================================================== --- lib/Target/X86/X86CallLowering.cpp +++ lib/Target/X86/X86CallLowering.cpp @@ -226,6 +226,28 @@ 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 @@ 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 @@ 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: Index: test/CodeGen/AArch64/GlobalISel/arm64-callingconv.ll =================================================================== --- test/CodeGen/AArch64/GlobalISel/arm64-callingconv.ll +++ test/CodeGen/AArch64/GlobalISel/arm64-callingconv.ll @@ -70,8 +70,10 @@ ; 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) Index: test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll =================================================================== --- test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll +++ test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll @@ -43,7 +43,7 @@ ; 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: :0:0: cannot select: G_STORE %vreg5, %vreg2; mem:ST4[%addr] GPR:%vreg5,%vreg2 (in function: pending_phis) +; FALLBACK-WITH-REPORT-ERR: remark: :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) { Index: test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll =================================================================== --- test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -971,7 +971,8 @@ } ; 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 @@ } ; 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 @@ } ; 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 @@ 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) Index: test/CodeGen/AArch64/GlobalISel/call-translator.ll =================================================================== --- test/CodeGen/AArch64/GlobalISel/call-translator.ll +++ test/CodeGen/AArch64/GlobalISel/call-translator.ll @@ -61,7 +61,8 @@ ; 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 @@ ; 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) Index: test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll =================================================================== --- test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll +++ test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll @@ -11,8 +11,10 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ 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 @@ ; 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]] Index: test/CodeGen/X86/GlobalISel/add-scalar.ll =================================================================== --- test/CodeGen/X86/GlobalISel/add-scalar.ll +++ test/CodeGen/X86/GlobalISel/add-scalar.ll @@ -48,8 +48,8 @@ define i16 @test_add_i16(i16 %arg1, i16 %arg2) { ; X64-LABEL: test_add_i16: ; X64: # BB#0: -; X64-NEXT: # kill: %DI %DI %RDI -; X64-NEXT: # kill: %SI %SI %RSI +; X64-NEXT: # kill: %EDI %EDI %RDI +; X64-NEXT: # kill: %ESI %ESI %RSI ; X64-NEXT: leal (%rsi,%rdi), %eax ; X64-NEXT: # kill: %AX %AX %EAX ; X64-NEXT: retq Index: test/CodeGen/X86/GlobalISel/callingconv.ll =================================================================== --- test/CodeGen/X86/GlobalISel/callingconv.ll +++ test/CodeGen/X86/GlobalISel/callingconv.ll @@ -314,22 +314,28 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 Index: test/CodeGen/X86/GlobalISel/ext-x86-64.ll =================================================================== --- test/CodeGen/X86/GlobalISel/ext-x86-64.ll +++ test/CodeGen/X86/GlobalISel/ext-x86-64.ll @@ -6,7 +6,7 @@ define i64 @test_zext_i1(i8 %a) { ; X64-LABEL: test_zext_i1: ; X64: # BB#0: -; X64-NEXT: # kill: %DIL %DIL %RDI +; X64-NEXT: # kill: %EDI %EDI %RDI ; X64-NEXT: andq $1, %rdi ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: retq Index: test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll =================================================================== --- test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll +++ test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll @@ -18,12 +18,18 @@ ; 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 @@ ; 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,17 +682,18 @@ ; 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: %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: %2(s32) = G_SEXT %1(s8) -; X64-NEXT: %edi = COPY %2(s32) +; 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: %3(s32) = G_ZEXT %1(s8) -; X64-NEXT: %edi = COPY %3(s32) +; 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