[llvm-branch-commits] [llvm] 9eac818 - [X86] Fix variadic argument handling for x32
Harald van Dijk via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Dec 14 15:52:19 PST 2020
Author: Harald van Dijk
Date: 2020-12-14T23:47:27Z
New Revision: 9eac818370fe4b50a167627593bfe53e61c216bc
URL: https://github.com/llvm/llvm-project/commit/9eac818370fe4b50a167627593bfe53e61c216bc
DIFF: https://github.com/llvm/llvm-project/commit/9eac818370fe4b50a167627593bfe53e61c216bc.diff
LOG: [X86] Fix variadic argument handling for x32
The X86-64 ABI defines va_list as
typedef struct {
unsigned int gp_offset;
unsigned int fp_offset;
void *overflow_arg_area;
void *reg_save_area;
} va_list[1];
This means the size, alignment, and reg_save_area offset will depend on
whether we are in LP64 or in ILP32 mode, so this commit adds the checks.
Additionally, the VAARG_64 pseudo-instruction assumed 64-bit pointers, so
this commit adds a VAARG_X32 pseudo-instruction that behaves just like
VAARG_64, except for assuming 32-bit pointers.
Some of these changes were originally done by
Michael Liao <michael.hliao at gmail.com>.
Fixes https://bugs.llvm.org/show_bug.cgi?id=48428.
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D93160
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/lib/Target/X86/X86ISelLowering.h
llvm/lib/Target/X86/X86InstrCompiler.td
llvm/lib/Target/X86/X86InstrInfo.td
llvm/test/CodeGen/X86/x86-64-varargs.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e4fcafc3352f..21af1a5aad00 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -24360,15 +24360,16 @@ SDValue X86TargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
Subtarget.hasSSE1());
}
- // Insert VAARG_64 node into the DAG
- // VAARG_64 returns two values: Variable Argument Address, Chain
+ // Insert VAARG node into the DAG
+ // VAARG returns two values: Variable Argument Address, Chain
SDValue InstOps[] = {Chain, SrcPtr,
DAG.getTargetConstant(ArgSize, dl, MVT::i32),
DAG.getTargetConstant(ArgMode, dl, MVT::i8),
DAG.getTargetConstant(Align, dl, MVT::i32)};
SDVTList VTs = DAG.getVTList(getPointerTy(DAG.getDataLayout()), MVT::Other);
SDValue VAARG = DAG.getMemIntrinsicNode(
- X86ISD::VAARG_64, dl, VTs, InstOps, MVT::i64, MachinePointerInfo(SV),
+ Subtarget.isTarget64BitLP64() ? X86ISD::VAARG_64 : X86ISD::VAARG_X32, dl,
+ VTs, InstOps, MVT::i64, MachinePointerInfo(SV),
/*Alignment=*/None,
MachineMemOperand::MOLoad | MachineMemOperand::MOStore);
Chain = VAARG.getValue(1);
@@ -24394,9 +24395,11 @@ static SDValue LowerVACOPY(SDValue Op, const X86Subtarget &Subtarget,
const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
SDLoc DL(Op);
- return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr, DAG.getIntPtrConstant(24, DL),
- Align(8), /*isVolatile*/ false, false, false,
- MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV));
+ return DAG.getMemcpy(
+ Chain, DL, DstPtr, SrcPtr,
+ DAG.getIntPtrConstant(Subtarget.isTarget64BitLP64() ? 24 : 16, DL),
+ Align(Subtarget.isTarget64BitLP64() ? 8 : 4), /*isVolatile*/ false, false,
+ false, MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV));
}
// Helper to get immediate/variable SSE shift opcode from other shift opcodes.
@@ -30959,6 +30962,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(DBPSADBW)
NODE_NAME_CASE(VASTART_SAVE_XMM_REGS)
NODE_NAME_CASE(VAARG_64)
+ NODE_NAME_CASE(VAARG_X32)
NODE_NAME_CASE(WIN_ALLOCA)
NODE_NAME_CASE(MEMBARRIER)
NODE_NAME_CASE(MFENCE)
@@ -31548,11 +31552,9 @@ static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
return sinkMBB;
}
-
-
MachineBasicBlock *
-X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
- MachineBasicBlock *MBB) const {
+X86TargetLowering::EmitVAARGWithCustomInserter(MachineInstr &MI,
+ MachineBasicBlock *MBB) const {
// Emit va_arg instruction on X86-64.
// Operands to this pseudo-instruction:
@@ -31563,9 +31565,8 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
// 8 ) Align : Alignment of type
// 9 ) EFLAGS (implicit-def)
- assert(MI.getNumOperands() == 10 && "VAARG_64 should have 10 operands!");
- static_assert(X86::AddrNumOperands == 5,
- "VAARG_64 assumes 5 address operands");
+ assert(MI.getNumOperands() == 10 && "VAARG should have 10 operands!");
+ static_assert(X86::AddrNumOperands == 5, "VAARG assumes 5 address operands");
Register DestReg = MI.getOperand(0).getReg();
MachineOperand &Base = MI.getOperand(1);
@@ -31580,7 +31581,7 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
MachineFunction *MF = MBB->getParent();
// Memory Reference
- assert(MI.hasOneMemOperand() && "Expected VAARG_64 to have one memoperand");
+ assert(MI.hasOneMemOperand() && "Expected VAARG to have one memoperand");
MachineMemOperand *OldMMO = MI.memoperands().front();
@@ -31593,7 +31594,8 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
// Machine Information
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
- const TargetRegisterClass *AddrRegClass = getRegClassFor(MVT::i64);
+ const TargetRegisterClass *AddrRegClass =
+ getRegClassFor(getPointerTy(MBB->getParent()->getDataLayout()));
const TargetRegisterClass *OffsetRegClass = getRegClassFor(MVT::i32);
const DebugLoc &DL = MI.getDebugLoc();
@@ -31704,25 +31706,35 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
// Read the reg_save_area address.
Register RegSaveReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(offsetMBB, DL, TII->get(X86::MOV64rm), RegSaveReg)
+ BuildMI(
+ offsetMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm),
+ RegSaveReg)
.add(Base)
.add(Scale)
.add(Index)
- .addDisp(Disp, 16)
+ .addDisp(Disp, Subtarget.isTarget64BitLP64() ? 16 : 12)
.add(Segment)
.setMemRefs(LoadOnlyMMO);
- // Zero-extend the offset
- Register OffsetReg64 = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(offsetMBB, DL, TII->get(X86::SUBREG_TO_REG), OffsetReg64)
- .addImm(0)
- .addReg(OffsetReg)
- .addImm(X86::sub_32bit);
+ if (Subtarget.isTarget64BitLP64()) {
+ // Zero-extend the offset
+ Register OffsetReg64 = MRI.createVirtualRegister(AddrRegClass);
+ BuildMI(offsetMBB, DL, TII->get(X86::SUBREG_TO_REG), OffsetReg64)
+ .addImm(0)
+ .addReg(OffsetReg)
+ .addImm(X86::sub_32bit);
- // Add the offset to the reg_save_area to get the final address.
- BuildMI(offsetMBB, DL, TII->get(X86::ADD64rr), OffsetDestReg)
- .addReg(OffsetReg64)
- .addReg(RegSaveReg);
+ // Add the offset to the reg_save_area to get the final address.
+ BuildMI(offsetMBB, DL, TII->get(X86::ADD64rr), OffsetDestReg)
+ .addReg(OffsetReg64)
+ .addReg(RegSaveReg);
+ } else {
+ // Add the offset to the reg_save_area to get the final address.
+ BuildMI(offsetMBB, DL, TII->get(X86::ADD32rr), OffsetDestReg)
+ .addReg(OffsetReg)
+ .addReg(RegSaveReg);
+ }
// Compute the offset for the next argument
Register NextOffsetReg = MRI.createVirtualRegister(OffsetRegClass);
@@ -31751,7 +31763,9 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
// Load the overflow_area address into a register.
Register OverflowAddrReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(overflowMBB, DL, TII->get(X86::MOV64rm), OverflowAddrReg)
+ BuildMI(overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm),
+ OverflowAddrReg)
.add(Base)
.add(Scale)
.add(Index)
@@ -31766,11 +31780,17 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
Register TmpReg = MRI.createVirtualRegister(AddrRegClass);
// aligned_addr = (addr + (align-1)) & ~(align-1)
- BuildMI(overflowMBB, DL, TII->get(X86::ADD64ri32), TmpReg)
+ BuildMI(
+ overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::ADD64ri32 : X86::ADD32ri),
+ TmpReg)
.addReg(OverflowAddrReg)
.addImm(Alignment.value() - 1);
- BuildMI(overflowMBB, DL, TII->get(X86::AND64ri32), OverflowDestReg)
+ BuildMI(
+ overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::AND64ri32 : X86::AND32ri),
+ OverflowDestReg)
.addReg(TmpReg)
.addImm(~(uint64_t)(Alignment.value() - 1));
} else {
@@ -31781,12 +31801,16 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(MachineInstr &MI,
// Compute the next overflow address after this argument.
// (the overflow address should be kept 8-byte aligned)
Register NextAddrReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(overflowMBB, DL, TII->get(X86::ADD64ri32), NextAddrReg)
- .addReg(OverflowDestReg)
- .addImm(ArgSizeA8);
+ BuildMI(
+ overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::ADD64ri32 : X86::ADD32ri),
+ NextAddrReg)
+ .addReg(OverflowDestReg)
+ .addImm(ArgSizeA8);
// Store the new overflow address.
- BuildMI(overflowMBB, DL, TII->get(X86::MOV64mr))
+ BuildMI(overflowMBB, DL,
+ TII->get(Subtarget.isTarget64BitLP64() ? X86::MOV64mr : X86::MOV32mr))
.add(Base)
.add(Scale)
.add(Index)
@@ -33721,7 +33745,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
return EmitVAStartSaveXMMRegsWithCustomInserter(MI, BB);
case X86::VAARG_64:
- return EmitVAARG64WithCustomInserter(MI, BB);
+ case X86::VAARG_X32:
+ return EmitVAARGWithCustomInserter(MI, BB);
case X86::EH_SjLj_SetJmp32:
case X86::EH_SjLj_SetJmp64:
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 6668fdb8ae60..25a42537ee14 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -814,9 +814,10 @@ namespace llvm {
/// specifies the type to store as.
FST,
- /// This instruction grabs the address of the next argument
+ /// These instructions grab the address of the next argument
/// from a va_list. (reads and modifies the va_list in memory)
VAARG_64,
+ VAARG_X32,
// Vector truncating store with unsigned/signed saturation
VTRUNCSTOREUS,
@@ -1581,8 +1582,7 @@ namespace llvm {
// Utility function to emit the low-level va_arg code for X86-64.
MachineBasicBlock *
- EmitVAARG64WithCustomInserter(MachineInstr &MI,
- MachineBasicBlock *MBB) const;
+ EmitVAARGWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const;
/// Utility function to emit the xmm reg save portion of va_start.
MachineBasicBlock *
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 0c9f972cf225..7a2facf226d8 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -81,17 +81,24 @@ def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
timm:$offset),
(implicit EFLAGS)]>;
-// The VAARG_64 pseudo-instruction takes the address of the va_list,
-// and places the address of the next argument into a register.
-let Defs = [EFLAGS] in
+// The VAARG_64 and VAARG_X32 pseudo-instructions take the address of the
+// va_list, and place the address of the next argument into a register.
+let Defs = [EFLAGS] in {
def VAARG_64 : I<0, Pseudo,
(outs GR64:$dst),
(ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align),
"#VAARG_64 $dst, $ap, $size, $mode, $align",
[(set GR64:$dst,
(X86vaarg64 addr:$ap, timm:$size, timm:$mode, timm:$align)),
- (implicit EFLAGS)]>;
-
+ (implicit EFLAGS)]>, Requires<[In64BitMode, IsLP64]>;
+def VAARG_X32 : I<0, Pseudo,
+ (outs GR32:$dst),
+ (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align),
+ "#VAARG_X32 $dst, $ap, $size, $mode, $align",
+ [(set GR32:$dst,
+ (X86vaargx32 addr:$ap, timm:$size, timm:$mode, timm:$align)),
+ (implicit EFLAGS)]>, Requires<[In64BitMode, NotLP64]>;
+}
// When using segmented stacks these are lowered into instructions which first
// check if the current stacklet has enough free memory. If it does, memory is
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index a8ea79506f22..26099b4dfee8 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -94,11 +94,11 @@ def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
SDTCisVT<1, iPTR>,
SDTCisVT<2, iPTR>]>;
-def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
- SDTCisPtrTy<1>,
- SDTCisVT<2, i32>,
- SDTCisVT<3, i8>,
- SDTCisVT<4, i32>]>;
+def SDT_X86VAARG : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
+ SDTCisPtrTy<1>,
+ SDTCisVT<2, i32>,
+ SDTCisVT<3, i8>,
+ SDTCisVT<4, i32>]>;
def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
@@ -186,7 +186,11 @@ def X86vastart_save_xmm_regs :
SDT_X86VASTART_SAVE_XMM_REGS,
[SDNPHasChain, SDNPVariadic]>;
def X86vaarg64 :
- SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
+ SDNode<"X86ISD::VAARG_64", SDT_X86VAARG,
+ [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
+ SDNPMemOperand]>;
+def X86vaargx32 :
+ SDNode<"X86ISD::VAARG_X32", SDT_X86VAARG,
[SDNPHasChain, SDNPMayLoad, SDNPMayStore,
SDNPMemOperand]>;
def X86callseq_start :
diff --git a/llvm/test/CodeGen/X86/x86-64-varargs.ll b/llvm/test/CodeGen/X86/x86-64-varargs.ll
index 48b757be2645..146248857fae 100644
--- a/llvm/test/CodeGen/X86/x86-64-varargs.ll
+++ b/llvm/test/CodeGen/X86/x86-64-varargs.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --no_x86_scrub_sp
; RUN: llc < %s -mtriple=x86_64-apple-darwin -code-model=large -relocation-model=static | FileCheck --check-prefix=CHECK-X64 %s
+; RUN: llc < %s -mtriple=x86_64-linux-gnux32 | FileCheck --check-prefix=CHECK-X32 %s
@.str = internal constant [38 x i8] c"%d, %f, %d, %lld, %d, %f, %d, %d, %d\0A\00" ; <[38 x i8]*> [#uses=1]
@@ -271,6 +272,261 @@ define void @func(...) nounwind {
; CHECK-X64-NEXT: addq $240, %rsp
; CHECK-X64-NEXT: popq %rbx
; CHECK-X64-NEXT: retq
+;
+; CHECK-X32-LABEL: func:
+; CHECK-X32: # %bb.0: # %entry
+; CHECK-X32-NEXT: subl $216, %esp
+; CHECK-X32-NEXT: testb %al, %al
+; CHECK-X32-NEXT: je .LBB0_2
+; CHECK-X32-NEXT: # %bb.1: # %entry
+; CHECK-X32-NEXT: movaps %xmm0, 80(%esp)
+; CHECK-X32-NEXT: movaps %xmm1, 96(%esp)
+; CHECK-X32-NEXT: movaps %xmm2, 112(%esp)
+; CHECK-X32-NEXT: movaps %xmm3, 128(%esp)
+; CHECK-X32-NEXT: movaps %xmm4, 144(%esp)
+; CHECK-X32-NEXT: movaps %xmm5, 160(%esp)
+; CHECK-X32-NEXT: movaps %xmm6, 176(%esp)
+; CHECK-X32-NEXT: movaps %xmm7, 192(%esp)
+; CHECK-X32-NEXT: .LBB0_2: # %entry
+; CHECK-X32-NEXT: movq %rdi, 32(%esp)
+; CHECK-X32-NEXT: movq %rsi, 40(%esp)
+; CHECK-X32-NEXT: movq %rdx, 48(%esp)
+; CHECK-X32-NEXT: movq %rcx, 56(%esp)
+; CHECK-X32-NEXT: movq %r8, 64(%esp)
+; CHECK-X32-NEXT: movq %r9, 72(%esp)
+; CHECK-X32-NEXT: movabsq $206158430208, %rax # imm = 0x3000000000
+; CHECK-X32-NEXT: movq %rax, (%esp)
+; CHECK-X32-NEXT: leal 224(%rsp), %eax
+; CHECK-X32-NEXT: movl %eax, 8(%esp)
+; CHECK-X32-NEXT: leal 32(%rsp), %eax
+; CHECK-X32-NEXT: movl %eax, 12(%esp)
+; CHECK-X32-NEXT: movl (%esp), %ecx
+; CHECK-X32-NEXT: cmpl $48, %ecx
+; CHECK-X32-NEXT: jae .LBB0_4
+; CHECK-X32-NEXT: # %bb.3: # %entry
+; CHECK-X32-NEXT: movl 12(%esp), %eax
+; CHECK-X32-NEXT: addl %ecx, %eax
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, (%esp)
+; CHECK-X32-NEXT: jmp .LBB0_5
+; CHECK-X32-NEXT: .LBB0_4: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %ecx
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_5: # %entry
+; CHECK-X32-NEXT: movl (%eax), %r10d
+; CHECK-X32-NEXT: movl (%esp), %ecx
+; CHECK-X32-NEXT: cmpl $48, %ecx
+; CHECK-X32-NEXT: jae .LBB0_7
+; CHECK-X32-NEXT: # %bb.6: # %entry
+; CHECK-X32-NEXT: movl 12(%esp), %eax
+; CHECK-X32-NEXT: addl %ecx, %eax
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, (%esp)
+; CHECK-X32-NEXT: jmp .LBB0_8
+; CHECK-X32-NEXT: .LBB0_7: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %ecx
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_8: # %entry
+; CHECK-X32-NEXT: movl (%eax), %r11d
+; CHECK-X32-NEXT: movl (%esp), %ecx
+; CHECK-X32-NEXT: cmpl $48, %ecx
+; CHECK-X32-NEXT: jae .LBB0_10
+; CHECK-X32-NEXT: # %bb.9: # %entry
+; CHECK-X32-NEXT: movl 12(%esp), %eax
+; CHECK-X32-NEXT: addl %ecx, %eax
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, (%esp)
+; CHECK-X32-NEXT: jmp .LBB0_11
+; CHECK-X32-NEXT: .LBB0_10: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %ecx
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_11: # %entry
+; CHECK-X32-NEXT: movl (%eax), %r9d
+; CHECK-X32-NEXT: movq (%esp), %rax
+; CHECK-X32-NEXT: movq 8(%esp), %rcx
+; CHECK-X32-NEXT: movq %rcx, 24(%esp)
+; CHECK-X32-NEXT: movq %rax, 16(%esp)
+; CHECK-X32-NEXT: movl 4(%esp), %eax
+; CHECK-X32-NEXT: cmpl $176, %eax
+; CHECK-X32-NEXT: jae .LBB0_13
+; CHECK-X32-NEXT: # %bb.12: # %entry
+; CHECK-X32-NEXT: addl $16, %eax
+; CHECK-X32-NEXT: movl %eax, 4(%esp)
+; CHECK-X32-NEXT: jmp .LBB0_14
+; CHECK-X32-NEXT: .LBB0_13: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_14: # %entry
+; CHECK-X32-NEXT: movl 20(%esp), %ecx
+; CHECK-X32-NEXT: cmpl $176, %ecx
+; CHECK-X32-NEXT: jae .LBB0_16
+; CHECK-X32-NEXT: # %bb.15: # %entry
+; CHECK-X32-NEXT: movl 28(%esp), %eax
+; CHECK-X32-NEXT: addl %ecx, %eax
+; CHECK-X32-NEXT: addl $16, %ecx
+; CHECK-X32-NEXT: movl %ecx, 20(%esp)
+; CHECK-X32-NEXT: jmp .LBB0_17
+; CHECK-X32-NEXT: .LBB0_16: # %entry
+; CHECK-X32-NEXT: movl 24(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %ecx
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, 24(%esp)
+; CHECK-X32-NEXT: .LBB0_17: # %entry
+; CHECK-X32-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero
+; CHECK-X32-NEXT: movl (%esp), %ecx
+; CHECK-X32-NEXT: cmpl $48, %ecx
+; CHECK-X32-NEXT: jae .LBB0_19
+; CHECK-X32-NEXT: # %bb.18: # %entry
+; CHECK-X32-NEXT: movl 12(%esp), %eax
+; CHECK-X32-NEXT: addl %ecx, %eax
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, (%esp)
+; CHECK-X32-NEXT: jmp .LBB0_20
+; CHECK-X32-NEXT: .LBB0_19: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %ecx
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_20: # %entry
+; CHECK-X32-NEXT: movl (%eax), %r8d
+; CHECK-X32-NEXT: movl 16(%esp), %eax
+; CHECK-X32-NEXT: cmpl $48, %eax
+; CHECK-X32-NEXT: jae .LBB0_22
+; CHECK-X32-NEXT: # %bb.21: # %entry
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 16(%esp)
+; CHECK-X32-NEXT: jmp .LBB0_23
+; CHECK-X32-NEXT: .LBB0_22: # %entry
+; CHECK-X32-NEXT: movl 24(%esp), %eax
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 24(%esp)
+; CHECK-X32-NEXT: .LBB0_23: # %entry
+; CHECK-X32-NEXT: movl (%esp), %eax
+; CHECK-X32-NEXT: cmpl $48, %eax
+; CHECK-X32-NEXT: jae .LBB0_25
+; CHECK-X32-NEXT: # %bb.24: # %entry
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, (%esp)
+; CHECK-X32-NEXT: jmp .LBB0_26
+; CHECK-X32-NEXT: .LBB0_25: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_26: # %entry
+; CHECK-X32-NEXT: movl 16(%esp), %ecx
+; CHECK-X32-NEXT: cmpl $48, %ecx
+; CHECK-X32-NEXT: jae .LBB0_28
+; CHECK-X32-NEXT: # %bb.27: # %entry
+; CHECK-X32-NEXT: movl 28(%esp), %eax
+; CHECK-X32-NEXT: addl %ecx, %eax
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, 16(%esp)
+; CHECK-X32-NEXT: jmp .LBB0_29
+; CHECK-X32-NEXT: .LBB0_28: # %entry
+; CHECK-X32-NEXT: movl 24(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %ecx
+; CHECK-X32-NEXT: addl $8, %ecx
+; CHECK-X32-NEXT: movl %ecx, 24(%esp)
+; CHECK-X32-NEXT: .LBB0_29: # %entry
+; CHECK-X32-NEXT: movq (%eax), %rcx
+; CHECK-X32-NEXT: movl (%esp), %edx
+; CHECK-X32-NEXT: cmpl $48, %edx
+; CHECK-X32-NEXT: jae .LBB0_31
+; CHECK-X32-NEXT: # %bb.30: # %entry
+; CHECK-X32-NEXT: movl 12(%esp), %eax
+; CHECK-X32-NEXT: addl %edx, %eax
+; CHECK-X32-NEXT: addl $8, %edx
+; CHECK-X32-NEXT: movl %edx, (%esp)
+; CHECK-X32-NEXT: jmp .LBB0_32
+; CHECK-X32-NEXT: .LBB0_31: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %edx
+; CHECK-X32-NEXT: addl $8, %edx
+; CHECK-X32-NEXT: movl %edx, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_32: # %entry
+; CHECK-X32-NEXT: movl (%eax), %edx
+; CHECK-X32-NEXT: movl 16(%esp), %eax
+; CHECK-X32-NEXT: cmpl $48, %eax
+; CHECK-X32-NEXT: jae .LBB0_34
+; CHECK-X32-NEXT: # %bb.33: # %entry
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 16(%esp)
+; CHECK-X32-NEXT: jmp .LBB0_35
+; CHECK-X32-NEXT: .LBB0_34: # %entry
+; CHECK-X32-NEXT: movl 24(%esp), %eax
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 24(%esp)
+; CHECK-X32-NEXT: .LBB0_35: # %entry
+; CHECK-X32-NEXT: movl 4(%esp), %eax
+; CHECK-X32-NEXT: cmpl $176, %eax
+; CHECK-X32-NEXT: jae .LBB0_37
+; CHECK-X32-NEXT: # %bb.36: # %entry
+; CHECK-X32-NEXT: addl $16, %eax
+; CHECK-X32-NEXT: movl %eax, 4(%esp)
+; CHECK-X32-NEXT: jmp .LBB0_38
+; CHECK-X32-NEXT: .LBB0_37: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_38: # %entry
+; CHECK-X32-NEXT: movl 20(%esp), %esi
+; CHECK-X32-NEXT: cmpl $176, %esi
+; CHECK-X32-NEXT: jae .LBB0_40
+; CHECK-X32-NEXT: # %bb.39: # %entry
+; CHECK-X32-NEXT: movl 28(%esp), %eax
+; CHECK-X32-NEXT: addl %esi, %eax
+; CHECK-X32-NEXT: addl $16, %esi
+; CHECK-X32-NEXT: movl %esi, 20(%esp)
+; CHECK-X32-NEXT: jmp .LBB0_41
+; CHECK-X32-NEXT: .LBB0_40: # %entry
+; CHECK-X32-NEXT: movl 24(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %esi
+; CHECK-X32-NEXT: addl $8, %esi
+; CHECK-X32-NEXT: movl %esi, 24(%esp)
+; CHECK-X32-NEXT: .LBB0_41: # %entry
+; CHECK-X32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
+; CHECK-X32-NEXT: movl (%esp), %esi
+; CHECK-X32-NEXT: cmpl $48, %esi
+; CHECK-X32-NEXT: jae .LBB0_43
+; CHECK-X32-NEXT: # %bb.42: # %entry
+; CHECK-X32-NEXT: movl 12(%esp), %eax
+; CHECK-X32-NEXT: addl %esi, %eax
+; CHECK-X32-NEXT: addl $8, %esi
+; CHECK-X32-NEXT: movl %esi, (%esp)
+; CHECK-X32-NEXT: jmp .LBB0_44
+; CHECK-X32-NEXT: .LBB0_43: # %entry
+; CHECK-X32-NEXT: movl 8(%esp), %eax
+; CHECK-X32-NEXT: movl %eax, %esi
+; CHECK-X32-NEXT: addl $8, %esi
+; CHECK-X32-NEXT: movl %esi, 8(%esp)
+; CHECK-X32-NEXT: .LBB0_44: # %entry
+; CHECK-X32-NEXT: movl (%eax), %esi
+; CHECK-X32-NEXT: movl 16(%esp), %eax
+; CHECK-X32-NEXT: cmpl $48, %eax
+; CHECK-X32-NEXT: jae .LBB0_46
+; CHECK-X32-NEXT: # %bb.45: # %entry
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 16(%esp)
+; CHECK-X32-NEXT: jmp .LBB0_47
+; CHECK-X32-NEXT: .LBB0_46: # %entry
+; CHECK-X32-NEXT: movl 24(%esp), %eax
+; CHECK-X32-NEXT: addl $8, %eax
+; CHECK-X32-NEXT: movl %eax, 24(%esp)
+; CHECK-X32-NEXT: .LBB0_47: # %entry
+; CHECK-X32-NEXT: movl $.str, %edi
+; CHECK-X32-NEXT: movb $2, %al
+; CHECK-X32-NEXT: pushq %r10
+; CHECK-X32-NEXT: pushq %r11
+; CHECK-X32-NEXT: callq printf at PLT
+; CHECK-X32-NEXT: addl $232, %esp
+; CHECK-X32-NEXT: retq
entry:
%ap1 = alloca %struct.va_list
%ap2 = alloca %struct.va_list
@@ -320,6 +576,24 @@ define i32 @main() nounwind {
; CHECK-X64-NEXT: xorl %eax, %eax
; CHECK-X64-NEXT: popq %rcx
; CHECK-X64-NEXT: retq
+;
+; CHECK-X32-LABEL: main:
+; CHECK-X32: # %bb.0: # %entry
+; CHECK-X32-NEXT: pushq %rax
+; CHECK-X32-NEXT: movl $12, (%esp)
+; CHECK-X32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
+; CHECK-X32-NEXT: movabsq $123456677890, %r8 # imm = 0x1CBE976802
+; CHECK-X32-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero
+; CHECK-X32-NEXT: movl $1, %edi
+; CHECK-X32-NEXT: movl $2, %esi
+; CHECK-X32-NEXT: movl $3, %edx
+; CHECK-X32-NEXT: movl $-10, %ecx
+; CHECK-X32-NEXT: movl $120, %r9d
+; CHECK-X32-NEXT: movb $2, %al
+; CHECK-X32-NEXT: callq func
+; CHECK-X32-NEXT: xorl %eax, %eax
+; CHECK-X32-NEXT: popq %rcx
+; CHECK-X32-NEXT: retq
entry:
tail call void (...) @func(i32 1, i32 2, i32 3, double 4.500000e+15, i32 -10, i64 123456677890, i32 120, double 0x3FF3EB8520000000, i32 12) nounwind
ret i32 0
More information about the llvm-branch-commits
mailing list