From clchiou at gmail.com Mon Mar 14 06:26:01 2011 From: clchiou at gmail.com (Che-Liang Chiou) Date: Mon, 14 Mar 2011 11:26:01 -0000 Subject: [llvm-commits] [llvm] r127577 - in /llvm/trunk: lib/Target/PTX/PTX.h lib/Target/PTX/PTXAsmPrinter.cpp lib/Target/PTX/PTXInstrInfo.cpp lib/Target/PTX/PTXInstrInfo.td test/CodeGen/PTX/setp.ll Message-ID: <20110314112601.DD5462A6C12C@llvm.org> Author: clchiou Date: Mon Mar 14 06:26:01 2011 New Revision: 127577 URL: http://llvm.org/viewvc/llvm-project?rev=127577&view=rev Log: ptx: add set.p instruction and related changes to predicate execution Added: llvm/trunk/test/CodeGen/PTX/setp.ll Modified: llvm/trunk/lib/Target/PTX/PTX.h llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Modified: llvm/trunk/lib/Target/PTX/PTX.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTX.h?rev=127577&r1=127576&r2=127577&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTX.h (original) +++ llvm/trunk/lib/Target/PTX/PTX.h Mon Mar 14 06:26:01 2011 @@ -31,7 +31,7 @@ }; enum Predicate { - PRED_IGNORE = 0, + PRED_NORMAL = 0, PRED_NEGATE = 1 }; } // namespace PTX Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp?rev=127577&r1=127576&r2=127577&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp Mon Mar 14 06:26:01 2011 @@ -410,7 +410,7 @@ DEBUG(dbgs() << "predicate: (" << reg << ", " << predOp << ")\n"); - if (reg && predOp != PTX::PRED_IGNORE) { + if (reg != PTX::NoRegister) { O << '@'; if (predOp == PTX::PRED_NEGATE) O << '!'; Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp?rev=127577&r1=127576&r2=127577&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Mon Mar 14 06:26:01 2011 @@ -100,10 +100,7 @@ bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const { int i = MI->findFirstPredOperandIdx(); - if (i == -1) - llvm_unreachable("missing predicate operand"); - return MI->getOperand(i).getReg() || - MI->getOperand(i+1).getImm() != PTX::PRED_IGNORE; + return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister; } bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { @@ -143,7 +140,29 @@ // If the specified instruction defines any predicate or condition code // register(s) used for predication, returns true as well as the definition // predicate(s) by reference. - return false; + + switch (MI->getOpcode()) { + default: + return false; + case PTX::SETPEQu32rr: + case PTX::SETPEQu32ri: + case PTX::SETPNEu32rr: + case PTX::SETPNEu32ri: + case PTX::SETPLTu32rr: + case PTX::SETPLTu32ri: + case PTX::SETPLEu32rr: + case PTX::SETPLEu32ri: + case PTX::SETPGTu32rr: + case PTX::SETPGTu32ri: + case PTX::SETPGEu32rr: + case PTX::SETPGEu32ri: { + const MachineOperand &MO = MI->getOperand(0); + assert(MO.isReg() && RI.getRegClass(MO.getReg()) == &PTX::PredsRegClass); + Pred.push_back(MO); + Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL)); + return true; + } + } } // static helper routines @@ -151,8 +170,8 @@ MachineSDNode *PTXInstrInfo:: GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode, DebugLoc dl, EVT VT, SDValue Op1) { - SDValue predReg = DAG->getRegister(0, MVT::i1); - SDValue predOp = DAG->getTargetConstant(PTX::PRED_IGNORE, MVT::i1); + SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1); + SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); SDValue ops[] = { Op1, predReg, predOp }; return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops)); } @@ -160,8 +179,8 @@ MachineSDNode *PTXInstrInfo:: GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode, DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) { - SDValue predReg = DAG->getRegister(0, MVT::i1); - SDValue predOp = DAG->getTargetConstant(PTX::PRED_IGNORE, MVT::i1); + SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1); + SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); SDValue ops[] = { Op1, Op2, predReg, predOp }; return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops)); } @@ -169,6 +188,6 @@ void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) { if (MI->findFirstPredOperandIdx() == -1) { MI->addOperand(MachineOperand::CreateReg(0, /*IsDef=*/false)); - MI->addOperand(MachineOperand::CreateImm(PTX::PRED_IGNORE)); + MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NORMAL)); } } Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=127577&r1=127576&r2=127577&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Mon Mar 14 06:26:01 2011 @@ -269,6 +269,18 @@ [(set RRegu32:$d, (opnode imm:$a, RRegu32:$b))]>; } +multiclass PTX_SETP { + def rr + : InstPTX<(outs Preds:$d), (ins RC:$a, RC:$b), + !strconcat("setp.", cmpstr, ".", regclsname, "\t$d, $a, $b"), + [(set Preds:$d, (setcc RC:$a, RC:$b, cmp))]>; + def ri + : InstPTX<(outs Preds:$d), (ins RC:$a, immcls:$b), + !strconcat("setp.", cmpstr, ".", regclsname, "\t$d, $a, $b"), + [(set Preds:$d, (setcc RC:$a, imm:$b, cmp))]>; +} + multiclass PTX_LD { def rr32 : InstPTX<(outs RC:$d), (ins MEMri32:$a), @@ -343,6 +355,11 @@ // Instructions //===----------------------------------------------------------------------===// +///===- Integer Arithmetic Instructions -----------------------------------===// + +defm ADD : INT3<"add", add>; +defm SUB : INT3<"sub", sub>; + ///===- Floating-Point Arithmetic Instructions ----------------------------===// // Standard Binary Operations @@ -397,12 +414,14 @@ // TODO: Allow the rounding mode to be selectable through llc. defm FMAD : PTX_FLOAT_4OP<"mad.rn", fmul, fadd>; +///===- Comparison and Selection Instructions -----------------------------===// - -///===- Integer Arithmetic Instructions -----------------------------------===// - -defm ADD : INT3<"add", add>; -defm SUB : INT3<"sub", sub>; +defm SETPEQu32 : PTX_SETP; +defm SETPNEu32 : PTX_SETP; +defm SETPLTu32 : PTX_SETP; +defm SETPLEu32 : PTX_SETP; +defm SETPGTu32 : PTX_SETP; +defm SETPGEu32 : PTX_SETP; ///===- Logic and Shift Instructions --------------------------------------===// @@ -475,6 +494,10 @@ // defm LDp : PTX_LD_ALL<"ld.param", load_parameter>; // TODO: Do something with st.param if/when it is needed. +def CVT_u32_pred + : InstPTX<(outs RRegu32:$d), (ins Preds:$a), "cvt.u32.pred\t$d, $a", + [(set RRegu32:$d, (zext Preds:$a))]>; + ///===- Control Flow Instructions -----------------------------------------===// let isReturn = 1, isTerminator = 1, isBarrier = 1 in { Added: llvm/trunk/test/CodeGen/PTX/setp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/setp.ll?rev=127577&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PTX/setp.ll (added) +++ llvm/trunk/test/CodeGen/PTX/setp.ll Mon Mar 14 06:26:01 2011 @@ -0,0 +1,109 @@ +; RUN: llc < %s -march=ptx | FileCheck %s + +define ptx_device i32 @test_setp_eq_u32_rr(i32 %x, i32 %y) { +; CHECK: setp.eq.u32 p0, r1, r2; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp eq i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_ne_u32_rr(i32 %x, i32 %y) { +; CHECK: setp.ne.u32 p0, r1, r2; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp ne i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_lt_u32_rr(i32 %x, i32 %y) { +; CHECK: setp.lt.u32 p0, r1, r2; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp ult i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_le_u32_rr(i32 %x, i32 %y) { +; CHECK: setp.le.u32 p0, r1, r2; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp ule i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_gt_u32_rr(i32 %x, i32 %y) { +; CHECK: setp.gt.u32 p0, r1, r2; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp ugt i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_ge_u32_rr(i32 %x, i32 %y) { +; CHECK: setp.ge.u32 p0, r1, r2; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp uge i32 %x, %y + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_eq_u32_ri(i32 %x) { +; CHECK: setp.eq.u32 p0, r1, 1; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp eq i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_ne_u32_ri(i32 %x) { +; CHECK: setp.ne.u32 p0, r1, 1; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp ne i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_lt_u32_ri(i32 %x) { +; CHECK: setp.eq.u32 p0, r1, 0; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp ult i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_le_u32_ri(i32 %x) { +; CHECK: setp.lt.u32 p0, r1, 2; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp ule i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_gt_u32_ri(i32 %x) { +; CHECK: setp.gt.u32 p0, r1, 1; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp ugt i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} + +define ptx_device i32 @test_setp_ge_u32_ri(i32 %x) { +; CHECK: setp.ne.u32 p0, r1, 0; +; CHECK-NEXT: cvt.u32.pred r0, p0; +; CHECK-NEXT: ret; + %p = icmp uge i32 %x, 1 + %z = zext i1 %p to i32 + ret i32 %z +} From justin.holewinski at gmail.com Mon Mar 14 09:09:33 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Mon, 14 Mar 2011 14:09:33 -0000 Subject: [llvm-commits] [llvm] r127578 - in /llvm/trunk: lib/Target/PTX/PTXInstrInfo.td test/CodeGen/PTX/llvm-intrinsic.ll Message-ID: <20110314140933.4384D2A6C12C@llvm.org> Author: jholewinski Date: Mon Mar 14 09:09:33 2011 New Revision: 127578 URL: http://llvm.org/viewvc/llvm-project?rev=127578&view=rev Log: PTX: Add support for sqrt/sin/cos intrinsics Added: llvm/trunk/test/CodeGen/PTX/llvm-intrinsic.ll Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=127578&r1=127577&r2=127578&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Mon Mar 14 09:09:33 2011 @@ -414,6 +414,39 @@ // TODO: Allow the rounding mode to be selectable through llc. defm FMAD : PTX_FLOAT_4OP<"mad.rn", fmul, fadd>; +///===- Floating-Point Intrinsic Instructions -----------------------------===// + +def FSQRT32 : InstPTX<(outs RRegf32:$d), + (ins RRegf32:$a), + "sqrt.rn.f32\t$d, $a", + [(set RRegf32:$d, (fsqrt RRegf32:$a))]>; + +def FSQRT64 : InstPTX<(outs RRegf64:$d), + (ins RRegf64:$a), + "sqrt.rn.f64\t$d, $a", + [(set RRegf64:$d, (fsqrt RRegf64:$a))]>; + +def FSIN32 : InstPTX<(outs RRegf32:$d), + (ins RRegf32:$a), + "sin.approx.f32\t$d, $a", + [(set RRegf32:$d, (fsin RRegf32:$a))]>; + +def FSIN64 : InstPTX<(outs RRegf64:$d), + (ins RRegf64:$a), + "sin.approx.f64\t$d, $a", + [(set RRegf64:$d, (fsin RRegf64:$a))]>; + +def FCOS32 : InstPTX<(outs RRegf32:$d), + (ins RRegf32:$a), + "cos.approx.f32\t$d, $a", + [(set RRegf32:$d, (fcos RRegf32:$a))]>; + +def FCOS64 : InstPTX<(outs RRegf64:$d), + (ins RRegf64:$a), + "cos.approx.f64\t$d, $a", + [(set RRegf64:$d, (fcos RRegf64:$a))]>; + + ///===- Comparison and Selection Instructions -----------------------------===// defm SETPEQu32 : PTX_SETP; Added: llvm/trunk/test/CodeGen/PTX/llvm-intrinsic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/llvm-intrinsic.ll?rev=127578&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PTX/llvm-intrinsic.ll (added) +++ llvm/trunk/test/CodeGen/PTX/llvm-intrinsic.ll Mon Mar 14 09:09:33 2011 @@ -0,0 +1,56 @@ +; RUN: llc < %s -march=ptx -mattr=+ptx20,+sm20 | FileCheck %s + +define ptx_device float @test_sqrt_f32(float %x) { +entry: +; CHECK: sqrt.rn.f32 f0, f1; +; CHECK-NEXT: ret; + %y = call float @llvm.sqrt.f32(float %x) + ret float %y +} + +define ptx_device double @test_sqrt_f64(double %x) { +entry: +; CHECK: sqrt.rn.f64 fd0, fd1; +; CHECK-NEXT: ret; + %y = call double @llvm.sqrt.f64(double %x) + ret double %y +} + +define ptx_device float @test_sin_f32(float %x) { +entry: +; CHECK: sin.approx.f32 f0, f1; +; CHECK-NEXT: ret; + %y = call float @llvm.sin.f32(float %x) + ret float %y +} + +define ptx_device double @test_sin_f64(double %x) { +entry: +; CHECK: sin.approx.f64 fd0, fd1; +; CHECK-NEXT: ret; + %y = call double @llvm.sin.f64(double %x) + ret double %y +} + +define ptx_device float @test_cos_f32(float %x) { +entry: +; CHECK: cos.approx.f32 f0, f1; +; CHECK-NEXT: ret; + %y = call float @llvm.cos.f32(float %x) + ret float %y +} + +define ptx_device double @test_cos_f64(double %x) { +entry: +; CHECK: cos.approx.f64 fd0, fd1; +; CHECK-NEXT: ret; + %y = call double @llvm.cos.f64(double %x) + ret double %y +} + +declare float @llvm.sqrt.f32(float) +declare double @llvm.sqrt.f64(double) +declare float @llvm.sin.f32(float) +declare double @llvm.sin.f64(double) +declare float @llvm.cos.f32(float) +declare double @llvm.cos.f64(double) From jan_sjodin at yahoo.com Mon Mar 14 09:43:19 2011 From: jan_sjodin at yahoo.com (Jan Sjodin) Date: Mon, 14 Mar 2011 07:43:19 -0700 (PDT) Subject: [llvm-commits] Fix for PR9477 In-Reply-To: <901267.5434.qm@web55606.mail.re4.yahoo.com> References: <901267.5434.qm@web55606.mail.re4.yahoo.com> Message-ID: <365431.79306.qm@web55603.mail.re4.yahoo.com> Let me know if this is ok to commit. Thanks, Jan ________________________________ From: Jan Sjodin To: llvm-commits at cs.uiuc.edu Sent: Sun, March 13, 2011 11:35:26 AM Subject: [llvm-commits] Fix for PR9477 Guard to check for AsmParser was missing. I tested the code by commenting out the "if" sections to see if it compiled on my machine, but someone may want to check it on a Mac. - Jan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110314/7ec4eabb/attachment.html From joerg at britannica.bec.de Mon Mar 14 10:38:27 2011 From: joerg at britannica.bec.de (Joerg Sonnenberger) Date: Mon, 14 Mar 2011 16:38:27 +0100 Subject: [llvm-commits] Support for explicit argument form of X86 string instructions In-Reply-To: <20110306232445.GA3958@britannica.bec.de> References: <20110306232445.GA3958@britannica.bec.de> Message-ID: <20110314153827.GB26058@britannica.bec.de> Ping. On Mon, Mar 07, 2011 at 12:24:45AM +0100, Joerg Sonnenberger wrote: > Hi all, > the attached patch implements the various explicit argument forms of the > X86 string instructions. They are used for documentation purposes, but > the use of segment overrides make them hard to specify with the normal > InstAlias syntax. This covers the ins, outs, movs, lods and stos family > of instructions. For lods and stos, both the implicit and explicit size > version is recognized. > > Joerg > Index: test/MC/X86/x86-32.s > =================================================================== > --- test/MC/X86/x86-32.s (revision 126955) > +++ test/MC/X86/x86-32.s (working copy) > @@ -816,3 +816,131 @@ > // CHECK: loopne 0 > // CHECK: encoding: [0xe0,A] > loopnz 0 > + > +// CHECK: outsb # encoding: [0x6e] > +// CHECK: outsb > +// CHECK: outsb > +// CHECK: outsb > +// CHECK: outsb > + outsb > + outsb %ds:(%esi), (%dx) > + outsb %ds:(%esi), %dx > + outsb (%esi), (%dx) > + outsb (%esi), %dx > + > +// CHECK: outsw # encoding: [0x66,0x6f] > +// CHECK: outsw > +// CHECK: outsw > +// CHECK: outsw > +// CHECK: outsw > + outsw > + outsw %ds:(%esi), (%dx) > + outsw %ds:(%esi), %dx > + outsw (%esi), (%dx) > + outsw (%esi), %dx > + > +// CHECK: outsl # encoding: [0x6f] > +// CHECK: outsl > +// CHECK: outsl > +// CHECK: outsl > + outsl > + outsl %ds:(%esi), (%dx) > + outsl %ds:(%esi), %dx > + outsl (%esi), (%dx) > + outsl (%esi), %dx > + > +// CHECK: insb # encoding: [0x6c] > +// CHECK: insb > +// CHECK: insb > + insb > + insb (%dx), %es:(%edi) > + insb %dx, %es:(%edi) > + > +// CHECK: insw # encoding: [0x66,0x6d] > +// CHECK: insw > +// CHECK: insw > + insw > + insw (%dx), %es:(%edi) > + insw %dx, %es:(%edi) > + > +// CHECK: insl # encoding: [0x6d] > +// CHECK: insl > +// CHECK: insl > + insl > + insl (%dx), %es:(%edi) > + insl %dx, %es:(%edi) > + > +// CHECK: movsb # encoding: [0xa4] > +// CHECK: movsb > +// CHECK: movsb > + movsb > + movsb %ds:(%esi), %es:(%edi) > + movsb (%esi), %es:(%edi) > + > +// CHECK: movsw # encoding: [0x66,0xa5] > +// CHECK: movsw > +// CHECK: movsw > + movsw > + movsw %ds:(%esi), %es:(%edi) > + movsw (%esi), %es:(%edi) > + > +// CHECK: movsl # encoding: [0xa5] > +// CHECK: movsl > +// CHECK: movsl > + movsl > + movsl %ds:(%esi), %es:(%edi) > + movsl (%esi), %es:(%edi) > + > +// CHECK: lodsb # encoding: [0xac] > +// CHECK: lodsb > +// CHECK: lodsb > +// CHECK: lodsb > +// CHECK: lodsb > + lodsb > + lodsb %ds:(%esi), %al > + lodsb (%esi), %al > + lods %ds:(%esi), %al > + lods (%esi), %al > + > +// CHECK: lodsw # encoding: [0x66,0xad] > +// CHECK: lodsw > +// CHECK: lodsw > +// CHECK: lodsw > +// CHECK: lodsw > + lodsw > + lodsw %ds:(%esi), %ax > + lodsw (%esi), %ax > + lods %ds:(%esi), %ax > + lods (%esi), %ax > + > +// CHECK: lodsl # encoding: [0xad] > +// CHECK: lodsl > +// CHECK: lodsl > +// CHECK: lodsl > +// CHECK: lodsl > + lodsl > + lodsl %ds:(%esi), %eax > + lodsl (%esi), %eax > + lods %ds:(%esi), %eax > + lods (%esi), %eax > + > +// CHECK: stosb # encoding: [0xaa] > +// CHECK: stosb > +// CHECK: stosb > + stosb > + stosb %al, %es:(%edi) > + stos %al, %es:(%edi) > + > +// CHECK: stosw # encoding: [0x66,0xab] > +// CHECK: stosw > +// CHECK: stosw > + stosw > + stosw %ax, %es:(%edi) > + stos %ax, %es:(%edi) > + > +// CHECK: stosl # encoding: [0xab] > +// CHECK: stosl > +// CHECK: stosl > + stosl > + stosl %eax, %es:(%edi) > + stos %eax, %es:(%edi) > Index: test/MC/X86/x86-64.s > =================================================================== > --- test/MC/X86/x86-64.s (revision 126955) > +++ test/MC/X86/x86-64.s (working copy) > @@ -973,3 +973,156 @@ > // CHECK: loopne 0 > // CHECK: encoding: [0xe0,A] > loopnz 0 > + > +// CHECK: outsb # encoding: [0x6e] > +// CHECK: outsb > +// CHECK: outsb > +// CHECK: outsb > +// CHECK: outsb > + outsb > + outsb %ds:(%rsi), (%dx) > + outsb %ds:(%rsi), %dx > + outsb (%rsi), (%dx) > + outsb (%rsi), %dx > + > +// CHECK: outsw # encoding: [0x66,0x6f] > +// CHECK: outsw > +// CHECK: outsw > +// CHECK: outsw > +// CHECK: outsw > + outsw > + outsw %ds:(%rsi), (%dx) > + outsw %ds:(%rsi), %dx > + outsw (%rsi), (%dx) > + outsw (%rsi), %dx > + > +// CHECK: outsl # encoding: [0x6f] > +// CHECK: outsl > +// CHECK: outsl > +// CHECK: outsl > + outsl > + outsl %ds:(%rsi), (%dx) > + outsl %ds:(%rsi), %dx > + outsl (%rsi), (%dx) > + outsl (%rsi), %dx > + > +// CHECK: insb # encoding: [0x6c] > +// CHECK: insb > +// CHECK: insb > + insb > + insb (%dx), %es:(%rdi) > + insb %dx, %es:(%rdi) > + > +// CHECK: insw # encoding: [0x66,0x6d] > +// CHECK: insw > +// CHECK: insw > + insw > + insw (%dx), %es:(%rdi) > + insw %dx, %es:(%rdi) > + > +// CHECK: insl # encoding: [0x6d] > +// CHECK: insl > +// CHECK: insl > + insl > + insl (%dx), %es:(%rdi) > + insl %dx, %es:(%rdi) > + > +// CHECK: movsb # encoding: [0xa4] > +// CHECK: movsb > +// CHECK: movsb > + movsb > + movsb %ds:(%rsi), %es:(%rdi) > + movsb (%rsi), %es:(%rdi) > + > +// CHECK: movsw # encoding: [0x66,0xa5] > +// CHECK: movsw > +// CHECK: movsw > + movsw > + movsw %ds:(%rsi), %es:(%rdi) > + movsw (%rsi), %es:(%rdi) > + > +// CHECK: movsl # encoding: [0xa5] > +// CHECK: movsl > +// CHECK: movsl > + movsl > + movsl %ds:(%rsi), %es:(%rdi) > + movsl (%rsi), %es:(%rdi) > + > +// CHECK: movsq # encoding: [0x48,0xa5] > +// CHECK: movsq > +// CHECK: movsq > + movsq > + movsq %ds:(%rsi), %es:(%rdi) > + movsq (%rsi), %es:(%rdi) > + > +// CHECK: lodsb # encoding: [0xac] > +// CHECK: lodsb > +// CHECK: lodsb > +// CHECK: lodsb > +// CHECK: lodsb > + lodsb > + lodsb %ds:(%rsi), %al > + lodsb (%rsi), %al > + lods %ds:(%rsi), %al > + lods (%rsi), %al > + > +// CHECK: lodsw # encoding: [0x66,0xad] > +// CHECK: lodsw > +// CHECK: lodsw > +// CHECK: lodsw > +// CHECK: lodsw > + lodsw > + lodsw %ds:(%rsi), %ax > + lodsw (%rsi), %ax > + lods %ds:(%rsi), %ax > + lods (%rsi), %ax > + > +// CHECK: lodsl # encoding: [0xad] > +// CHECK: lodsl > +// CHECK: lodsl > +// CHECK: lodsl > +// CHECK: lodsl > + lodsl > + lodsl %ds:(%rsi), %eax > + lodsl (%rsi), %eax > + lods %ds:(%rsi), %eax > + lods (%rsi), %eax > + > +// CHECK: lodsq # encoding: [0x48,0xad] > +// CHECK: lodsq > +// CHECK: lodsq > +// CHECK: lodsq > +// CHECK: lodsq > + lodsq > + lodsq %ds:(%rsi), %rax > + lodsq (%rsi), %rax > + lods %ds:(%rsi), %rax > + lods (%rsi), %rax > + > +// CHECK: stosb # encoding: [0xaa] > +// CHECK: stosb > +// CHECK: stosb > + stosb > + stosb %al, %es:(%rdi) > + stos %al, %es:(%rdi) > + > +// CHECK: stosw # encoding: [0x66,0xab] > +// CHECK: stosw > +// CHECK: stosw > + stosw > + stosw %ax, %es:(%rdi) > + stos %ax, %es:(%rdi) > + > +// CHECK: stosl # encoding: [0xab] > +// CHECK: stosl > +// CHECK: stosl > + stosl > + stosl %eax, %es:(%rdi) > + stos %eax, %es:(%rdi) > + > +// CHECK: stosq # encoding: [0x48,0xab] > +// CHECK: stosq > +// CHECK: stosq > + stosq > + stosq %rax, %es:(%rdi) > + stos %rax, %es:(%rdi) > Index: lib/Target/X86/AsmParser/X86AsmParser.cpp > =================================================================== > --- lib/Target/X86/AsmParser/X86AsmParser.cpp (revision 126955) > +++ lib/Target/X86/AsmParser/X86AsmParser.cpp (working copy) > @@ -38,6 +38,10 @@ > unsigned Is64Bit : 1; > > private: > + bool isSrcOp(X86Operand &Op); > + bool isDstOp(X86Operand &Op); > + bool isPortDxOp(X86Operand &Op); > + > MCAsmParser &getParser() const { return Parser; } > > MCAsmLexer &getLexer() const { return Parser.getLexer(); } > @@ -356,7 +360,32 @@ > > } // end anonymous namespace. > > +bool X86ATTAsmParser::isSrcOp(X86Operand &Op) { > + unsigned basereg = Is64Bit ? X86::RSI : X86::ESI; > > + return (Op.isMem() && > + (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) && > + isa(Op.Mem.Disp) && > + cast(Op.Mem.Disp)->getValue() == 0 && > + Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0); > +} > + > +bool X86ATTAsmParser::isDstOp(X86Operand &Op) { > + unsigned basereg = Is64Bit ? X86::RDI : X86::EDI; > + > + return Op.isMem() && Op.Mem.SegReg == X86::ES && > + isa(Op.Mem.Disp) && > + cast(Op.Mem.Disp)->getValue() == 0 && > + Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0; > +} > + > +bool X86ATTAsmParser::isPortDxOp(X86Operand &Op) { > + return Op.isMem() && Op.Mem.SegReg == 0 && > + isa(Op.Mem.Disp) && > + cast(Op.Mem.Disp)->getValue() == 0 && > + Op.Mem.BaseReg == X86::DX && Op.Mem.IndexReg == 0; > +} > + > bool X86ATTAsmParser::ParseRegister(unsigned &RegNo, > SMLoc &StartLoc, SMLoc &EndLoc) { > RegNo = 0; > @@ -788,7 +817,108 @@ > delete &Op; > } > } > - > + // Transform "ins[bwl] (%dx), %es:(%edi)" into "ins[bwl]" > + if (Name.startswith("ins") && Operands.size() == 3 && > + (Name == "insb" || Name == "insw" || Name == "insl")) { > + X86Operand &Op = *(X86Operand*)Operands.begin()[1]; > + X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; > + if ((isPortDxOp(Op) || (Op.isReg() && Op.getReg() == X86::DX)) && > + isDstOp(Op2)) { > + Operands.pop_back(); > + Operands.pop_back(); > + delete &Op; > + delete &Op2; > + } > + } > + > + // Transform "outs[bwl] %ds:(%esi), (%dx)" into "out[bwl]" > + if (Name.startswith("outs") && Operands.size() == 3 && > + (Name == "outsb" || Name == "outsw" || Name == "outsl")) { > + X86Operand &Op = *(X86Operand*)Operands.begin()[1]; > + X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; > + if (isSrcOp(Op) && > + (isPortDxOp(Op2) || (Op2.isReg() && Op2.getReg() == X86::DX))) { > + Operands.pop_back(); > + Operands.pop_back(); > + delete &Op; > + delete &Op2; > + } > + } > + > + // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]" > + if (Name.startswith("movs") && Operands.size() == 3 && > + (Name == "movsb" || Name == "movsw" || Name == "movsl" || > + (Is64Bit && Name == "movsq"))) { > + X86Operand &Op = *(X86Operand*)Operands.begin()[1]; > + X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; > + if (isSrcOp(Op) && isDstOp(Op2)) { > + Operands.pop_back(); > + Operands.pop_back(); > + delete &Op; > + delete &Op2; > + } > + } > + // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]" > + if (Name.startswith("lods") && Operands.size() == 3 && > + (Name == "lods" || Name == "lodsb" || Name == "lodsw" || > + Name == "lodsl" || (Is64Bit && Name == "lodsq"))) { > + X86Operand *Op1 = static_cast(Operands[1]); > + X86Operand *Op2 = static_cast(Operands[2]); > + if (isSrcOp(*Op1) && Op2->isReg()) { > + const char *ins; > + unsigned reg = Op2->getReg(); > + bool isLods = Name == "lods"; > + if (reg == X86::AL && (isLods || Name == "lodsb")) > + ins = "lodsb"; > + else if (reg == X86::AX && (isLods || Name == "lodsw")) > + ins = "lodsw"; > + else if (reg == X86::EAX && (isLods || Name == "lodsl")) > + ins = "lodsl"; > + else if (reg == X86::RAX && (isLods || Name == "lodsq")) > + ins = "lodsq"; > + else > + ins = NULL; > + if (ins != NULL) { > + Operands.pop_back(); > + Operands.pop_back(); > + delete Op1; > + delete Op2; > + if (Name != ins) > + static_cast(Operands[0])->setTokenValue(ins); > + } > + } > + } > + // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]" > + if (Name.startswith("stos") && Operands.size() == 3 && > + (Name == "stos" || Name == "stosb" || Name == "stosw" || > + Name == "stosl" || (Is64Bit && Name == "stosq"))) { > + X86Operand *Op1 = static_cast(Operands[1]); > + X86Operand *Op2 = static_cast(Operands[2]); > + if (isDstOp(*Op2) && Op1->isReg()) { > + const char *ins; > + unsigned reg = Op1->getReg(); > + bool isStos = Name == "stos"; > + if (reg == X86::AL && (isStos || Name == "stosb")) > + ins = "stosb"; > + else if (reg == X86::AX && (isStos || Name == "stosw")) > + ins = "stosw"; > + else if (reg == X86::EAX && (isStos || Name == "stosl")) > + ins = "stosl"; > + else if (reg == X86::RAX && (isStos || Name == "stosq")) > + ins = "stosq"; > + else > + ins = NULL; > + if (ins != NULL) { > + Operands.pop_back(); > + Operands.pop_back(); > + delete Op1; > + delete Op2; > + if (Name != ins) > + static_cast(Operands[0])->setTokenValue(ins); > + } > + } > + } > + > // FIXME: Hack to handle recognize s{hr,ar,hl} $1, . Canonicalize to > // "shift ". > if ((Name.startswith("shr") || Name.startswith("sar") || > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From justin.holewinski at gmail.com Mon Mar 14 10:40:11 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Mon, 14 Mar 2011 15:40:11 -0000 Subject: [llvm-commits] [llvm] r127584 - in /llvm/trunk: lib/Target/PTX/PTXAsmPrinter.cpp test/CodeGen/PTX/ld.ll test/CodeGen/PTX/st.ll Message-ID: <20110314154011.5883F2A6C12C@llvm.org> Author: jholewinski Date: Mon Mar 14 10:40:11 2011 New Revision: 127584 URL: http://llvm.org/viewvc/llvm-project?rev=127584&view=rev Log: PTX: Emit global arrays with proper sizes - Emit all arrays as type .b8 and proper sizes in bytes to conform to the output of nvcc Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp llvm/trunk/test/CodeGen/PTX/ld.ll llvm/trunk/test/CodeGen/PTX/st.ll Modified: llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp?rev=127584&r1=127583&r2=127584&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXAsmPrinter.cpp Mon Mar 14 10:40:11 2011 @@ -316,13 +316,42 @@ decl += " "; } - decl += getTypeName(gv->getType()); - decl += " "; - decl += gvsym->getName(); + if (PointerType::classof(gv->getType())) { + const PointerType* pointerTy = dyn_cast(gv->getType()); + const Type* elementTy = pointerTy->getElementType(); + + assert(elementTy->isArrayTy() && "Only pointers to arrays are supported"); + + const ArrayType* arrayTy = dyn_cast(elementTy); + elementTy = arrayTy->getElementType(); + + // FIXME: isPrimitiveType() == false for i16? + assert(elementTy->isSingleValueType() && + "Non-primitive types are not handled"); + + // Compute the size of the array, in bytes. + uint64_t arraySize = (elementTy->getPrimitiveSizeInBits() >> 3) + * arrayTy->getNumElements(); + + decl += ".b8 "; + decl += gvsym->getName(); + decl += "["; + decl += utostr(arraySize); + decl += "]"; + } + else { + // Note: this is currently the fall-through case and most likely generates + // incorrect code. + decl += getTypeName(gv->getType()); + decl += " "; - if (ArrayType::classof(gv->getType()) || PointerType::classof(gv->getType())) - decl += "[]"; + decl += gvsym->getName(); + + if (ArrayType::classof(gv->getType()) || + PointerType::classof(gv->getType())) + decl += "[]"; + } decl += ";"; Modified: llvm/trunk/test/CodeGen/PTX/ld.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/ld.ll?rev=127584&r1=127583&r2=127584&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/ld.ll (original) +++ llvm/trunk/test/CodeGen/PTX/ld.ll Mon Mar 14 10:40:11 2011 @@ -1,63 +1,63 @@ ; RUN: llc < %s -march=ptx | FileCheck %s -;CHECK: .extern .global .u16 array_i16[]; +;CHECK: .extern .global .b8 array_i16[20]; @array_i16 = external global [10 x i16] -;CHECK: .extern .const .u16 array_constant_i16[]; +;CHECK: .extern .const .b8 array_constant_i16[20]; @array_constant_i16 = external addrspace(1) constant [10 x i16] -;CHECK: .extern .local .u16 array_local_i16[]; +;CHECK: .extern .local .b8 array_local_i16[20]; @array_local_i16 = external addrspace(2) global [10 x i16] -;CHECK: .extern .shared .u16 array_shared_i16[]; +;CHECK: .extern .shared .b8 array_shared_i16[20]; @array_shared_i16 = external addrspace(4) global [10 x i16] -;CHECK: .extern .global .u32 array_i32[]; +;CHECK: .extern .global .b8 array_i32[40]; @array_i32 = external global [10 x i32] -;CHECK: .extern .const .u32 array_constant_i32[]; +;CHECK: .extern .const .b8 array_constant_i32[40]; @array_constant_i32 = external addrspace(1) constant [10 x i32] -;CHECK: .extern .local .u32 array_local_i32[]; +;CHECK: .extern .local .b8 array_local_i32[40]; @array_local_i32 = external addrspace(2) global [10 x i32] -;CHECK: .extern .shared .u32 array_shared_i32[]; +;CHECK: .extern .shared .b8 array_shared_i32[40]; @array_shared_i32 = external addrspace(4) global [10 x i32] -;CHECK: .extern .global .u64 array_i64[]; +;CHECK: .extern .global .b8 array_i64[80]; @array_i64 = external global [10 x i64] -;CHECK: .extern .const .u64 array_constant_i64[]; +;CHECK: .extern .const .b8 array_constant_i64[80]; @array_constant_i64 = external addrspace(1) constant [10 x i64] -;CHECK: .extern .local .u64 array_local_i64[]; +;CHECK: .extern .local .b8 array_local_i64[80]; @array_local_i64 = external addrspace(2) global [10 x i64] -;CHECK: .extern .shared .u64 array_shared_i64[]; +;CHECK: .extern .shared .b8 array_shared_i64[80]; @array_shared_i64 = external addrspace(4) global [10 x i64] -;CHECK: .extern .global .f32 array_float[]; +;CHECK: .extern .global .b8 array_float[40]; @array_float = external global [10 x float] -;CHECK: .extern .const .f32 array_constant_float[]; +;CHECK: .extern .const .b8 array_constant_float[40]; @array_constant_float = external addrspace(1) constant [10 x float] -;CHECK: .extern .local .f32 array_local_float[]; +;CHECK: .extern .local .b8 array_local_float[40]; @array_local_float = external addrspace(2) global [10 x float] -;CHECK: .extern .shared .f32 array_shared_float[]; +;CHECK: .extern .shared .b8 array_shared_float[40]; @array_shared_float = external addrspace(4) global [10 x float] -;CHECK: .extern .global .f64 array_double[]; +;CHECK: .extern .global .b8 array_double[80]; @array_double = external global [10 x double] -;CHECK: .extern .const .f64 array_constant_double[]; +;CHECK: .extern .const .b8 array_constant_double[80]; @array_constant_double = external addrspace(1) constant [10 x double] -;CHECK: .extern .local .f64 array_local_double[]; +;CHECK: .extern .local .b8 array_local_double[80]; @array_local_double = external addrspace(2) global [10 x double] -;CHECK: .extern .shared .f64 array_shared_double[]; +;CHECK: .extern .shared .b8 array_shared_double[80]; @array_shared_double = external addrspace(4) global [10 x double] Modified: llvm/trunk/test/CodeGen/PTX/st.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/st.ll?rev=127584&r1=127583&r2=127584&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/st.ll (original) +++ llvm/trunk/test/CodeGen/PTX/st.ll Mon Mar 14 10:40:11 2011 @@ -1,63 +1,63 @@ ; RUN: llc < %s -march=ptx | FileCheck %s -;CHECK: .extern .global .u16 array_i16[]; +;CHECK: .extern .global .b8 array_i16[20]; @array_i16 = external global [10 x i16] -;CHECK: .extern .const .u16 array_constant_i16[]; +;CHECK: .extern .const .b8 array_constant_i16[20]; @array_constant_i16 = external addrspace(1) constant [10 x i16] -;CHECK: .extern .local .u16 array_local_i16[]; +;CHECK: .extern .local .b8 array_local_i16[20]; @array_local_i16 = external addrspace(2) global [10 x i16] -;CHECK: .extern .shared .u16 array_shared_i16[]; +;CHECK: .extern .shared .b8 array_shared_i16[20]; @array_shared_i16 = external addrspace(4) global [10 x i16] -;CHECK: .extern .global .u32 array_i32[]; +;CHECK: .extern .global .b8 array_i32[40]; @array_i32 = external global [10 x i32] -;CHECK: .extern .const .u32 array_constant_i32[]; +;CHECK: .extern .const .b8 array_constant_i32[40]; @array_constant_i32 = external addrspace(1) constant [10 x i32] -;CHECK: .extern .local .u32 array_local_i32[]; +;CHECK: .extern .local .b8 array_local_i32[40]; @array_local_i32 = external addrspace(2) global [10 x i32] -;CHECK: .extern .shared .u32 array_shared_i32[]; +;CHECK: .extern .shared .b8 array_shared_i32[40]; @array_shared_i32 = external addrspace(4) global [10 x i32] -;CHECK: .extern .global .u64 array_i64[]; +;CHECK: .extern .global .b8 array_i64[80]; @array_i64 = external global [10 x i64] -;CHECK: .extern .const .u64 array_constant_i64[]; +;CHECK: .extern .const .b8 array_constant_i64[80]; @array_constant_i64 = external addrspace(1) constant [10 x i64] -;CHECK: .extern .local .u64 array_local_i64[]; +;CHECK: .extern .local .b8 array_local_i64[80]; @array_local_i64 = external addrspace(2) global [10 x i64] -;CHECK: .extern .shared .u64 array_shared_i64[]; +;CHECK: .extern .shared .b8 array_shared_i64[80]; @array_shared_i64 = external addrspace(4) global [10 x i64] -;CHECK: .extern .global .f32 array_float[]; +;CHECK: .extern .global .b8 array_float[40]; @array_float = external global [10 x float] -;CHECK: .extern .const .f32 array_constant_float[]; +;CHECK: .extern .const .b8 array_constant_float[40]; @array_constant_float = external addrspace(1) constant [10 x float] -;CHECK: .extern .local .f32 array_local_float[]; +;CHECK: .extern .local .b8 array_local_float[40]; @array_local_float = external addrspace(2) global [10 x float] -;CHECK: .extern .shared .f32 array_shared_float[]; +;CHECK: .extern .shared .b8 array_shared_float[40]; @array_shared_float = external addrspace(4) global [10 x float] -;CHECK: .extern .global .f64 array_double[]; +;CHECK: .extern .global .b8 array_double[80]; @array_double = external global [10 x double] -;CHECK: .extern .const .f64 array_constant_double[]; +;CHECK: .extern .const .b8 array_constant_double[80]; @array_constant_double = external addrspace(1) constant [10 x double] -;CHECK: .extern .local .f64 array_local_double[]; +;CHECK: .extern .local .b8 array_local_double[80]; @array_local_double = external addrspace(2) global [10 x double] -;CHECK: .extern .shared .f64 array_shared_double[]; +;CHECK: .extern .shared .b8 array_shared_double[80]; @array_shared_double = external addrspace(4) global [10 x double] From atrick at apple.com Mon Mar 14 11:48:10 2011 From: atrick at apple.com (Andrew Trick) Date: Mon, 14 Mar 2011 16:48:10 -0000 Subject: [llvm-commits] [llvm] r127589 - /llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Message-ID: <20110314164810.6BD272A6C12C@llvm.org> Author: atrick Date: Mon Mar 14 11:48:10 2011 New Revision: 127589 URL: http://llvm.org/viewvc/llvm-project?rev=127589&view=rev Log: whitespace Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=127589&r1=127588&r2=127589&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Mon Mar 14 11:48:10 2011 @@ -81,7 +81,7 @@ bool processLoopStore(StoreInst *SI, const SCEV *BECount); bool processLoopMemSet(MemSetInst *MSI, const SCEV *BECount); - + bool processLoopStridedStore(Value *DestPtr, unsigned StoreSize, unsigned StoreAlignment, Value *SplatValue, Instruction *TheStore, @@ -91,7 +91,7 @@ const SCEVAddRecExpr *StoreEv, const SCEVAddRecExpr *LoadEv, const SCEV *BECount); - + /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG. /// @@ -134,50 +134,50 @@ /// static void DeleteDeadInstruction(Instruction *I, ScalarEvolution &SE) { SmallVector NowDeadInsts; - + NowDeadInsts.push_back(I); - + // Before we touch this instruction, remove it from SE! do { Instruction *DeadInst = NowDeadInsts.pop_back_val(); - + // This instruction is dead, zap it, in stages. Start by removing it from // SCEV. SE.forgetValue(DeadInst); - + for (unsigned op = 0, e = DeadInst->getNumOperands(); op != e; ++op) { Value *Op = DeadInst->getOperand(op); DeadInst->setOperand(op, 0); - + // If this operand just became dead, add it to the NowDeadInsts list. if (!Op->use_empty()) continue; - + if (Instruction *OpI = dyn_cast(Op)) if (isInstructionTriviallyDead(OpI)) NowDeadInsts.push_back(OpI); } - + DeadInst->eraseFromParent(); - + } while (!NowDeadInsts.empty()); } bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) { CurLoop = L; - + // The trip count of the loop must be analyzable. SE = &getAnalysis(); if (!SE->hasLoopInvariantBackedgeTakenCount(L)) return false; const SCEV *BECount = SE->getBackedgeTakenCount(L); if (isa(BECount)) return false; - + // If this loop executes exactly one time, then it should be peeled, not // optimized by this pass. if (const SCEVConstant *BECst = dyn_cast(BECount)) if (BECst->getValue()->getValue() == 0) return false; - + // We require target data for now. TD = getAnalysisIfAvailable(); if (TD == 0) return false; @@ -185,14 +185,14 @@ DT = &getAnalysis(); LoopInfo &LI = getAnalysis(); TLI = &getAnalysis(); - + SmallVector ExitBlocks; CurLoop->getUniqueExitBlocks(ExitBlocks); DEBUG(dbgs() << "loop-idiom Scanning: F[" << L->getHeader()->getParent()->getName() << "] Loop %" << L->getHeader()->getName() << "\n"); - + bool MadeChange = false; // Scan all the blocks in the loop that are not in subloops. for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; @@ -200,7 +200,7 @@ // Ignore blocks in subloops. if (LI.getLoopFor(*BI) != CurLoop) continue; - + MadeChange |= runOnLoopBlock(*BI, BECount, ExitBlocks); } return MadeChange; @@ -217,7 +217,7 @@ for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) if (!DT->dominates(BB, ExitBlocks[i])) return false; - + bool MadeChange = false; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { Instruction *Inst = I++; @@ -226,20 +226,20 @@ WeakVH InstPtr(I); if (!processLoopStore(SI, BECount)) continue; MadeChange = true; - + // If processing the store invalidated our iterator, start over from the // top of the block. if (InstPtr == 0) I = BB->begin(); continue; } - + // Look for memset instructions, which may be optimized to a larger memset. if (MemSetInst *MSI = dyn_cast(Inst)) { WeakVH InstPtr(I); if (!processLoopMemSet(MSI, BECount)) continue; MadeChange = true; - + // If processing the memset invalidated our iterator, start over from the // top of the block. if (InstPtr == 0) @@ -247,7 +247,7 @@ continue; } } - + return MadeChange; } @@ -258,12 +258,12 @@ Value *StoredVal = SI->getValueOperand(); Value *StorePtr = SI->getPointerOperand(); - + // Reject stores that are so large that they overflow an unsigned. uint64_t SizeInBits = TD->getTypeSizeInBits(StoredVal->getType()); if ((SizeInBits & 7) || (SizeInBits >> 32) != 0) return false; - + // See if the pointer expression is an AddRec like {base,+,1} on the current // loop, which indicates a strided store. If we have something else, it's a // random store we can't handle. @@ -274,9 +274,9 @@ // Check to see if the stride matches the size of the store. If so, then we // know that every byte is touched in the loop. - unsigned StoreSize = (unsigned)SizeInBits >> 3; + unsigned StoreSize = (unsigned)SizeInBits >> 3; const SCEVConstant *Stride = dyn_cast(StoreEv->getOperand(1)); - + if (Stride == 0 || StoreSize != Stride->getValue()->getValue()) { // TODO: Could also handle negative stride here someday, that will require // the validity check in mayLoopAccessLocation to be updated though. @@ -285,7 +285,7 @@ dbgs() << "NEGATIVE STRIDE: " << *SI << "\n"; dbgs() << "BB: " << *SI->getParent(); } - + return false; } @@ -319,9 +319,9 @@ // If we're not allowed to hack on memset, we fail. if (!TLI->has(LibFunc::memset)) return false; - + Value *Pointer = MSI->getDest(); - + // See if the pointer expression is an AddRec like {base,+,1} on the current // loop, which indicates a strided store. If we have something else, it's a // random store we can't handle. @@ -333,16 +333,16 @@ uint64_t SizeInBytes = cast(MSI->getLength())->getZExtValue(); if ((SizeInBytes >> 32) != 0) return false; - + // Check to see if the stride matches the size of the memset. If so, then we // know that every byte is touched in the loop. const SCEVConstant *Stride = dyn_cast(Ev->getOperand(1)); - + // TODO: Could also handle negative stride here someday, that will require the // validity check in mayLoopAccessLocation to be updated though. if (Stride == 0 || MSI->getLength() != Stride->getValue()) return false; - + return processLoopStridedStore(Pointer, (unsigned)SizeInBytes, MSI->getAlignment(), MSI->getValue(), MSI, Ev, BECount); @@ -365,7 +365,7 @@ // to be exactly the size of the memset, which is (BECount+1)*StoreSize if (const SCEVConstant *BECst = dyn_cast(BECount)) AccessSize = (BECst->getValue()->getZExtValue()+1)*StoreSize; - + // TODO: For this to be really effective, we have to dive into the pointer // operand in the store. Store to &A[i] of 100 will always return may alias // with store of &A[100], we need to StoreLoc to be "A" with size of 100, @@ -394,12 +394,12 @@ // that doesn't seem worthwhile. Constant *C = dyn_cast(V); if (C == 0) return 0; - + // Only handle simple values that are a power of two bytes in size. uint64_t Size = TD.getTypeSizeInBits(V->getType()); if (Size == 0 || (Size & 7) || (Size & (Size-1))) return 0; - + // Don't care enough about darwin/ppc to implement this. if (TD.isBigEndian()) return 0; @@ -410,7 +410,7 @@ // TODO: If CI is larger than 16-bytes, we can try slicing it in half to see // if the top and bottom are the same (e.g. for vectors and large integers). if (Size > 16) return 0; - + // If the constant is exactly 16 bytes, just use it. if (Size == 16) return C; @@ -428,14 +428,14 @@ unsigned StoreAlignment, Value *StoredVal, Instruction *TheStore, const SCEVAddRecExpr *Ev, const SCEV *BECount) { - + // If the stored value is a byte-wise value (like i32 -1), then it may be // turned into a memset of i8 -1, assuming that all the consecutive bytes // are stored. A store of i32 0x01020304 can never be turned into a memset, // but it can be turned into memset_pattern if the target supports it. Value *SplatValue = isBytewiseValue(StoredVal); Constant *PatternValue = 0; - + // If we're allowed to form a memset, and the stored value would be acceptable // for memset, use it. if (SplatValue && TLI->has(LibFunc::memset) && @@ -453,8 +453,8 @@ // do anything with a 3-byte store, for example. return false; } - - + + // Okay, we have a strided store "p[i]" of a splattable value. We can turn // this into a memset in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read @@ -463,36 +463,36 @@ CurLoop, BECount, StoreSize, getAnalysis(), TheStore)) return false; - + // Okay, everything looks good, insert the memset. BasicBlock *Preheader = CurLoop->getLoopPreheader(); - + IRBuilder<> Builder(Preheader->getTerminator()); - + // The trip count of the loop and the base pointer of the addrec SCEV is // guaranteed to be loop invariant, which means that it should dominate the // header. Just insert code for it in the preheader. SCEVExpander Expander(*SE); - + unsigned AddrSpace = cast(DestPtr->getType())->getAddressSpace(); - Value *BasePtr = + Value *BasePtr = Expander.expandCodeFor(Ev->getStart(), Builder.getInt8PtrTy(AddrSpace), Preheader->getTerminator()); - + // The # stored bytes is (BECount+1)*Size. Expand the trip count out to // pointer size if it isn't already. const Type *IntPtr = TD->getIntPtrType(DestPtr->getContext()); BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr); - + const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), true /*no unsigned overflow*/); if (StoreSize != 1) NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize), true /*no unsigned overflow*/); - - Value *NumBytes = + + Value *NumBytes = Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); - + CallInst *NewCall; if (SplatValue) NewCall = Builder.CreateMemSet(BasePtr, SplatValue,NumBytes,StoreAlignment); @@ -500,10 +500,10 @@ Module *M = TheStore->getParent()->getParent()->getParent(); Value *MSP = M->getOrInsertFunction("memset_pattern16", Builder.getVoidTy(), - Builder.getInt8PtrTy(), + Builder.getInt8PtrTy(), Builder.getInt8PtrTy(), IntPtr, (void*)0); - + // Otherwise we should form a memset_pattern16. PatternValue is known to be // an constant array of 16-bytes. Plop the value into a mergable global. GlobalVariable *GV = new GlobalVariable(*M, PatternValue->getType(), true, @@ -514,11 +514,11 @@ Value *PatternPtr = ConstantExpr::getBitCast(GV, Builder.getInt8PtrTy()); NewCall = Builder.CreateCall3(MSP, BasePtr, PatternPtr, NumBytes); } - + DEBUG(dbgs() << " Formed memset: " << *NewCall << "\n" << " from store to: " << *Ev << " at: " << *TheStore << "\n"); NewCall->setDebugLoc(TheStore->getDebugLoc()); - + // Okay, the memset has been formed. Zap the original store and anything that // feeds into it. DeleteDeadInstruction(TheStore, *SE); @@ -536,9 +536,9 @@ // If we're not allowed to form memcpy, we fail. if (!TLI->has(LibFunc::memcpy)) return false; - + LoadInst *LI = cast(SI->getValueOperand()); - + // Okay, we have a strided store "p[i]" of a loaded value. We can turn // this into a memcpy in the loop preheader now if we want. However, this // would be unsafe to do if there is anything else in the loop that may read @@ -555,49 +555,49 @@ CurLoop, BECount, StoreSize, getAnalysis(), SI)) return false; - + // Okay, everything looks good, insert the memcpy. BasicBlock *Preheader = CurLoop->getLoopPreheader(); - + IRBuilder<> Builder(Preheader->getTerminator()); - + // The trip count of the loop and the base pointer of the addrec SCEV is // guaranteed to be loop invariant, which means that it should dominate the // header. Just insert code for it in the preheader. SCEVExpander Expander(*SE); - Value *LoadBasePtr = + Value *LoadBasePtr = Expander.expandCodeFor(LoadEv->getStart(), Builder.getInt8PtrTy(LI->getPointerAddressSpace()), Preheader->getTerminator()); - Value *StoreBasePtr = + Value *StoreBasePtr = Expander.expandCodeFor(StoreEv->getStart(), Builder.getInt8PtrTy(SI->getPointerAddressSpace()), Preheader->getTerminator()); - + // The # stored bytes is (BECount+1)*Size. Expand the trip count out to // pointer size if it isn't already. const Type *IntPtr = TD->getIntPtrType(SI->getContext()); BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr); - + const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), true /*no unsigned overflow*/); if (StoreSize != 1) NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize), true /*no unsigned overflow*/); - + Value *NumBytes = Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); - + Value *NewCall = Builder.CreateMemCpy(StoreBasePtr, LoadBasePtr, NumBytes, std::min(SI->getAlignment(), LI->getAlignment())); - + DEBUG(dbgs() << " Formed memcpy: " << *NewCall << "\n" << " from load ptr=" << *LoadEv << " at: " << *LI << "\n" << " from store ptr=" << *StoreEv << " at: " << *SI << "\n"); (void)NewCall; - + // Okay, the memset has been formed. Zap the original store and anything that // feeds into it. DeleteDeadInstruction(SI, *SE); From atrick at apple.com Mon Mar 14 11:50:06 2011 From: atrick at apple.com (Andrew Trick) Date: Mon, 14 Mar 2011 16:50:06 -0000 Subject: [llvm-commits] [llvm] r127590 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h include/llvm/Analysis/ScalarEvolutionExpressions.h lib/Analysis/ScalarEvolution.cpp lib/Analysis/ScalarEvolutionExpander.cpp lib/Analysis/ScalarEvolutionNormalization.cpp lib/Transforms/Scalar/LoopIdiomRecognize.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <20110314165007.069952A6C12C@llvm.org> Author: atrick Date: Mon Mar 14 11:50:06 2011 New Revision: 127590 URL: http://llvm.org/viewvc/llvm-project?rev=127590&view=rev Log: Added SCEV::NoWrapFlags to manage unsigned, signed, and self wrap properties. Added the self-wrap flag for SCEV::AddRecExpr. A slew of temporary FIXMEs indicate the intention of the no-self-wrap flag without changing behavior in this revision. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp llvm/trunk/lib/Analysis/ScalarEvolutionNormalization.cpp llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=127590&r1=127589&r2=127590&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Mon Mar 14 11:50:06 2011 @@ -72,6 +72,29 @@ void operator=(const SCEV &); // DO NOT IMPLEMENT public: + /// NoWrapFlags are bitfield indices into SubclassData. + /// + /// Add and Mul expressions may have no-unsigned-wrap or + /// no-signed-wrap properties, which are derived from the IR + /// operator. NSW is a misnomer that we use to mean no signed overflow or + /// underflow. + /// + /// AddRec expression may have a no-self-wraparound property if the + /// result can never reach the start value. This property is independent of + /// the actual start value and step direction. Self-wraparound is defined + /// purely in terms of the recurrence's loop, step size, and + /// bitwidth. Formally, a recurrence with no self-wraparound satisfies: + /// abs(step) * max-iteration(loop) <= unsigned-max(bitwidth). + /// + /// Note that NUW and NSW are also valid properties of a recurrence, and + /// either implies NW. For convenience, NW will be set for a recurrence + /// whenever either NUW or NSW are set. + enum NoWrapFlags { FlagAnyWrap = 0, // No guarantee. + FlagNW = (1 << 0), // No self-wrap. + FlagNUW = (1 << 1), // No unsigned wrap. + FlagNSW = (1 << 2), // No signed wrap. + NoWrapMask = (1 << 3) -1 }; + explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) : FastID(ID), SCEVType(SCEVTy), SubclassData(0) {} @@ -159,6 +182,20 @@ ProperlyDominatesBlock ///< The SCEV properly dominates the block. }; + /// Convenient NoWrapFlags manipulation that hides enum casts and is + /// visible in the ScalarEvolution name space. + static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags, int Mask) { + return (SCEV::NoWrapFlags)(Flags & Mask); + } + static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags, + SCEV::NoWrapFlags OnFlags) { + return (SCEV::NoWrapFlags)(Flags | OnFlags); + } + static SCEV::NoWrapFlags clearFlags(SCEV::NoWrapFlags Flags, + SCEV::NoWrapFlags OffFlags) { + return (SCEV::NoWrapFlags)(Flags & ~OffFlags); + } + private: /// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be /// notified whenever a Value is deleted. @@ -465,44 +502,41 @@ const SCEV *getSignExtendExpr(const SCEV *Op, const Type *Ty); const SCEV *getAnyExtendExpr(const SCEV *Op, const Type *Ty); const SCEV *getAddExpr(SmallVectorImpl &Ops, - bool HasNUW = false, bool HasNSW = false); + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS, - bool HasNUW = false, bool HasNSW = false) { + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { SmallVector Ops; Ops.push_back(LHS); Ops.push_back(RHS); - return getAddExpr(Ops, HasNUW, HasNSW); + return getAddExpr(Ops, Flags); } - const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, - const SCEV *Op2, - bool HasNUW = false, bool HasNSW = false) { + const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { SmallVector Ops; Ops.push_back(Op0); Ops.push_back(Op1); Ops.push_back(Op2); - return getAddExpr(Ops, HasNUW, HasNSW); + return getAddExpr(Ops, Flags); } const SCEV *getMulExpr(SmallVectorImpl &Ops, - bool HasNUW = false, bool HasNSW = false); + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS, - bool HasNUW = false, bool HasNSW = false) { + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) + { SmallVector Ops; Ops.push_back(LHS); Ops.push_back(RHS); - return getMulExpr(Ops, HasNUW, HasNSW); + return getMulExpr(Ops, Flags); } const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step, - const Loop *L, - bool HasNUW = false, bool HasNSW = false); + const Loop *L, SCEV::NoWrapFlags Flags); const SCEV *getAddRecExpr(SmallVectorImpl &Operands, - const Loop *L, - bool HasNUW = false, bool HasNSW = false); + const Loop *L, SCEV::NoWrapFlags Flags); const SCEV *getAddRecExpr(const SmallVectorImpl &Operands, - const Loop *L, - bool HasNUW = false, bool HasNSW = false) { + const Loop *L, SCEV::NoWrapFlags Flags) { SmallVector NewOp(Operands.begin(), Operands.end()); - return getAddRecExpr(NewOp, L, HasNUW, HasNSW); + return getAddRecExpr(NewOp, L, Flags); } const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getSMaxExpr(SmallVectorImpl &Operands); @@ -537,11 +571,9 @@ /// const SCEV *getNotSCEV(const SCEV *V); - /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1, - /// and thus the HasNUW and HasNSW bits apply to the resultant add, not - /// whether the sub would have overflowed. + /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1. const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS, - bool HasNUW = false, bool HasNSW = false); + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion /// of the input value to the specified type. If the type must be Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h?rev=127590&r1=127589&r2=127590&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h Mon Mar 14 11:50:06 2011 @@ -160,13 +160,8 @@ const Type *getType() const { return getOperand(0)->getType(); } - bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); } - void setHasNoUnsignedWrap(bool B) { - SubclassData = (SubclassData & ~(1 << 0)) | (B << 0); - } - bool hasNoSignedWrap() const { return SubclassData & (1 << 1); } - void setHasNoSignedWrap(bool B) { - SubclassData = (SubclassData & ~(1 << 1)) | (B << 1); + NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const { + return (NoWrapFlags)(SubclassData & Mask); } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -199,6 +194,11 @@ S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr; } + + /// Set flags for a non-recurrence without clearing previously set flags. + void setNoWrapFlags(NoWrapFlags Flags) { + SubclassData |= Flags; + } }; @@ -305,11 +305,12 @@ /// getStepRecurrence - This method constructs and returns the recurrence /// indicating how much this expression steps by. If this is a polynomial /// of degree N, it returns a chrec of degree N-1. + /// We cannot determine whether the step recurrence has self-wraparound. const SCEV *getStepRecurrence(ScalarEvolution &SE) const { if (isAffine()) return getOperand(1); return SE.getAddRecExpr(SmallVector(op_begin()+1, op_end()), - getLoop()); + getLoop(), FlagAnyWrap); } /// isAffine - Return true if this is an affine AddRec (i.e., it represents @@ -327,6 +328,15 @@ return getNumOperands() == 3; } + /// Set flags for a recurrence without clearing any previously set flags. + /// For AddRec, either NUW or NSW implies NW. Keep track of this fact here + /// to make it easier to propagate flags. + void setNoWrapFlags(NoWrapFlags Flags) { + if (Flags & (FlagNUW | FlagNSW)) + Flags = ScalarEvolution::setFlags(Flags, FlagNW); + SubclassData |= Flags; + } + /// evaluateAtIteration - Return the value of this chain of recurrences at /// the specified iteration number. const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const; @@ -364,8 +374,7 @@ const SCEV *const *O, size_t N) : SCEVCommutativeExpr(ID, scSMaxExpr, O, N) { // Max never overflows. - setHasNoUnsignedWrap(true); - setHasNoSignedWrap(true); + setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW)); } public: @@ -387,8 +396,7 @@ const SCEV *const *O, size_t N) : SCEVCommutativeExpr(ID, scUMaxExpr, O, N) { // Max never overflows. - setHasNoUnsignedWrap(true); - setHasNoSignedWrap(true); + setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW)); } public: Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127590&r1=127589&r2=127590&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 14 11:50:06 2011 @@ -157,10 +157,13 @@ for (unsigned i = 1, e = AR->getNumOperands(); i != e; ++i) OS << ",+," << *AR->getOperand(i); OS << "}<"; - if (AR->hasNoUnsignedWrap()) + if (AR->getNoWrapFlags(FlagNUW)) OS << "nuw><"; - if (AR->hasNoSignedWrap()) + if (AR->getNoWrapFlags(FlagNSW)) OS << "nsw><"; + if (AR->getNoWrapFlags(FlagNW) && + !AR->getNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW))) + OS << "nw><"; WriteAsOperand(OS, AR->getLoop()->getHeader(), /*PrintType=*/false); OS << ">"; return; @@ -830,7 +833,7 @@ Operands.push_back(S); } if (!hasTrunc) - return getAddExpr(Operands, false, false); + return getAddExpr(Operands); UniqueSCEVs.FindNodeOrInsertPos(ID, IP); // Mutates IP, returns NULL. } @@ -845,7 +848,7 @@ Operands.push_back(S); } if (!hasTrunc) - return getMulExpr(Operands, false, false); + return getMulExpr(Operands); UniqueSCEVs.FindNodeOrInsertPos(ID, IP); // Mutates IP, returns NULL. } @@ -854,7 +857,7 @@ SmallVector Operands; for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) Operands.push_back(getTruncateExpr(AddRec->getOperand(i), Ty)); - return getAddRecExpr(Operands, AddRec->getLoop()); + return getAddRecExpr(Operands, AddRec->getLoop(), SCEV::FlagAnyWrap); } // As a special case, fold trunc(undef) to undef. We don't want to @@ -926,10 +929,11 @@ // If we have special knowledge that this addrec won't overflow, // we don't need to do any further analysis. - if (AR->hasNoUnsignedWrap()) + if (AR->getNoWrapFlags(SCEV::FlagNUW)) return getAddRecExpr(getZeroExtendExpr(Start, Ty), getZeroExtendExpr(Step, Ty), - L); + // FIXME: Can use SCEV::FlagNUW + L, SCEV::FlagAnyWrap); // Check whether the backedge-taken count is SCEVCouldNotCompute. // Note that this serves two purposes: It filters out loops that are @@ -963,7 +967,8 @@ // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), getZeroExtendExpr(Step, Ty), - L); + // FIXME: can use FlagNUW + L, SCEV::FlagAnyWrap); // Similar to above, only this time treat the step value as signed. // This covers loops that count down. @@ -977,7 +982,8 @@ // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - L); + // FIXME: can use FlagNW + L, SCEV::FlagAnyWrap); } // If the backedge is guarded by a comparison with the pre-inc value @@ -994,7 +1000,8 @@ // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), getZeroExtendExpr(Step, Ty), - L); + // FIXME: can use FlagNUW + L, SCEV::FlagAnyWrap); } else if (isKnownNegative(Step)) { const SCEV *N = getConstant(APInt::getMaxValue(BitWidth) - getSignedRange(Step).getSignedMin()); @@ -1002,10 +1009,12 @@ (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_UGT, Start, N) && isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT, AR->getPostIncExpr(*this), N))) - // Return the expression with the addrec on the outside. + // Return the expression with the addrec on the outside. The + // negative step causes unsigned wrap, but it still can't self-wrap. return getAddRecExpr(getZeroExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - L); + // FIXME: can use FlagNW + L, SCEV::FlagAnyWrap); } } } @@ -1080,10 +1089,11 @@ // If we have special knowledge that this addrec won't overflow, // we don't need to do any further analysis. - if (AR->hasNoSignedWrap()) + if (AR->getNoWrapFlags(SCEV::FlagNSW)) return getAddRecExpr(getSignExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - L); + // FIXME: can use SCEV::FlagNSW + L, SCEV::FlagAnyWrap); // Check whether the backedge-taken count is SCEVCouldNotCompute. // Note that this serves two purposes: It filters out loops that are @@ -1117,7 +1127,8 @@ // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - L); + // FIXME: can use SCEV::FlagNSW + L, SCEV::FlagAnyWrap); // Similar to above, only this time treat the step value as unsigned. // This covers loops that count up with an unsigned step. @@ -1131,7 +1142,8 @@ // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), getZeroExtendExpr(Step, Ty), - L); + // FIXME: can use SCEV::FlagNSW + L, SCEV::FlagAnyWrap); } // If the backedge is guarded by a comparison with the pre-inc value @@ -1148,7 +1160,8 @@ // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - L); + // FIXME: can use SCEV::FlagNSW + L, SCEV::FlagAnyWrap); } else if (isKnownNegative(Step)) { const SCEV *N = getConstant(APInt::getSignedMaxValue(BitWidth) - getSignedRange(Step).getSignedMin()); @@ -1159,7 +1172,8 @@ // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - L); + // FIXME: can use SCEV::FlagNSW + L, SCEV::FlagAnyWrap); } } } @@ -1213,7 +1227,8 @@ for (SCEVAddRecExpr::op_iterator I = AR->op_begin(), E = AR->op_end(); I != E; ++I) Ops.push_back(getAnyExtendExpr(*I, Ty)); - return getAddRecExpr(Ops, AR->getLoop()); + // FIXME: can use AR->getNoWrapFlags(SCEV::FlagNW) + return getAddRecExpr(Ops, AR->getLoop(), SCEV::FlagAnyWrap); } // As a special case, fold anyext(undef) to undef. We don't want to @@ -1334,7 +1349,9 @@ /// getAddExpr - Get a canonical add expression, or something simpler if /// possible. const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl &Ops, - bool HasNUW, bool HasNSW) { + SCEV::NoWrapFlags Flags) { + assert(!(Flags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) && + "only nuw or nsw allowed"); assert(!Ops.empty() && "Cannot get empty add!"); if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG @@ -1344,8 +1361,8 @@ "SCEVAddExpr operand types don't match!"); #endif - // If HasNSW is true and all the operands are non-negative, infer HasNUW. - if (!HasNUW && HasNSW) { + // If FlagNSW is true and all the operands are non-negative, infer FlagNUW. + if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) { bool All = true; for (SmallVectorImpl::const_iterator I = Ops.begin(), E = Ops.end(); I != E; ++I) @@ -1353,7 +1370,7 @@ All = false; break; } - if (All) HasNUW = true; + if (All) Flags = setFlags(Flags, SCEV::FlagNUW); } // Sort by complexity, this groups all similar expression types together. @@ -1404,7 +1421,7 @@ FoundMatch = true; } if (FoundMatch) - return getAddExpr(Ops, HasNUW, HasNSW); + return getAddExpr(Ops, Flags); // Check for truncates. If all the operands are truncated from the same // type, see if factoring out the truncate would permit the result to be @@ -1454,7 +1471,7 @@ } if (Ok) { // Evaluate the expression in the larger type. - const SCEV *Fold = getAddExpr(LargeOps, HasNUW, HasNSW); + const SCEV *Fold = getAddExpr(LargeOps, Flags); // If it folds to something simple, use it. Otherwise, don't. if (isa(Fold) || isa(Fold)) return getTruncateExpr(Fold, DstType); @@ -1625,9 +1642,10 @@ // Build the new addrec. Propagate the NUW and NSW flags if both the // outer add and the inner addrec are guaranteed to have no overflow. - const SCEV *NewRec = getAddRecExpr(AddRecOps, AddRecLoop, - HasNUW && AddRec->hasNoUnsignedWrap(), - HasNSW && AddRec->hasNoSignedWrap()); + // FIXME: Always propagate NW + // AddRec->getNoWrapFlags(setFlags(Flags, SCEV::FlagNW)) + Flags = AddRec->getNoWrapFlags(Flags); + const SCEV *NewRec = getAddRecExpr(AddRecOps, AddRecLoop, Flags); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -1668,7 +1686,8 @@ } Ops.erase(Ops.begin() + OtherIdx); --OtherIdx; } - Ops[Idx] = getAddRecExpr(AddRecOps, AddRecLoop); + // Step size has changed, so we cannot guarantee no self-wraparound. + Ops[Idx] = getAddRecExpr(AddRecOps, AddRecLoop, SCEV::FlagAnyWrap); return getAddExpr(Ops); } @@ -1692,15 +1711,16 @@ O, Ops.size()); UniqueSCEVs.InsertNode(S, IP); } - if (HasNUW) S->setHasNoUnsignedWrap(true); - if (HasNSW) S->setHasNoSignedWrap(true); + S->setNoWrapFlags(Flags); return S; } /// getMulExpr - Get a canonical multiply expression, or something simpler if /// possible. const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, - bool HasNUW, bool HasNSW) { + SCEV::NoWrapFlags Flags) { + assert(Flags == maskFlags(Flags, SCEV::FlagNUW | SCEV::FlagNSW) && + "only nuw or nsw allowed"); assert(!Ops.empty() && "Cannot get empty mul!"); if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG @@ -1710,8 +1730,8 @@ "SCEVMulExpr operand types don't match!"); #endif - // If HasNSW is true and all the operands are non-negative, infer HasNUW. - if (!HasNUW && HasNSW) { + // If FlagNSW is true and all the operands are non-negative, infer FlagNUW. + if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) { bool All = true; for (SmallVectorImpl::const_iterator I = Ops.begin(), E = Ops.end(); I != E; ++I) @@ -1719,7 +1739,7 @@ All = false; break; } - if (All) HasNUW = true; + if (All) Flags = setFlags(Flags, SCEV::FlagNUW); } // Sort by complexity, this groups all similar expression types together. @@ -1759,12 +1779,12 @@ } else if (Ops[0]->isAllOnesValue()) { // If we have a mul by -1 of an add, try distributing the -1 among the // add operands. - if (Ops.size() == 2) + if (Ops.size() == 2) { if (const SCEVAddExpr *Add = dyn_cast(Ops[1])) { SmallVector NewOps; bool AnyFolded = false; - for (SCEVAddRecExpr::op_iterator I = Add->op_begin(), E = Add->op_end(); - I != E; ++I) { + for (SCEVAddRecExpr::op_iterator I = Add->op_begin(), + E = Add->op_end(); I != E; ++I) { const SCEV *Mul = getMulExpr(Ops[0], *I); if (!isa(Mul)) AnyFolded = true; NewOps.push_back(Mul); @@ -1772,6 +1792,7 @@ if (AnyFolded) return getAddExpr(NewOps); } + } } if (Ops.size() == 1) @@ -1831,9 +1852,11 @@ // Build the new addrec. Propagate the NUW and NSW flags if both the // outer mul and the inner addrec are guaranteed to have no overflow. - const SCEV *NewRec = getAddRecExpr(NewOps, AddRecLoop, - HasNUW && AddRec->hasNoUnsignedWrap(), - HasNSW && AddRec->hasNoSignedWrap()); + // + // No self-wrap cannot be guaranteed after changing the step size, but + // will be infered if either NUW or NSW is true. + Flags = AddRec->getNoWrapFlags(clearFlags(Flags, SCEV::FlagNW)); + const SCEV *NewRec = getAddRecExpr(NewOps, AddRecLoop, Flags); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -1869,7 +1892,8 @@ getMulExpr(G, B), getMulExpr(B, D)); const SCEV *NewAddRec = getAddRecExpr(NewStart, NewStep, - F->getLoop()); + F->getLoop(), + SCEV::FlagAnyWrap); if (Ops.size() == 2) return NewAddRec; Ops[Idx] = AddRec = cast(NewAddRec); Ops.erase(Ops.begin() + OtherIdx); --OtherIdx; @@ -1897,8 +1921,7 @@ O, Ops.size()); UniqueSCEVs.InsertNode(S, IP); } - if (HasNUW) S->setHasNoUnsignedWrap(true); - if (HasNSW) S->setHasNoSignedWrap(true); + S->setNoWrapFlags(Flags); return S; } @@ -1938,11 +1961,13 @@ getZeroExtendExpr(AR, ExtTy) == getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy), getZeroExtendExpr(Step, ExtTy), - AR->getLoop())) { + AR->getLoop(), SCEV::FlagAnyWrap)) { SmallVector Operands; for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i) Operands.push_back(getUDivExpr(AR->getOperand(i), RHS)); - return getAddRecExpr(Operands, AR->getLoop()); + return getAddRecExpr(Operands, AR->getLoop(), + // FIXME: AR->getNoWrapFlags(SCEV::FlagNW) + SCEV::FlagAnyWrap); } // (A*B)/C --> A*(B/C) if safe and B/C can be folded. if (const SCEVMulExpr *M = dyn_cast(LHS)) { @@ -2006,27 +2031,27 @@ /// getAddRecExpr - Get an add recurrence expression for the specified loop. /// Simplify the expression as much as possible. -const SCEV *ScalarEvolution::getAddRecExpr(const SCEV *Start, - const SCEV *Step, const Loop *L, - bool HasNUW, bool HasNSW) { +const SCEV *ScalarEvolution::getAddRecExpr(const SCEV *Start, const SCEV *Step, + const Loop *L, + SCEV::NoWrapFlags Flags) { SmallVector Operands; Operands.push_back(Start); if (const SCEVAddRecExpr *StepChrec = dyn_cast(Step)) if (StepChrec->getLoop() == L) { Operands.append(StepChrec->op_begin(), StepChrec->op_end()); - return getAddRecExpr(Operands, L); + // FIXME: can use maskFlags(Flags, SCEV::FlagNW) + return getAddRecExpr(Operands, L, SCEV::FlagAnyWrap); } Operands.push_back(Step); - return getAddRecExpr(Operands, L, HasNUW, HasNSW); + return getAddRecExpr(Operands, L, Flags); } /// getAddRecExpr - Get an add recurrence expression for the specified loop. /// Simplify the expression as much as possible. const SCEV * ScalarEvolution::getAddRecExpr(SmallVectorImpl &Operands, - const Loop *L, - bool HasNUW, bool HasNSW) { + const Loop *L, SCEV::NoWrapFlags Flags) { if (Operands.size() == 1) return Operands[0]; #ifndef NDEBUG const Type *ETy = getEffectiveSCEVType(Operands[0]->getType()); @@ -2040,7 +2065,7 @@ if (Operands.back()->isZero()) { Operands.pop_back(); - return getAddRecExpr(Operands, L, HasNUW, HasNSW); // {X,+,0} --> X + return getAddRecExpr(Operands, L, SCEV::FlagAnyWrap); // {X,+,0} --> X } // It's tempting to want to call getMaxBackedgeTakenCount count here and @@ -2049,8 +2074,8 @@ // meaningful BE count at this point (and if we don't, we'd be stuck // with a SCEVCouldNotCompute as the cached BE count). - // If HasNSW is true and all the operands are non-negative, infer HasNUW. - if (!HasNUW && HasNSW) { + // If FlagNSW is true and all the operands are non-negative, infer FlagNUW. + if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) { bool All = true; for (SmallVectorImpl::const_iterator I = Operands.begin(), E = Operands.end(); I != E; ++I) @@ -2058,7 +2083,7 @@ All = false; break; } - if (All) HasNUW = true; + if (All) Flags = setFlags(Flags, SCEV::FlagNUW); } // Canonicalize nested AddRecs in by nesting them in order of loop depth. @@ -2081,16 +2106,31 @@ break; } if (AllInvariant) { - NestedOperands[0] = getAddRecExpr(Operands, L); + // Create a recurrence for the outer loop with the same step size. + // + // FIXME: + // The outer recurrence keeps its NW flag but only keeps NUW/NSW if the + // inner recurrence has the same property. + // maskFlags(Flags, SCEV::FlagNW | NestedAR->getNoWrapFlags()); + SCEV::NoWrapFlags OuterFlags = SCEV::FlagAnyWrap; + + NestedOperands[0] = getAddRecExpr(Operands, L, OuterFlags); AllInvariant = true; for (unsigned i = 0, e = NestedOperands.size(); i != e; ++i) if (!isLoopInvariant(NestedOperands[i], NestedLoop)) { AllInvariant = false; break; } - if (AllInvariant) + if (AllInvariant) { // Ok, both add recurrences are valid after the transformation. - return getAddRecExpr(NestedOperands, NestedLoop, HasNUW, HasNSW); + // + // FIXME: + // The inner recurrence keeps its NW flag but only keeps NUW/NSW if + // the outer recurrence has the same property. + // maskFlags(NestedAR->getNoWrapFlags(), SCEV::FlagNW | Flags); + SCEV::NoWrapFlags InnerFlags = SCEV::FlagAnyWrap; + return getAddRecExpr(NestedOperands, NestedLoop, InnerFlags); + } } // Reset Operands to its original state. Operands[0] = NestedAR; @@ -2114,8 +2154,7 @@ O, Operands.size(), L); UniqueSCEVs.InsertNode(S, IP); } - if (HasNUW) S->setHasNoUnsignedWrap(true); - if (HasNSW) S->setHasNoSignedWrap(true); + S->setNoWrapFlags(Flags); return S; } @@ -2510,17 +2549,17 @@ return getMinusSCEV(AllOnes, V); } -/// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1, -/// and thus the HasNUW and HasNSW bits apply to the resultant add, not -/// whether the sub would have overflowed. +/// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1. +/// +/// FIXME: prohibit FlagNUW here, as soon as getMinusSCEVForExitTest goes. const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS, - bool HasNUW, bool HasNSW) { + SCEV::NoWrapFlags Flags) { // Fast path: X - X --> 0. if (LHS == RHS) return getConstant(LHS->getType(), 0); // X - Y --> X + -Y - return getAddExpr(LHS, getNegativeSCEV(RHS), HasNUW, HasNSW); + return getAddExpr(LHS, getNegativeSCEV(RHS), Flags); } /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion of the @@ -2773,44 +2812,35 @@ if (isLoopInvariant(Accum, L) || (isa(Accum) && cast(Accum)->getLoop() == L)) { - bool HasNUW = false; - bool HasNSW = false; + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap; // If the increment doesn't overflow, then neither the addrec nor // the post-increment will overflow. if (const AddOperator *OBO = dyn_cast(BEValueV)) { if (OBO->hasNoUnsignedWrap()) - HasNUW = true; + Flags = setFlags(Flags, SCEV::FlagNUW); if (OBO->hasNoSignedWrap()) - HasNSW = true; + Flags = setFlags(Flags, SCEV::FlagNSW); } else if (const GEPOperator *GEP = - dyn_cast(BEValueV)) { - // If the increment is a GEP, then we know it won't perform a - // signed overflow, because the address space cannot be - // wrapped around. - // - // NOTE: This isn't strictly true, because you could have an - // object straddling the 2G address boundary in a 32-bit address - // space (for example). We really want to model this as a "has - // no signed/unsigned wrap" where the base pointer is treated as - // unsigned and the increment is known to not have signed - // wrapping. - // - // This is a highly theoretical concern though, and this is good - // enough for all cases we know of at this point. :) - // - HasNSW |= GEP->isInBounds(); + dyn_cast(BEValueV)) { + // If the increment is an inbounds GEP, then we know the address + // space cannot be wrapped around. We cannot make any guarantee + // about signed or unsigned overflow because pointers are + // unsigned but we may have a negative index from the base + // pointer. + if (GEP->isInBounds()) + // FIXME: should be SCEV::FlagNW + Flags = setFlags(Flags, SCEV::FlagNSW); } const SCEV *StartVal = getSCEV(StartValueV); - const SCEV *PHISCEV = - getAddRecExpr(StartVal, Accum, L, HasNUW, HasNSW); + const SCEV *PHISCEV = getAddRecExpr(StartVal, Accum, L, Flags); // Since the no-wrap flags are on the increment, they apply to the // post-incremented value as well. if (isLoopInvariant(Accum, L)) (void)getAddRecExpr(getAddExpr(StartVal, Accum), - Accum, L, HasNUW, HasNSW); + Accum, L, Flags); // Okay, for the entire analysis of this edge we assumed the PHI // to be symbolic. We now need to go back and purge all of the @@ -2834,8 +2864,11 @@ // initial step of the addrec evolution. if (StartVal == getMinusSCEV(AddRec->getOperand(0), AddRec->getOperand(1))) { + // FIXME: For constant StartVal, we should be able to infer + // no-wrap flags. const SCEV *PHISCEV = - getAddRecExpr(StartVal, AddRec->getOperand(1), L); + getAddRecExpr(StartVal, AddRec->getOperand(1), L, + SCEV::FlagAnyWrap); // Okay, for the entire analysis of this edge we assumed the PHI // to be symbolic. We now need to go back and purge all of the @@ -2899,8 +2932,9 @@ IndexS = getTruncateOrSignExtend(IndexS, IntPtrTy); // Multiply the index by the element size to compute the element offset. - const SCEV *LocalOffset = getMulExpr(IndexS, ElementSize, /*NUW*/ false, - /*NSW*/ isInBounds); + const SCEV *LocalOffset = getMulExpr(IndexS, ElementSize, + isInBounds ? SCEV::FlagNSW : + SCEV::FlagAnyWrap); // Add the element offset to the running total offset. TotalOffset = getAddExpr(TotalOffset, LocalOffset); @@ -2911,8 +2945,8 @@ const SCEV *BaseS = getSCEV(Base); // Add the total offset from all the GEP indices to the base. - return getAddExpr(BaseS, TotalOffset, /*NUW*/ false, - /*NSW*/ isInBounds); + return getAddExpr(BaseS, TotalOffset, + isInBounds ? SCEV::FlagNSW : SCEV::FlagAnyWrap); } /// GetMinTrailingZeros - Determine the minimum number of zero bits that S is @@ -3074,7 +3108,8 @@ if (const SCEVAddRecExpr *AddRec = dyn_cast(S)) { // If there's no unsigned wrap, the value will never be less than its // initial value. - if (AddRec->hasNoUnsignedWrap()) + // FIXME: can broaden to FlagNW? + if (AddRec->getNoWrapFlags(SCEV::FlagNUW)) if (const SCEVConstant *C = dyn_cast(AddRec->getStart())) if (!C->getValue()->isZero()) ConservativeResult = @@ -3216,7 +3251,7 @@ if (const SCEVAddRecExpr *AddRec = dyn_cast(S)) { // If there's no signed wrap, and all the operands have the same sign or // zero, the value won't ever change sign. - if (AddRec->hasNoSignedWrap()) { + if (AddRec->getNoWrapFlags(SCEV::FlagNSW)) { bool AllNonNeg = true; bool AllNonPos = true; for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) { @@ -3411,10 +3446,8 @@ // transfer the no-wrap flags, since an or won't introduce a wrap. if (const SCEVAddRecExpr *NewAR = dyn_cast(S)) { const SCEVAddRecExpr *OldAR = cast(LHS); - if (OldAR->hasNoUnsignedWrap()) - const_cast(NewAR)->setHasNoUnsignedWrap(true); - if (OldAR->hasNoSignedWrap()) - const_cast(NewAR)->setHasNoSignedWrap(true); + const_cast(NewAR)->setNoWrapFlags( + OldAR->getNoWrapFlags()); } return S; } @@ -4031,7 +4064,7 @@ return 0; // The SCEV must be known to not wrap in some way to be interesting. - if (!SA->hasNoUnsignedWrap() && !SA->hasNoSignedWrap()) + if (!SA->getNoWrapFlags(SCEV::FlagNW)) return 0; // The stride must be a constant so that we know if it is striding up or down. @@ -4046,14 +4079,15 @@ /// advantage of the fact that this subtraction is only being used in a /// comparison by zero context. /// +/// FIXME: this can be completely removed once AddRec FlagNWs are propagated. static const SCEV *getMinusSCEVForExitTest(const SCEV *LHS, const SCEV *RHS, const Loop *L, ScalarEvolution &SE) { // If either LHS or RHS is an AddRec SCEV (of this loop) that is known to not - // wrap (either NSW or NUW), then we know that the value will either become - // the other one (and thus the loop terminates), that the loop will terminate - // through some other exit condition first, or that the loop has undefined - // behavior. This information is useful when the addrec has a stride that is - // != 1 or -1, because it means we can't "miss" the exit value. + // self-wrap, then we know that the value will either become the other one + // (and thus the loop terminates), that the loop will terminate through some + // other exit condition first, or that the loop has undefined behavior. This + // information is useful when the addrec has a stride that is != 1 or -1, + // because it means we can't "miss" the exit value. // // In any of these three cases, it is safe to turn the exit condition into a // "counting down" AddRec (to zero) by subtracting the two inputs as normal, @@ -4090,7 +4124,7 @@ if (Stride->getValue().isNegative()) std::swap(LHS, RHS); - return SE.getMinusSCEV(RHS, LHS, true /*HasNUW*/); + return SE.getMinusSCEV(RHS, LHS, SCEV::FlagNUW); } // If both LHS and RHS are interesting, we have something like: @@ -4118,7 +4152,7 @@ std::swap(LHS, RHS); } - return SE.getMinusSCEV(LHS, RHS, true /*HasNUW*/); + return SE.getMinusSCEV(LHS, RHS, SCEV::FlagNUW); } /// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of times the @@ -4180,6 +4214,8 @@ switch (Cond) { case ICmpInst::ICMP_NE: { // while (X != Y) // Convert to: while (X-Y != 0) + // FIXME: Once AddRec FlagNW are propagated, should be: + // BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEV(LHS, RHS), L); BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEVForExitTest(LHS, RHS, L, *this), L); if (BTI.hasAnyInfo()) return BTI; @@ -4706,7 +4742,10 @@ for (++i; i != e; ++i) NewOps.push_back(getSCEVAtScope(AddRec->getOperand(i), L)); - AddRec = cast(getAddRecExpr(NewOps, AddRec->getLoop())); + AddRec = cast( + getAddRecExpr(NewOps, AddRec->getLoop(), + // FIXME: AddRec->getNoWrapFlags(SCEV::FlagNW) + SCEV::FlagAnyWrap)); break; } @@ -4871,6 +4910,11 @@ /// HowFarToZero - Return the number of times a backedge comparing the specified /// value to zero will execute. If not computable, return CouldNotCompute. +/// +/// This is only used for loops with a "x != y" exit test. The exit condition is +/// now expressed as a single expression, V = x-y. So the exit test is +/// effectively V != 0. We know and take advantage of the fact that this +/// expression only being used in a comparison by zero context. ScalarEvolution::BackedgeTakenInfo ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) { // If the value is a constant @@ -4939,21 +4983,34 @@ // down, it cannot "miss" 0 (which would cause it to wrap), regardless of what // the stride is. As such, NUW addrec's will always become zero in // "start / -stride" steps, and we know that the division is exact. - if (AddRec->hasNoUnsignedWrap()) + if (AddRec->getNoWrapFlags(SCEV::FlagNUW)) // FIXME: We really want an "isexact" bit for udiv. return getUDivExpr(Start, getNegativeSCEV(Step)); // For now we handle only constant steps. + // + // TODO: Handle a nonconstant Step given AddRec. If the + // AddRec is NUW, then (in an unsigned sense) it cannot be counting up to wrap + // to 0, it must be counting down to equal 0. Consequently, N = Start / -Step. + // We have not yet seen any such cases. const SCEVConstant *StepC = dyn_cast(Step); if (StepC == 0) return getCouldNotCompute(); - // First, handle unitary steps. + // For positive steps (counting up until unsigned overflow): + // N = -Start/Step (as unsigned) + // For negative steps (counting down to zero): + // N = Start/-Step + // First compute the unsigned distance from zero in the direction of Step. + const SCEV *Distance = StepC->getValue()->getValue().isNonNegative() ? + getNegativeSCEV(Start) : Start; + + // Handle unitary steps, which cannot wraparound. if (StepC->getValue()->equalsInt(1)) // 1*N = -Start (mod 2^BW), so: - return getNegativeSCEV(Start); // N = -Start (as unsigned) + return Distance; // N = -Start (as unsigned) if (StepC->getValue()->isAllOnesValue()) // -1*N = -Start (mod 2^BW), so: - return Start; // N = Start (as unsigned) + return Distance; // N = Start (as unsigned) // Then, try to solve the above equation provided that Start is constant. if (const SCEVConstant *StartC = dyn_cast(Start)) @@ -5220,12 +5277,12 @@ case ICmpInst::ICMP_SLE: if (!getSignedRange(RHS).getSignedMax().isMaxSignedValue()) { RHS = getAddExpr(getConstant(RHS->getType(), 1, true), RHS, - /*HasNUW=*/false, /*HasNSW=*/true); + SCEV::FlagNSW); Pred = ICmpInst::ICMP_SLT; Changed = true; } else if (!getSignedRange(LHS).getSignedMin().isMinSignedValue()) { LHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), LHS, - /*HasNUW=*/false, /*HasNSW=*/true); + SCEV::FlagNSW); Pred = ICmpInst::ICMP_SLT; Changed = true; } @@ -5233,12 +5290,12 @@ case ICmpInst::ICMP_SGE: if (!getSignedRange(RHS).getSignedMin().isMinSignedValue()) { RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS, - /*HasNUW=*/false, /*HasNSW=*/true); + SCEV::FlagNSW); Pred = ICmpInst::ICMP_SGT; Changed = true; } else if (!getSignedRange(LHS).getSignedMax().isMaxSignedValue()) { LHS = getAddExpr(getConstant(RHS->getType(), 1, true), LHS, - /*HasNUW=*/false, /*HasNSW=*/true); + SCEV::FlagNSW); Pred = ICmpInst::ICMP_SGT; Changed = true; } @@ -5246,12 +5303,12 @@ case ICmpInst::ICMP_ULE: if (!getUnsignedRange(RHS).getUnsignedMax().isMaxValue()) { RHS = getAddExpr(getConstant(RHS->getType(), 1, true), RHS, - /*HasNUW=*/true, /*HasNSW=*/false); + SCEV::FlagNUW); Pred = ICmpInst::ICMP_ULT; Changed = true; } else if (!getUnsignedRange(LHS).getUnsignedMin().isMinValue()) { LHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), LHS, - /*HasNUW=*/true, /*HasNSW=*/false); + SCEV::FlagNUW); Pred = ICmpInst::ICMP_ULT; Changed = true; } @@ -5259,12 +5316,12 @@ case ICmpInst::ICMP_UGE: if (!getUnsignedRange(RHS).getUnsignedMin().isMinValue()) { RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS, - /*HasNUW=*/true, /*HasNSW=*/false); + SCEV::FlagNUW); Pred = ICmpInst::ICMP_UGT; Changed = true; } else if (!getUnsignedRange(LHS).getUnsignedMax().isMaxValue()) { LHS = getAddExpr(getConstant(RHS->getType(), 1, true), LHS, - /*HasNUW=*/true, /*HasNSW=*/false); + SCEV::FlagNUW); Pred = ICmpInst::ICMP_UGT; Changed = true; } @@ -5690,8 +5747,8 @@ return getCouldNotCompute(); // Check to see if we have a flag which makes analysis easy. - bool NoWrap = isSigned ? AddRec->hasNoSignedWrap() : - AddRec->hasNoUnsignedWrap(); + bool NoWrap = isSigned ? AddRec->getNoWrapFlags(SCEV::FlagNSW) : + AddRec->getNoWrapFlags(SCEV::FlagNUW); if (AddRec->isAffine()) { unsigned BitWidth = getTypeSizeInBits(AddRec->getType()); @@ -5807,7 +5864,9 @@ if (!SC->getValue()->isZero()) { SmallVector Operands(op_begin(), op_end()); Operands[0] = SE.getConstant(SC->getType(), 0); - const SCEV *Shifted = SE.getAddRecExpr(Operands, getLoop()); + const SCEV *Shifted = SE.getAddRecExpr(Operands, getLoop(), + // FIXME: getNoWrapFlags(FlagNW) + FlagAnyWrap); if (const SCEVAddRecExpr *ShiftedAddRec = dyn_cast(Shifted)) return ShiftedAddRec->getNumIterationsInRange( @@ -5868,7 +5927,9 @@ // Range.getUpper() is crossed. SmallVector NewOps(op_begin(), op_end()); NewOps[0] = SE.getNegativeSCEV(SE.getConstant(Range.getUpper())); - const SCEV *NewAddRec = SE.getAddRecExpr(NewOps, getLoop()); + const SCEV *NewAddRec = SE.getAddRecExpr(NewOps, getLoop(), + // getNoWrapFlags(FlagNW) + FlagAnyWrap); // Next, solve the constructed addrec std::pair Roots = Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=127590&r1=127589&r2=127590&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Mon Mar 14 11:50:06 2011 @@ -262,7 +262,8 @@ const SCEV *Start = A->getStart(); if (!FactorOutConstant(Start, Remainder, Factor, SE, TD)) return false; - S = SE.getAddRecExpr(Start, Step, A->getLoop()); + // FIXME: can use A->getNoWrapFlags(FlagNW) + S = SE.getAddRecExpr(Start, Step, A->getLoop(), SCEV::FlagAnyWrap); return true; } @@ -314,7 +315,9 @@ const SCEV *Zero = SE.getConstant(Ty, 0); AddRecs.push_back(SE.getAddRecExpr(Zero, A->getStepRecurrence(SE), - A->getLoop())); + A->getLoop(), + // FIXME: A->getNoWrapFlags(FlagNW) + SCEV::FlagAnyWrap)); if (const SCEVAddExpr *Add = dyn_cast(Start)) { Ops[i] = Zero; Ops.append(Add->op_begin(), Add->op_end()); @@ -823,7 +826,9 @@ Rest = SE.getAddExpr(Rest, SE.getAddRecExpr(SE.getConstant(A->getType(), 0), A->getStepRecurrence(SE), - A->getLoop())); + A->getLoop(), + // FIXME: A->getNoWrapFlags(FlagNW) + SCEV::FlagAnyWrap)); } if (const SCEVAddExpr *A = dyn_cast(Base)) { Base = A->getOperand(A->getNumOperands()-1); @@ -1005,10 +1010,11 @@ if (!SE.properlyDominates(Start, L->getHeader())) { PostLoopOffset = Start; Start = SE.getConstant(Normalized->getType(), 0); - Normalized = - cast(SE.getAddRecExpr(Start, - Normalized->getStepRecurrence(SE), - Normalized->getLoop())); + Normalized = cast( + SE.getAddRecExpr(Start, Normalized->getStepRecurrence(SE), + Normalized->getLoop(), + // FIXME: Normalized->getNoWrapFlags(FlagNW) + SCEV::FlagAnyWrap)); } // Strip off any non-loop-dominating component from the addrec step. @@ -1019,7 +1025,10 @@ Step = SE.getConstant(Normalized->getType(), 1); Normalized = cast(SE.getAddRecExpr(Start, Step, - Normalized->getLoop())); + Normalized->getLoop(), + // FIXME: Normalized + // ->getNoWrapFlags(FlagNW) + SCEV::FlagAnyWrap)); } // Expand the core addrec. If we need post-loop scaling, force it to @@ -1082,7 +1091,9 @@ SmallVector NewOps(S->getNumOperands()); for (unsigned i = 0, e = S->getNumOperands(); i != e; ++i) NewOps[i] = SE.getAnyExtendExpr(S->op_begin()[i], CanonicalIV->getType()); - Value *V = expand(SE.getAddRecExpr(NewOps, S->getLoop())); + Value *V = expand(SE.getAddRecExpr(NewOps, S->getLoop(), + // FIXME: S->getNoWrapFlags(FlagNW) + SCEV::FlagAnyWrap)); BasicBlock *SaveInsertBB = Builder.GetInsertBlock(); BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint(); BasicBlock::iterator NewInsertPt = @@ -1099,7 +1110,8 @@ if (!S->getStart()->isZero()) { SmallVector NewOps(S->op_begin(), S->op_end()); NewOps[0] = SE.getConstant(Ty, 0); - const SCEV *Rest = SE.getAddRecExpr(NewOps, L); + // FIXME: can use S->getNoWrapFlags() + const SCEV *Rest = SE.getAddRecExpr(NewOps, L, SCEV::FlagAnyWrap); // Turn things like ptrtoint+arithmetic+inttoptr into GEP. See the // comments on expandAddToGEP for details. @@ -1334,7 +1346,7 @@ InsertedValues.insert(I); // If we just claimed an existing instruction and that instruction had - // been the insert point, adjust the insert point forward so that + // been the insert point, adjust the insert point forward so that // subsequently inserted code will be dominated. if (Builder.GetInsertPoint() == I) { BasicBlock::iterator It = cast(I); @@ -1362,8 +1374,9 @@ assert(Ty->isIntegerTy() && "Can only insert integer induction variables!"); // Build a SCEV for {0,+,1}. + // Conservatively use FlagAnyWrap for now. const SCEV *H = SE.getAddRecExpr(SE.getConstant(Ty, 0), - SE.getConstant(Ty, 1), L); + SE.getConstant(Ty, 1), L, SCEV::FlagAnyWrap); // Emit code for it. BasicBlock *SaveInsertBB = Builder.GetInsertBlock(); Modified: llvm/trunk/lib/Analysis/ScalarEvolutionNormalization.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionNormalization.cpp?rev=127590&r1=127589&r2=127590&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionNormalization.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionNormalization.cpp Mon Mar 14 11:50:06 2011 @@ -97,7 +97,8 @@ const SCEV *N = TransformForPostIncUse(Kind, O, LUser, 0, Loops, SE, DT); Operands.push_back(N); } - const SCEV *Result = SE.getAddRecExpr(Operands, L); + // Conservatively use AnyWrap until/unless we need FlagNW. + const SCEV *Result = SE.getAddRecExpr(Operands, L, SCEV::FlagAnyWrap); switch (Kind) { default: llvm_unreachable("Unexpected transform name!"); case NormalizeAutodetect: Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=127590&r1=127589&r2=127590&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Mon Mar 14 11:50:06 2011 @@ -485,10 +485,10 @@ BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr); const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), - true /*no unsigned overflow*/); + SCEV::FlagNUW); if (StoreSize != 1) NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize), - true /*no unsigned overflow*/); + SCEV::FlagNUW); Value *NumBytes = Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); @@ -581,10 +581,10 @@ BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr); const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1), - true /*no unsigned overflow*/); + SCEV::FlagNUW); if (StoreSize != 1) NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize), - true /*no unsigned overflow*/); + SCEV::FlagNUW); Value *NumBytes = Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator()); Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=127590&r1=127589&r2=127590&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Mar 14 11:50:06 2011 @@ -253,7 +253,8 @@ DoInitialMatch(AR->getStart(), L, Good, Bad, SE); DoInitialMatch(SE.getAddRecExpr(SE.getConstant(AR->getType(), 0), AR->getStepRecurrence(SE), - AR->getLoop()), + // FIXME: AR->getNoWrapFlags() + AR->getLoop(), SCEV::FlagAnyWrap), L, Good, Bad, SE); return; } @@ -455,7 +456,10 @@ const SCEV *Start = getExactSDiv(AR->getStart(), RHS, SE, IgnoreSignificantBits); if (!Start) return 0; - return SE.getAddRecExpr(Start, Step, AR->getLoop()); + // FlagNW is independent of the start value, step direction, and is + // preserved with smaller magnitude steps. + // FIXME: AR->getNoWrapFlags(SCEV::FlagNW) + return SE.getAddRecExpr(Start, Step, AR->getLoop(), SCEV::FlagAnyWrap); } return 0; } @@ -520,7 +524,9 @@ SmallVector NewOps(AR->op_begin(), AR->op_end()); int64_t Result = ExtractImmediate(NewOps.front(), SE); if (Result != 0) - S = SE.getAddRecExpr(NewOps, AR->getLoop()); + S = SE.getAddRecExpr(NewOps, AR->getLoop(), + // FIXME: AR->getNoWrapFlags(SCEV::FlagNW) + SCEV::FlagAnyWrap); return Result; } return 0; @@ -545,7 +551,9 @@ SmallVector NewOps(AR->op_begin(), AR->op_end()); GlobalValue *Result = ExtractSymbol(NewOps.front(), SE); if (Result) - S = SE.getAddRecExpr(NewOps, AR->getLoop()); + S = SE.getAddRecExpr(NewOps, AR->getLoop(), + // FIXME: AR->getNoWrapFlags(SCEV::FlagNW) + SCEV::FlagAnyWrap); return Result; } return 0; @@ -2236,7 +2244,9 @@ if (!AR->getStart()->isZero()) { CollectSubexprs(SE.getAddRecExpr(SE.getConstant(AR->getType(), 0), AR->getStepRecurrence(SE), - AR->getLoop()), + AR->getLoop(), + //FIXME: AR->getNoWrapFlags(SCEV::FlagNW) + SCEV::FlagAnyWrap), C, Ops, L, SE); CollectSubexprs(AR->getStart(), C, Ops, L, SE); return; @@ -3047,7 +3057,7 @@ } } -/// NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters - Call +/// NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters - Call /// FilterOutUndesirableDedicatedRegisters again, if necessary, now that /// we've done more filtering, as it may be able to find more formulae to /// eliminate. From renato.golin at arm.com Mon Mar 14 12:26:22 2011 From: renato.golin at arm.com (Renato Golin) Date: Mon, 14 Mar 2011 17:26:22 +0000 Subject: [llvm-commits] Debug Relocation Patch Message-ID: Patch to a fix dwarf relocation problem on ARM. One-line fix plus the test where it used to break. Check-all passes cleanly. Rationale: When the location of a symbol vary during the execution of the program, GCC emits the Dwarf location as a reference to a temporary symbol inside the .debug_loc section, so GAS can later interpret this as an offset and emit the proper relocation (to .debug_loc). LLVM was emitting the offset directly and not leaving enough information to GAS for relocation information. This patch makes LLVM emit the reference to the symbol directly, as GCC does. Ok to commit? cheers, --renato -------------- next part -------------- A non-text attachment was scrubbed... Name: dwarf-relocation.patch Type: text/x-patch Size: 6582 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110314/282d14f4/attachment.bin From atrick at apple.com Mon Mar 14 12:28:02 2011 From: atrick at apple.com (Andrew Trick) Date: Mon, 14 Mar 2011 17:28:02 -0000 Subject: [llvm-commits] [llvm] r127591 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <20110314172802.877602A6C12C@llvm.org> Author: atrick Date: Mon Mar 14 12:28:02 2011 New Revision: 127591 URL: http://llvm.org/viewvc/llvm-project?rev=127591&view=rev Log: HowFarToZero can compute a trip count as long as the recurrence has no-self-wrap. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127591&r1=127590&r2=127591&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 14 12:28:02 2011 @@ -4978,15 +4978,6 @@ const SCEV *Start = getSCEVAtScope(AddRec->getStart(), L->getParentLoop()); const SCEV *Step = getSCEVAtScope(AddRec->getOperand(1), L->getParentLoop()); - // If the AddRec is NUW, then (in an unsigned sense) it cannot be counting up - // to wrap to 0, it must be counting down to equal 0. Also, while counting - // down, it cannot "miss" 0 (which would cause it to wrap), regardless of what - // the stride is. As such, NUW addrec's will always become zero in - // "start / -stride" steps, and we know that the division is exact. - if (AddRec->getNoWrapFlags(SCEV::FlagNUW)) - // FIXME: We really want an "isexact" bit for udiv. - return getUDivExpr(Start, getNegativeSCEV(Step)); - // For now we handle only constant steps. // // TODO: Handle a nonconstant Step given AddRec. If the @@ -5002,15 +4993,28 @@ // For negative steps (counting down to zero): // N = Start/-Step // First compute the unsigned distance from zero in the direction of Step. - const SCEV *Distance = StepC->getValue()->getValue().isNonNegative() ? - getNegativeSCEV(Start) : Start; + bool CountDown = StepC->getValue()->getValue().isNegative(); + const SCEV *Distance = CountDown ? Start : getNegativeSCEV(Start); // Handle unitary steps, which cannot wraparound. - if (StepC->getValue()->equalsInt(1)) // 1*N = -Start (mod 2^BW), so: - return Distance; // N = -Start (as unsigned) - - if (StepC->getValue()->isAllOnesValue()) // -1*N = -Start (mod 2^BW), so: - return Distance; // N = Start (as unsigned) + // 1*N = -Start; -1*N = Start (mod 2^BW), so: + // N = Distance (as unsigned) + if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) + return Distance; + + // If the recurrence is known not to wraparound, unsigned divide computes the + // back edge count. We know that the value will either become zero (and thus + // the loop terminates), that the loop will terminate through some other exit + // condition first, or that the loop has undefined behavior. This means + // we can't "miss" the exit value, even with nonunit stride. + // + // FIXME: Prove that loops always exhibits *acceptable* undefined + // behavior. Loops must exhibit defined behavior until a wrapped value is + // actually used. So the trip count computed by udiv could be smaller than the + // number of well-defined iterations. + if (AddRec->getNoWrapFlags(SCEV::FlagNW)) + // FIXME: We really want an "isexact" bit for udiv. + return getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step); // Then, try to solve the above equation provided that Start is constant. if (const SCEVConstant *StartC = dyn_cast(Start)) From grosbach at apple.com Mon Mar 14 12:32:49 2011 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 14 Mar 2011 17:32:49 -0000 Subject: [llvm-commits] [llvm] r127592 - /llvm/trunk/utils/TableGen/CodeGenInstruction.h Message-ID: <20110314173249.44A212A6C12C@llvm.org> Author: grosbach Date: Mon Mar 14 12:32:49 2011 New Revision: 127592 URL: http://llvm.org/viewvc/llvm-project?rev=127592&view=rev Log: Trailing whitespace. Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=127592&r1=127591&r2=127592&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Mon Mar 14 12:32:49 2011 @@ -26,7 +26,7 @@ class DagInit; class CodeGenTarget; class StringRef; - + class CGIOperandList { public: class ConstraintInfo { @@ -34,25 +34,25 @@ unsigned OtherTiedOperand; public: ConstraintInfo() : Kind(None) {} - + static ConstraintInfo getEarlyClobber() { ConstraintInfo I; I.Kind = EarlyClobber; I.OtherTiedOperand = 0; return I; } - + static ConstraintInfo getTied(unsigned Op) { ConstraintInfo I; I.Kind = Tied; I.OtherTiedOperand = Op; return I; } - + bool isNone() const { return Kind == None; } bool isEarlyClobber() const { return Kind == EarlyClobber; } bool isTied() const { return Kind == Tied; } - + unsigned getTiedOperand() const { assert(isTied()); return OtherTiedOperand; @@ -65,19 +65,19 @@ /// Rec - The definition this operand is declared as. /// Record *Rec; - + /// Name - If this operand was assigned a symbolic name, this is it, /// otherwise, it's empty. std::string Name; - + /// PrinterMethodName - The method used to print operands of this type in /// the asmprinter. std::string PrinterMethodName; - + /// EncoderMethodName - The method used to get the machine operand value /// for binary encoding. "getMachineOpValue" by default. std::string EncoderMethodName; - + /// MIOperandNo - Currently (this is meant to be phased out), some logical /// operands correspond to multiple MachineInstr operands. In the X86 /// target for example, one address operand is represented as 4 @@ -86,27 +86,27 @@ /// does, this contains the MI operand index of this operand. unsigned MIOperandNo; unsigned MINumOperands; // The number of operands. - + /// DoNotEncode - Bools are set to true in this vector for each operand in /// the DisableEncoding list. These should not be emitted by the code /// emitter. std::vector DoNotEncode; - + /// MIOperandInfo - Default MI operand type. Note an operand may be made /// up of multiple MI operands. DagInit *MIOperandInfo; - + /// Constraint info for this operand. This operand can have pieces, so we /// track constraint info for each. std::vector Constraints; - + OperandInfo(Record *R, const std::string &N, const std::string &PMN, const std::string &EMN, unsigned MION, unsigned MINO, DagInit *MIOI) : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN), MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {} - - + + /// getTiedOperand - If this operand is tied to another one, return the /// other operand number. Otherwise, return -1. int getTiedRegister() const { @@ -117,43 +117,43 @@ return -1; } }; - + CGIOperandList(Record *D); - + Record *TheDef; // The actual record containing this OperandList. /// NumDefs - Number of def operands declared, this is the number of /// elements in the instruction's (outs) list. /// unsigned NumDefs; - + /// OperandList - The list of declared operands, along with their declared /// type (which is a record). std::vector OperandList; - + // Information gleaned from the operand list. bool isPredicable; bool hasOptionalDef; bool isVariadic; - + // Provide transparent accessors to the operand list. unsigned size() const { return OperandList.size(); } const OperandInfo &operator[](unsigned i) const { return OperandList[i]; } OperandInfo &operator[](unsigned i) { return OperandList[i]; } OperandInfo &back() { return OperandList.back(); } const OperandInfo &back() const { return OperandList.back(); } - - + + /// getOperandNamed - Return the index of the operand with the specified /// non-empty name. If the instruction does not have an operand with the /// specified name, throw an exception. unsigned getOperandNamed(StringRef Name) const; - + /// hasOperandNamed - Query whether the instruction has an operand of the /// given name. If so, return true and set OpIdx to the index of the /// operand. Otherwise, return false. bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const; - + /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar", /// where $foo is a whole operand and $foo.bar refers to a suboperand. /// This throws an exception if the name is invalid. If AllowWholeOp is @@ -161,13 +161,13 @@ /// not. std::pair ParseOperandName(const std::string &Op, bool AllowWholeOp = true); - + /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a /// flat machineinstr operand #. unsigned getFlattenedOperandNumber(std::pair Op) const { return OperandList[Op.first].MIOperandNo + Op.second; } - + /// getSubOperandNumber - Unflatten a operand number into an /// operand/suboperand pair. std::pair getSubOperandNumber(unsigned Op) const { @@ -177,8 +177,8 @@ return std::make_pair(i, Op-OperandList[i].MIOperandNo); } } - - + + /// isFlatOperandNotEmitted - Return true if the specified flat operand # /// should not be emitted with the code emitter. bool isFlatOperandNotEmitted(unsigned FlatOpNo) const { @@ -187,10 +187,10 @@ return OperandList[Op.first].DoNotEncode[Op.second]; return false; } - + void ProcessDisableEncoding(std::string Value); }; - + class CodeGenInstruction { public: @@ -242,45 +242,45 @@ /// MVT::Other. MVT::SimpleValueType HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const; - - + + /// FlattenAsmStringVariants - Flatten the specified AsmString to only /// include text from the specified variant, returning the new string. static std::string FlattenAsmStringVariants(StringRef AsmString, unsigned Variant); }; - - + + /// CodeGenInstAlias - This represents an InstAlias definition. class CodeGenInstAlias { public: Record *TheDef; // The actual record defining this InstAlias. - + /// AsmString - The format string used to emit a .s file for the /// instruction. std::string AsmString; - + /// Result - The result instruction. DagInit *Result; - + /// ResultInst - The instruction generated by the alias (decoded from /// Result). CodeGenInstruction *ResultInst; - - + + struct ResultOperand { private: StringRef Name; Record *R; - + int64_t Imm; - public: + public: enum { K_Record, K_Imm, K_Reg } Kind; - + ResultOperand(StringRef N, Record *r) : Name(N), R(r), Kind(K_Record) {} ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {} ResultOperand(Record *r) : R(r), Kind(K_Reg) {} @@ -288,13 +288,13 @@ bool isRecord() const { return Kind == K_Record; } bool isImm() const { return Kind == K_Imm; } bool isReg() const { return Kind == K_Reg; } - + StringRef getName() const { assert(isRecord()); return Name; } Record *getRecord() const { assert(isRecord()); return R; } int64_t getImm() const { assert(isImm()); return Imm; } Record *getRegister() const { assert(isReg()); return R; } }; - + /// ResultOperands - The decoded operands for the result instruction. std::vector ResultOperands; @@ -304,13 +304,13 @@ /// index specifies the suboperand. If there are no suboperands or if all /// of them are matched by the operand, the second value should be -1. std::vector > ResultInstOperandIndex; - + CodeGenInstAlias(Record *R, CodeGenTarget &T); bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, Record *InstOpRec, bool hasSubOps, SMLoc Loc, CodeGenTarget &T, ResultOperand &ResOp); - }; + }; } #endif From atrick at apple.com Mon Mar 14 12:38:55 2011 From: atrick at apple.com (Andrew Trick) Date: Mon, 14 Mar 2011 17:38:55 -0000 Subject: [llvm-commits] [llvm] r127593 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <20110314173855.3206F2A6C12C@llvm.org> Author: atrick Date: Mon Mar 14 12:38:54 2011 New Revision: 127593 URL: http://llvm.org/viewvc/llvm-project?rev=127593&view=rev Log: Negating a recurrence preserves no-self-wrap. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127593&r1=127592&r2=127593&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 14 12:38:54 2011 @@ -1792,6 +1792,17 @@ if (AnyFolded) return getAddExpr(NewOps); } + else if (const SCEVAddRecExpr * + AddRec = dyn_cast(Ops[1])) { + // Negation preserves a recurrence's no self-wrap property. + SmallVector Operands; + for (SCEVAddRecExpr::op_iterator I = AddRec->op_begin(), + E = AddRec->op_end(); I != E; ++I) { + Operands.push_back(getMulExpr(Ops[0], *I)); + } + return getAddRecExpr(Operands, AddRec->getLoop(), + AddRec->getNoWrapFlags(SCEV::FlagNW)); + } } } From evan.cheng at apple.com Mon Mar 14 13:02:30 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 14 Mar 2011 18:02:30 -0000 Subject: [llvm-commits] [llvm] r127595 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20110314180230.800A12A6C12D@llvm.org> Author: evancheng Date: Mon Mar 14 13:02:30 2011 New Revision: 127595 URL: http://llvm.org/viewvc/llvm-project?rev=127595&view=rev Log: Indentation. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127595&r1=127594&r2=127595&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Mar 14 13:02:30 2011 @@ -4555,7 +4555,7 @@ case ISD::EH_SJLJ_DISPATCHSETUP: return LowerEH_SJLJ_DISPATCHSETUP(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG, Subtarget); - case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG); + case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG); case ISD::SHL: case ISD::SRL: case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget); From echristo at apple.com Mon Mar 14 13:15:19 2011 From: echristo at apple.com (Eric Christopher) Date: Mon, 14 Mar 2011 11:15:19 -0700 Subject: [llvm-commits] [llvm] r127518 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-pred.ll In-Reply-To: References: <20110312010929.82F192A6C12C@llvm.org> Message-ID: <840DE70F-D015-4072-8E37-A822480A4393@apple.com> >> I agree this will fix the crash, but have to confess it kinda makes me a bit squirmy. If the instruction isn't predicable, it shouldn't have the operands. Is there no way we can tell the backend directly that some NEON instructions really aren't predicable? Note: I have not looked deeply into how predication+NEON is handled, so that could easily be anywhere from "trivial" to "holy crap hard" in complexity to do. I'm purely talking from the perspective of what I'd like to see at a high level. As you described it: the compiler shouldn't lie to itself. > I agree, but the problem is in more than just this area and I haven't really looked into how to rewrite that part of the arm backend to fix it. Keep in mind that the normal isel also lies in this way - I'm guessing that the optional def is unconditionally added and then mucked with later during the selection dag timeframe. >> Added: llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll?rev=127518&view=auto >> ============================================================================== >> --- llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll (added) >> +++ llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll Fri Mar 11 19:09:29 2011 >> @@ -0,0 +1,60 @@ >> +; ModuleID = 'test.c' >> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64-n32" >> +target triple = "armv7-apple-darwin" >> + > On the completely nitpicky side, is the test really Darwin specific? Either way, the datalayout and triple lines aren't really necessary. Just passing -march/-mtriple and -mcpu to llc in the RUN line is more consistent with the rest of the tests. > I make no claims about how well fast-isel works for darwin targets so it's turned off there - so this testcase isn't valid for non-darwin at the moment. > This was code-gen OK before, but failed when trying to assemble due to an invalid instruction (predicate on a non-predicable instruction), right? If so, this test won't catch that as it doesn't try to assemble the assembly file. Adding a CHECK-NOT for the particular instruction that was bogus and a CHECK for what it actually should be would be good. This would assert with a Debug+Asserts build. > Not a huge deal, but seems a bit largish for this sort of test. Does it reduce down at all? I would, perhaps naively, expect that a conditional followed by the vcvt (sitofp <4 x i32> %1 to <4 x float>) would do the trick. I believed the original submitter when she said she couldn't get it any smaller :) -eric From rafael.espindola at gmail.com Mon Mar 14 13:19:26 2011 From: rafael.espindola at gmail.com (Rafael Avila de Espindola) Date: Mon, 14 Mar 2011 14:19:26 -0400 Subject: [llvm-commits] Debug Relocation Patch In-Reply-To: References: Message-ID: <4D7E5C2E.1000803@gmail.com> On 11-03-14 01:26 PM, Renato Golin wrote: > Patch to a fix dwarf relocation problem on ARM. One-line fix plus the > test where it used to break. Check-all passes cleanly. > > Rationale: > When the location of a symbol vary during the execution of the > program, GCC emits the Dwarf location as a reference to a temporary > symbol inside the .debug_loc section, so GAS can later interpret this > as an offset and emit the proper relocation (to .debug_loc). LLVM was > emitting the offset directly and not leaving enough information to GAS > for relocation information. This patch makes LLVM emit the reference > to the symbol directly, as GCC does. > > Ok to commit? This might be a difference in how ELF and Mach-O handle debug info. Can you try this on a Darwin system too? > cheers, > --renato Thanks, Rafael From evan.cheng at apple.com Mon Mar 14 13:15:55 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 14 Mar 2011 18:15:55 -0000 Subject: [llvm-commits] [llvm] r127598 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/ARM/shifter_operand.ll test/CodeGen/ARM/undef-sext.ll Message-ID: <20110314181555.6A48F2A6C12D@llvm.org> Author: evancheng Date: Mon Mar 14 13:15:55 2011 New Revision: 127598 URL: http://llvm.org/viewvc/llvm-project?rev=127598&view=rev Log: Minor optimization. sign-ext/anyext of undef is still undef. Added: llvm/trunk/test/CodeGen/ARM/undef-sext.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/test/CodeGen/ARM/shifter_operand.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=127598&r1=127597&r2=127598&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Mar 14 13:15:55 2011 @@ -2482,6 +2482,8 @@ "Vector element count mismatch!"); if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND) return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0)); + else if (OpOpcode == ISD::UNDEF) + return getUNDEF(VT); break; case ISD::ZERO_EXTEND: assert(VT.isInteger() && Operand.getValueType().isInteger() && @@ -2512,6 +2514,8 @@ OpOpcode == ISD::ANY_EXTEND) // (ext (zext x)) -> (zext x) and (ext (sext x)) -> (sext x) return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0)); + else if (OpOpcode == ISD::UNDEF) + return getUNDEF(VT); // (ext (trunx x)) -> x if (OpOpcode == ISD::TRUNCATE) { Modified: llvm/trunk/test/CodeGen/ARM/shifter_operand.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/shifter_operand.ll?rev=127598&r1=127597&r2=127598&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/shifter_operand.ll (original) +++ llvm/trunk/test/CodeGen/ARM/shifter_operand.ll Mon Mar 14 13:15:55 2011 @@ -51,19 +51,19 @@ declare i8* @malloc(...) -define fastcc void @test4() nounwind { +define fastcc void @test4(i16 %addr) nounwind { entry: ; A8: test4: -; A8: ldr r1, [r0, r0, lsl #2] -; A8: str r1, [r0, r0, lsl #2] +; A8: ldr r2, [r0, r1, lsl #2] +; A8: str r2, [r0, r1, lsl #2] ; A9: test4: -; A9: add r0, r0, r0, lsl #2 +; A9: add r0, r0, r4, lsl #2 ; A9: ldr r1, [r0] ; A9: str r1, [r0] %0 = tail call i8* (...)* @malloc(i32 undef) nounwind %1 = bitcast i8* %0 to i32* - %2 = sext i16 undef to i32 + %2 = sext i16 %addr to i32 %3 = getelementptr inbounds i32* %1, i32 %2 %4 = load i32* %3, align 4 %5 = add nsw i32 %4, 1 Added: llvm/trunk/test/CodeGen/ARM/undef-sext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/undef-sext.ll?rev=127598&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/undef-sext.ll (added) +++ llvm/trunk/test/CodeGen/ARM/undef-sext.ll Mon Mar 14 13:15:55 2011 @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=armv7-apple-darwin -mcpu=cortex-a8 | FileCheck %s + +; No need to sign-extend undef. + +define i32 @t(i32* %a) nounwind { +entry: +; CHECK: t: +; CHECK: ldr r0, [r0] +; CHECK: bx lr + %0 = sext i16 undef to i32 + %1 = getelementptr inbounds i32* %a, i32 %0 + %2 = load i32* %1, align 4 + ret i32 %2 +} From evan.cheng at apple.com Mon Mar 14 13:19:52 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 14 Mar 2011 18:19:52 -0000 Subject: [llvm-commits] [llvm] r127600 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <20110314181952.BAE312A6C12D@llvm.org> Author: evancheng Date: Mon Mar 14 13:19:52 2011 New Revision: 127600 URL: http://llvm.org/viewvc/llvm-project?rev=127600&view=rev Log: BIT_CONVERT has been renamed to BITCAST. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=127600&r1=127599&r2=127600&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Mar 14 13:19:52 2011 @@ -5908,7 +5908,7 @@ case ISD::UINT_TO_FP: return "uint_to_fp"; case ISD::FP_TO_SINT: return "fp_to_sint"; case ISD::FP_TO_UINT: return "fp_to_uint"; - case ISD::BITCAST: return "bit_convert"; + case ISD::BITCAST: return "bitcast"; case ISD::FP16_TO_FP32: return "fp16_to_fp32"; case ISD::FP32_TO_FP16: return "fp32_to_fp16"; From fvbommel at gmail.com Mon Mar 14 13:25:56 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 14 Mar 2011 19:25:56 +0100 Subject: [llvm-commits] [llvm] r127598 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/ARM/shifter_operand.ll test/CodeGen/ARM/undef-sext.ll In-Reply-To: <20110314181555.6A48F2A6C12D@llvm.org> References: <20110314181555.6A48F2A6C12D@llvm.org> Message-ID: On Mon, Mar 14, 2011 at 7:15 PM, Evan Cheng wrote: > Log: > Minor optimization. sign-ext/anyext of undef is still undef. I can believe this for anyext, but a sext'ed undef should probably still have equal high bits, which is not a requirement for the bigger undef you're replacing it with. From echristo at apple.com Mon Mar 14 13:34:51 2011 From: echristo at apple.com (Eric Christopher) Date: Mon, 14 Mar 2011 11:34:51 -0700 Subject: [llvm-commits] Fix for PR9477 In-Reply-To: <901267.5434.qm@web55606.mail.re4.yahoo.com> References: <901267.5434.qm@web55606.mail.re4.yahoo.com> Message-ID: <30BFEAA9-86BE-48B1-9464-D0509240DA48@apple.com> On Mar 13, 2011, at 8:35 AM, Jan Sjodin wrote: > Guard to check for AsmParser was missing. I tested the code by commenting out the "if" sections to see if it compiled on my machine, but someone may want to check it on a Mac. Should be fine to commit. Thanks! -eric From grosbach at apple.com Mon Mar 14 13:37:12 2011 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 14 Mar 2011 11:37:12 -0700 Subject: [llvm-commits] [llvm] r127518 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-pred.ll In-Reply-To: <840DE70F-D015-4072-8E37-A822480A4393@apple.com> References: <20110312010929.82F192A6C12C@llvm.org> <840DE70F-D015-4072-8E37-A822480A4393@apple.com> Message-ID: <65BBAA8B-86A9-4332-99BC-AC54C4FFD3FA@apple.com> Re-cap summary of our offline convo: On Mar 14, 2011, at 11:15 AM, Eric Christopher wrote: > >>> I agree this will fix the crash, but have to confess it kinda makes me a bit squirmy. If the instruction isn't predicable, it shouldn't have the operands. Is there no way we can tell the backend directly that some NEON instructions really aren't predicable? Note: I have not looked deeply into how predication+NEON is handled, so that could easily be anywhere from "trivial" to "holy crap hard" in complexity to do. I'm purely talking from the perspective of what I'd like to see at a high level. As you described it: the compiler shouldn't lie to itself. >> > > I agree, but the problem is in more than just this area and I haven't really looked into how to rewrite that part of the arm backend to fix it. Keep in mind that the normal isel also lies in this way - I'm guessing that the optional def is unconditionally added and then mucked with later during the selection dag timeframe. Yah, I was just hoping to pique your curiosity to dig deeper. :) I agree it's a pre-existing issue and not a necessity to address as part of this bugfix. > >>> Added: llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll?rev=127518&view=auto >>> ============================================================================== >>> --- llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll (added) >>> +++ llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll Fri Mar 11 19:09:29 2011 >>> @@ -0,0 +1,60 @@ >>> +; ModuleID = 'test.c' >>> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64-n32" >>> +target triple = "armv7-apple-darwin" >>> + >> On the completely nitpicky side, is the test really Darwin specific? Either way, the datalayout and triple lines aren't really necessary. Just passing -march/-mtriple and -mcpu to llc in the RUN line is more consistent with the rest of the tests. >> > > I make no claims about how well fast-isel works for darwin targets so it's turned off there - so this testcase isn't valid for non-darwin at the moment. Ah, right. Forgot it was turned off entirely for non-darwin. Just putting the info on the RUN line should take care of it, then. > >> This was code-gen OK before, but failed when trying to assemble due to an invalid instruction (predicate on a non-predicable instruction), right? If so, this test won't catch that as it doesn't try to assemble the assembly file. Adding a CHECK-NOT for the particular instruction that was bogus and a CHECK for what it actually should be would be good. > > This would assert with a Debug+Asserts build. It'd still be good for the -Asserts build to be able to detect the failure, though, right? The CHECK/CHECK-NOT also help self-document what was going wrong. >> Not a huge deal, but seems a bit largish for this sort of test. Does it reduce down at all? I would, perhaps naively, expect that a conditional followed by the vcvt (sitofp <4 x i32> %1 to <4 x float>) would do the trick. > > I believed the original submitter when she said she couldn't get it any smaller :) As we talked about offline, we can probably get a bit smaller, but not too much. Fast-isel heuristics are probably playing some games here. IMO, worth trying a bit, but not spending a huge amount of time on it. Maybe just reduce to a single function and add an explanatory comment about what's really being checked for? -Jim From grosbach at apple.com Mon Mar 14 13:34:35 2011 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 14 Mar 2011 18:34:35 -0000 Subject: [llvm-commits] [llvm] r127601 - in /llvm/trunk/lib/Target/ARM: ARMInstrFormats.td ARMInstrThumb2.td InstPrinter/ARMInstPrinter.cpp InstPrinter/ARMInstPrinter.h Message-ID: <20110314183435.83E2B2A6C12C@llvm.org> Author: grosbach Date: Mon Mar 14 13:34:35 2011 New Revision: 127601 URL: http://llvm.org/viewvc/llvm-project?rev=127601&view=rev Log: Remove some dead patterns. Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=127601&r1=127600&r2=127601&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Mon Mar 14 13:34:35 2011 @@ -206,21 +206,11 @@ let PrintMethod = "printSetendOperand"; } -def cps_opt : Operand { - let PrintMethod = "printCPSOptionOperand"; -} - def msr_mask : Operand { let PrintMethod = "printMSRMaskOperand"; let ParserMatchClass = MSRMaskOperand; } -// A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0. -// The neg_zero operand translates -0 to -1, -1 to -2, ..., etc. -def neg_zero : Operand { - let PrintMethod = "printNegZeroOperand"; -} - // Shift Right Immediate - A shift right immediate is encoded differently from // other shift immediates. The imm6 field is encoded like so: // Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=127601&r1=127600&r2=127601&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Mar 14 13:34:35 2011 @@ -61,40 +61,6 @@ return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1; }], t2_so_imm_neg_XFORM>; -// Break t2_so_imm's up into two pieces. This handles immediates with up to 16 -// bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12] -// to get the first/second pieces. -def t2_so_imm2part : Operand, - PatLeaf<(imm), [{ - return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue()); - }]> { -} - -def t2_so_imm2part_1 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(V, MVT::i32); -}]>; - -def t2_so_imm2part_2 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(V, MVT::i32); -}]>; - -def t2_so_neg_imm2part : Operand, PatLeaf<(imm), [{ - return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue()); - }]> { -} - -def t2_so_neg_imm2part_1 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(V, MVT::i32); -}]>; - -def t2_so_neg_imm2part_2 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(V, MVT::i32); -}]>; - /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31]. def imm1_31 : PatLeaf<(i32 imm), [{ return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32; Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=127601&r1=127600&r2=127601&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Mon Mar 14 13:34:35 2011 @@ -417,16 +417,6 @@ } } -void ARMInstPrinter::printNegZeroOperand(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { - const MCOperand &Op = MI->getOperand(OpNum); - O << '#'; - if (Op.getImm() < 0) - O << '-' << (-Op.getImm() - 1); - else - O << Op.getImm(); -} - void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) { ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=127601&r1=127600&r2=127601&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Mon Mar 14 13:34:35 2011 @@ -88,9 +88,7 @@ void printSetendOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printCPSIMod(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printCPSIFlag(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printCPSOptionOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printMSRMaskOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printNegZeroOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); From echristo at apple.com Mon Mar 14 13:38:42 2011 From: echristo at apple.com (Eric Christopher) Date: Mon, 14 Mar 2011 11:38:42 -0700 Subject: [llvm-commits] [llvm] r127518 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-pred.ll In-Reply-To: <65BBAA8B-86A9-4332-99BC-AC54C4FFD3FA@apple.com> References: <20110312010929.82F192A6C12C@llvm.org> <840DE70F-D015-4072-8E37-A822480A4393@apple.com> <65BBAA8B-86A9-4332-99BC-AC54C4FFD3FA@apple.com> Message-ID: <5830590B-9AF8-44F5-9AC1-0DEBD80DDB16@apple.com> >> >> I make no claims about how well fast-isel works for darwin targets so it's turned off there - so this testcase isn't valid for non-darwin at the moment. > > Ah, right. Forgot it was turned off entirely for non-darwin. Just putting the info on the RUN line should take care of it, then. > >> >>> This was code-gen OK before, but failed when trying to assemble due to an invalid instruction (predicate on a non-predicable instruction), right? If so, this test won't catch that as it doesn't try to assemble the assembly file. Adding a CHECK-NOT for the particular instruction that was bogus and a CHECK for what it actually should be would be good. >> >> This would assert with a Debug+Asserts build. > > It'd still be good for the -Asserts build to be able to detect the failure, though, right? The CHECK/CHECK-NOT also help self-document what was going wrong. > That's fair, and probably useful too. :) >>> Not a huge deal, but seems a bit largish for this sort of test. Does it reduce down at all? I would, perhaps naively, expect that a conditional followed by the vcvt (sitofp <4 x i32> %1 to <4 x float>) would do the trick. >> >> I believed the original submitter when she said she couldn't get it any smaller :) > > As we talked about offline, we can probably get a bit smaller, but not too much. Fast-isel heuristics are probably playing some games here. IMO, worth trying a bit, but not spending a huge amount of time on it. Maybe just reduce to a single function and add an explanatory comment about what's really being checked for? I'll see what I can do :) -eric From Renato.Golin at arm.com Mon Mar 14 14:17:36 2011 From: Renato.Golin at arm.com (Renato Golin) Date: Mon, 14 Mar 2011 19:17:36 +0000 Subject: [llvm-commits] Debug Relocation Patch In-Reply-To: <4D7E5C2E.1000803@gmail.com> References: , <4D7E5C2E.1000803@gmail.com> Message-ID: > This might be a difference in how ELF and Mach-O handle debug info. Can > you try this on a Darwin system too? Nope, sorry. I don't have it available for me to test. :( I was hoping there was a test for that that but I couldn't find it, so I just created one. As far as I understand, Mach-O doesn't have relocations (right?), so the current style is actually correct. Is it possible for the Mach-O back-end to understand that a label inside another section is actually an offset? Or maybe we need to delegate that to each specific back-end... cheers, --renato -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. From rafael.espindola at gmail.com Mon Mar 14 14:45:40 2011 From: rafael.espindola at gmail.com (Rafael Avila de Espindola) Date: Mon, 14 Mar 2011 15:45:40 -0400 Subject: [llvm-commits] Debug Relocation Patch In-Reply-To: References: , <4D7E5C2E.1000803@gmail.com> Message-ID: <4D7E7064.5060101@gmail.com> > Nope, sorry. I don't have it available for me to test. :( > > I was hoping there was a test for that that but I couldn't find it, > so I just created one. > > As far as I understand, Mach-O doesn't have relocations (right?), so > the current style is actually correct. It has relocations in general, but as far as I know it also requires the linker to know dwarf, so it can use that to avoid some. > Is it possible for the Mach-O back-end to understand that a label > inside another section is actually an offset? Or maybe we need to > delegate that to each specific back-end... We might need a virtual method or similar. Devang, for testing on linux I normally use a current version of the gdb testsuite. I assume that for darwin it is better to use an older one. Which testsuite do you normally use? > cheers, --renato > Cheers, Rafael From stoklund at 2pi.dk Mon Mar 14 14:56:43 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 14 Mar 2011 19:56:43 -0000 Subject: [llvm-commits] [llvm] r127607 - /llvm/trunk/lib/CodeGen/InlineSpiller.cpp Message-ID: <20110314195643.9B38F2A6C12C@llvm.org> Author: stoklund Date: Mon Mar 14 14:56:43 2011 New Revision: 127607 URL: http://llvm.org/viewvc/llvm-project?rev=127607&view=rev Log: Rename members to match LLVM naming conventions more closely. Remove the unused reserved_ bit vector, no functional change intended. This doesn't break 'svn blame', this file really is all my fault. Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=127607&r1=127606&r2=127607&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Mon Mar 14 14:56:43 2011 @@ -31,24 +31,23 @@ namespace { class InlineSpiller : public Spiller { - MachineFunctionPass &pass_; - MachineFunction &mf_; - LiveIntervals &lis_; - LiveStacks &lss_; - AliasAnalysis *aa_; - VirtRegMap &vrm_; - MachineFrameInfo &mfi_; - MachineRegisterInfo &mri_; - const TargetInstrInfo &tii_; - const TargetRegisterInfo &tri_; - const BitVector reserved_; + MachineFunctionPass &Pass; + MachineFunction &MF; + LiveIntervals &LIS; + LiveStacks &LSS; + AliasAnalysis *AA; + VirtRegMap &VRM; + MachineFrameInfo &MFI; + MachineRegisterInfo &MRI; + const TargetInstrInfo &TII; + const TargetRegisterInfo &TRI; // Variables that are valid during spill(), but used by multiple methods. - LiveRangeEdit *edit_; - const TargetRegisterClass *rc_; - int stackSlot_; + LiveRangeEdit *Edit; + const TargetRegisterClass *RC; + int StackSlot; - // All registers to spill to stackSlot_, including the main register. + // All registers to spill to StackSlot, including the main register. SmallVector RegsToSpill; // All COPY instructions to/from snippets. @@ -56,7 +55,7 @@ SmallPtrSet SnippetCopies; // Values that failed to remat at some point. - SmallPtrSet usedValues_; + SmallPtrSet UsedValues; ~InlineSpiller() {} @@ -64,17 +63,16 @@ InlineSpiller(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm) - : pass_(pass), - mf_(mf), - lis_(pass.getAnalysis()), - lss_(pass.getAnalysis()), - aa_(&pass.getAnalysis()), - vrm_(vrm), - mfi_(*mf.getFrameInfo()), - mri_(mf.getRegInfo()), - tii_(*mf.getTarget().getInstrInfo()), - tri_(*mf.getTarget().getRegisterInfo()), - reserved_(tri_.getReservedRegs(mf_)) {} + : Pass(pass), + MF(mf), + LIS(pass.getAnalysis()), + LSS(pass.getAnalysis()), + AA(&pass.getAnalysis()), + VRM(vrm), + MFI(*mf.getFrameInfo()), + MRI(mf.getRegInfo()), + TII(*mf.getTarget().getInstrInfo()), + TRI(*mf.getTarget().getRegisterInfo()) {} void spill(LiveRangeEdit &); @@ -135,9 +133,9 @@ /// isSnippet - Identify if a live interval is a snippet that should be spilled. /// It is assumed that SnipLI is a virtual register with the same original as -/// edit_->getReg(). +/// Edit->getReg(). bool InlineSpiller::isSnippet(const LiveInterval &SnipLI) { - unsigned Reg = edit_->getReg(); + unsigned Reg = Edit->getReg(); // A snippet is a tiny live range with only a single instruction using it // besides copies to/from Reg or spills/fills. We accept: @@ -146,14 +144,14 @@ // %snip = USE %snip // %Reg = COPY %snip / SPILL %snip, fi# // - if (SnipLI.getNumValNums() > 2 || !lis_.intervalIsInOneMBB(SnipLI)) + if (SnipLI.getNumValNums() > 2 || !LIS.intervalIsInOneMBB(SnipLI)) return false; MachineInstr *UseMI = 0; // Check that all uses satisfy our criteria. for (MachineRegisterInfo::reg_nodbg_iterator - RI = mri_.reg_nodbg_begin(SnipLI.reg); + RI = MRI.reg_nodbg_begin(SnipLI.reg); MachineInstr *MI = RI.skipInstruction();) { // Allow copies to/from Reg. @@ -162,11 +160,11 @@ // Allow stack slot loads. int FI; - if (SnipLI.reg == tii_.isLoadFromStackSlot(MI, FI) && FI == stackSlot_) + if (SnipLI.reg == TII.isLoadFromStackSlot(MI, FI) && FI == StackSlot) continue; // Allow stack slot stores. - if (SnipLI.reg == tii_.isStoreToStackSlot(MI, FI) && FI == stackSlot_) + if (SnipLI.reg == TII.isStoreToStackSlot(MI, FI) && FI == StackSlot) continue; // Allow a single additional instruction. @@ -180,8 +178,8 @@ /// collectRegsToSpill - Collect live range snippets that only have a single /// real use. void InlineSpiller::collectRegsToSpill() { - unsigned Reg = edit_->getReg(); - unsigned Orig = vrm_.getOriginal(Reg); + unsigned Reg = Edit->getReg(); + unsigned Orig = VRM.getOriginal(Reg); // Main register always spills. RegsToSpill.assign(1, Reg); @@ -192,16 +190,16 @@ if (Orig == Reg) return; - for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(Reg); + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Reg); MachineInstr *MI = RI.skipInstruction();) { unsigned SnipReg = isFullCopyOf(MI, Reg); if (!SnipReg) continue; if (!TargetRegisterInfo::isVirtualRegister(SnipReg)) continue; - if (vrm_.getOriginal(SnipReg) != Orig) + if (VRM.getOriginal(SnipReg) != Orig) continue; - LiveInterval &SnipLI = lis_.getInterval(SnipReg); + LiveInterval &SnipLI = LIS.getInterval(SnipReg); if (!isSnippet(SnipLI)) continue; SnippetCopies.insert(MI); @@ -215,14 +213,14 @@ /// reMaterializeFor - Attempt to rematerialize before MI instead of reloading. bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) { - SlotIndex UseIdx = lis_.getInstructionIndex(MI).getUseIndex(); - VNInfo *OrigVNI = edit_->getParent().getVNInfoAt(UseIdx); + SlotIndex UseIdx = LIS.getInstructionIndex(MI).getUseIndex(); + VNInfo *OrigVNI = Edit->getParent().getVNInfoAt(UseIdx); if (!OrigVNI) { DEBUG(dbgs() << "\tadding flags: "); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); - if (MO.isReg() && MO.isUse() && MO.getReg() == edit_->getReg()) + if (MO.isReg() && MO.isUse() && MO.getReg() == Edit->getReg()) MO.setIsUndef(); } DEBUG(dbgs() << UseIdx << '\t' << *MI); @@ -231,27 +229,27 @@ // FIXME: Properly remat for snippets as well. if (SnippetCopies.count(MI)) { - usedValues_.insert(OrigVNI); + UsedValues.insert(OrigVNI); return false; } LiveRangeEdit::Remat RM(OrigVNI); - if (!edit_->canRematerializeAt(RM, UseIdx, false, lis_)) { - usedValues_.insert(OrigVNI); + if (!Edit->canRematerializeAt(RM, UseIdx, false, LIS)) { + UsedValues.insert(OrigVNI); DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << *MI); return false; } - // If the instruction also writes edit_->getReg(), it had better not require + // If the instruction also writes Edit->getReg(), it had better not require // the same register for uses and defs. bool Reads, Writes; SmallVector Ops; - tie(Reads, Writes) = MI->readsWritesVirtualRegister(edit_->getReg(), &Ops); + tie(Reads, Writes) = MI->readsWritesVirtualRegister(Edit->getReg(), &Ops); if (Writes) { for (unsigned i = 0, e = Ops.size(); i != e; ++i) { MachineOperand &MO = MI->getOperand(Ops[i]); if (MO.isUse() ? MI->isRegTiedToDefOperand(Ops[i]) : MO.getSubReg()) { - usedValues_.insert(OrigVNI); + UsedValues.insert(OrigVNI); DEBUG(dbgs() << "\tcannot remat tied reg: " << UseIdx << '\t' << *MI); return false; } @@ -262,35 +260,35 @@ // fold a load into the instruction. That avoids allocating a new register. if (RM.OrigMI->getDesc().canFoldAsLoad() && foldMemoryOperand(MI, Ops, RM.OrigMI)) { - edit_->markRematerialized(RM.ParentVNI); + Edit->markRematerialized(RM.ParentVNI); return true; } // Alocate a new register for the remat. - LiveInterval &NewLI = edit_->create(mri_, lis_, vrm_); + LiveInterval &NewLI = Edit->create(MRI, LIS, VRM); NewLI.markNotSpillable(); // Rematting for a copy: Set allocation hint to be the destination register. if (MI->isCopy()) - mri_.setRegAllocationHint(NewLI.reg, 0, MI->getOperand(0).getReg()); + MRI.setRegAllocationHint(NewLI.reg, 0, MI->getOperand(0).getReg()); // Finally we can rematerialize OrigMI before MI. - SlotIndex DefIdx = edit_->rematerializeAt(*MI->getParent(), MI, NewLI.reg, RM, - lis_, tii_, tri_); + SlotIndex DefIdx = Edit->rematerializeAt(*MI->getParent(), MI, NewLI.reg, RM, + LIS, TII, TRI); DEBUG(dbgs() << "\tremat: " << DefIdx << '\t' - << *lis_.getInstructionFromIndex(DefIdx)); + << *LIS.getInstructionFromIndex(DefIdx)); // Replace operands for (unsigned i = 0, e = Ops.size(); i != e; ++i) { MachineOperand &MO = MI->getOperand(Ops[i]); - if (MO.isReg() && MO.isUse() && MO.getReg() == edit_->getReg()) { + if (MO.isReg() && MO.isUse() && MO.getReg() == Edit->getReg()) { MO.setReg(NewLI.reg); MO.setIsKill(); } } DEBUG(dbgs() << "\t " << UseIdx << '\t' << *MI); - VNInfo *DefVNI = NewLI.getNextValue(DefIdx, 0, lis_.getVNInfoAllocator()); + VNInfo *DefVNI = NewLI.getNextValue(DefIdx, 0, LIS.getVNInfoAllocator()); NewLI.addRange(LiveRange(DefIdx, UseIdx.getDefIndex(), DefVNI)); DEBUG(dbgs() << "\tinterval: " << NewLI << '\n'); return true; @@ -300,15 +298,15 @@ /// and trim the live ranges after. void InlineSpiller::reMaterializeAll() { // Do a quick scan of the interval values to find if any are remattable. - if (!edit_->anyRematerializable(lis_, tii_, aa_)) + if (!Edit->anyRematerializable(LIS, TII, AA)) return; - usedValues_.clear(); + UsedValues.clear(); - // Try to remat before all uses of edit_->getReg(). + // Try to remat before all uses of Edit->getReg(). bool anyRemat = false; for (MachineRegisterInfo::use_nodbg_iterator - RI = mri_.use_nodbg_begin(edit_->getReg()); + RI = MRI.use_nodbg_begin(Edit->getReg()); MachineInstr *MI = RI.skipInstruction();) anyRemat |= reMaterializeFor(MI); @@ -317,16 +315,16 @@ // Remove any values that were completely rematted. bool anyRemoved = false; - for (LiveInterval::vni_iterator I = edit_->getParent().vni_begin(), - E = edit_->getParent().vni_end(); I != E; ++I) { + for (LiveInterval::vni_iterator I = Edit->getParent().vni_begin(), + E = Edit->getParent().vni_end(); I != E; ++I) { VNInfo *VNI = *I; - if (VNI->hasPHIKill() || !edit_->didRematerialize(VNI) || - usedValues_.count(VNI)) + if (VNI->hasPHIKill() || !Edit->didRematerialize(VNI) || + UsedValues.count(VNI)) continue; - MachineInstr *DefMI = lis_.getInstructionFromIndex(VNI->def); + MachineInstr *DefMI = LIS.getInstructionFromIndex(VNI->def); DEBUG(dbgs() << "\tremoving dead def: " << VNI->def << '\t' << *DefMI); - lis_.RemoveMachineInstrFromMaps(DefMI); - vrm_.RemoveMachineInstrFromMaps(DefMI); + LIS.RemoveMachineInstrFromMaps(DefMI); + VRM.RemoveMachineInstrFromMaps(DefMI); DefMI->eraseFromParent(); VNI->def = SlotIndex(); anyRemoved = true; @@ -336,17 +334,17 @@ return; // Removing values may cause debug uses where parent is not live. - for (MachineRegisterInfo::use_iterator RI = mri_.use_begin(edit_->getReg()); + for (MachineRegisterInfo::use_iterator RI = MRI.use_begin(Edit->getReg()); MachineInstr *MI = RI.skipInstruction();) { if (!MI->isDebugValue()) continue; // Try to preserve the debug value if parent is live immediately after it. MachineBasicBlock::iterator NextMI = MI; ++NextMI; - if (NextMI != MI->getParent()->end() && !lis_.isNotInMIMap(NextMI)) { - SlotIndex Idx = lis_.getInstructionIndex(NextMI); - VNInfo *VNI = edit_->getParent().getVNInfoAt(Idx); - if (VNI && (VNI->hasPHIKill() || usedValues_.count(VNI))) + if (NextMI != MI->getParent()->end() && !LIS.isNotInMIMap(NextMI)) { + SlotIndex Idx = LIS.getInstructionIndex(NextMI); + VNInfo *VNI = Edit->getParent().getVNInfoAt(Idx); + if (VNI && (VNI->hasPHIKill() || UsedValues.count(VNI))) continue; } DEBUG(dbgs() << "Removing debug info due to remat:" << "\t" << *MI); @@ -354,20 +352,20 @@ } } -/// If MI is a load or store of stackSlot_, it can be removed. +/// If MI is a load or store of StackSlot, it can be removed. bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { int FI = 0; unsigned InstrReg; - if (!(InstrReg = tii_.isLoadFromStackSlot(MI, FI)) && - !(InstrReg = tii_.isStoreToStackSlot(MI, FI))) + if (!(InstrReg = TII.isLoadFromStackSlot(MI, FI)) && + !(InstrReg = TII.isStoreToStackSlot(MI, FI))) return false; // We have a stack access. Is it the right register and slot? - if (InstrReg != Reg || FI != stackSlot_) + if (InstrReg != Reg || FI != StackSlot) return false; DEBUG(dbgs() << "Coalescing stack access: " << *MI); - lis_.RemoveMachineInstrFromMaps(MI); + LIS.RemoveMachineInstrFromMaps(MI); MI->eraseFromParent(); return true; } @@ -400,13 +398,13 @@ } MachineInstr *FoldMI = - LoadMI ? tii_.foldMemoryOperand(MI, FoldOps, LoadMI) - : tii_.foldMemoryOperand(MI, FoldOps, stackSlot_); + LoadMI ? TII.foldMemoryOperand(MI, FoldOps, LoadMI) + : TII.foldMemoryOperand(MI, FoldOps, StackSlot); if (!FoldMI) return false; - lis_.ReplaceMachineInstrInMaps(MI, FoldMI); + LIS.ReplaceMachineInstrInMaps(MI, FoldMI); if (!LoadMI) - vrm_.addSpillSlotUse(stackSlot_, FoldMI); + VRM.addSpillSlotUse(StackSlot, FoldMI); MI->eraseFromParent(); DEBUG(dbgs() << "\tfolded: " << *FoldMI); return true; @@ -416,14 +414,14 @@ void InlineSpiller::insertReload(LiveInterval &NewLI, MachineBasicBlock::iterator MI) { MachineBasicBlock &MBB = *MI->getParent(); - SlotIndex Idx = lis_.getInstructionIndex(MI).getDefIndex(); - tii_.loadRegFromStackSlot(MBB, MI, NewLI.reg, stackSlot_, rc_, &tri_); + SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex(); + TII.loadRegFromStackSlot(MBB, MI, NewLI.reg, StackSlot, RC, &TRI); --MI; // Point to load instruction. - SlotIndex LoadIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex(); - vrm_.addSpillSlotUse(stackSlot_, MI); + SlotIndex LoadIdx = LIS.InsertMachineInstrInMaps(MI).getDefIndex(); + VRM.addSpillSlotUse(StackSlot, MI); DEBUG(dbgs() << "\treload: " << LoadIdx << '\t' << *MI); VNInfo *LoadVNI = NewLI.getNextValue(LoadIdx, 0, - lis_.getVNInfoAllocator()); + LIS.getVNInfoAllocator()); NewLI.addRange(LiveRange(LoadIdx, Idx, LoadVNI)); } @@ -433,26 +431,26 @@ MachineBasicBlock &MBB = *MI->getParent(); // Get the defined value. It could be an early clobber so keep the def index. - SlotIndex Idx = lis_.getInstructionIndex(MI).getDefIndex(); + SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex(); VNInfo *VNI = OldLI.getVNInfoAt(Idx); assert(VNI && VNI->def.getDefIndex() == Idx && "Inconsistent VNInfo"); Idx = VNI->def; - tii_.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, stackSlot_, rc_, &tri_); + TII.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, StackSlot, RC, &TRI); --MI; // Point to store instruction. - SlotIndex StoreIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex(); - vrm_.addSpillSlotUse(stackSlot_, MI); + SlotIndex StoreIdx = LIS.InsertMachineInstrInMaps(MI).getDefIndex(); + VRM.addSpillSlotUse(StackSlot, MI); DEBUG(dbgs() << "\tspilled: " << StoreIdx << '\t' << *MI); - VNInfo *StoreVNI = NewLI.getNextValue(Idx, 0, lis_.getVNInfoAllocator()); + VNInfo *StoreVNI = NewLI.getNextValue(Idx, 0, LIS.getVNInfoAllocator()); NewLI.addRange(LiveRange(Idx, StoreIdx, StoreVNI)); } /// spillAroundUses - insert spill code around each use of Reg. void InlineSpiller::spillAroundUses(unsigned Reg) { - LiveInterval &OldLI = lis_.getInterval(Reg); + LiveInterval &OldLI = LIS.getInterval(Reg); // Iterate over instructions using Reg. - for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(Reg); + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Reg); MachineInstr *MI = RI.skipInstruction();) { // Debug values are not allowed to affect codegen. @@ -461,7 +459,7 @@ uint64_t Offset = MI->getOperand(1).getImm(); const MDNode *MDPtr = MI->getOperand(2).getMetadata(); DebugLoc DL = MI->getDebugLoc(); - if (MachineInstr *NewDV = tii_.emitFrameIndexDebugValue(mf_, stackSlot_, + if (MachineInstr *NewDV = TII.emitFrameIndexDebugValue(MF, StackSlot, Offset, MDPtr, DL)) { DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *MI); MachineBasicBlock *MBB = MI->getParent(); @@ -492,7 +490,7 @@ // Allocate interval around instruction. // FIXME: Infer regclass from instruction alone. - LiveInterval &NewLI = edit_->create(mri_, lis_, vrm_); + LiveInterval &NewLI = Edit->create(MRI, LIS, VRM); NewLI.markNotSpillable(); if (Reads) @@ -521,42 +519,42 @@ } void InlineSpiller::spill(LiveRangeEdit &edit) { - edit_ = &edit; + Edit = &edit; assert(!TargetRegisterInfo::isStackSlot(edit.getReg()) && "Trying to spill a stack slot."); DEBUG(dbgs() << "Inline spilling " - << mri_.getRegClass(edit.getReg())->getName() + << MRI.getRegClass(edit.getReg())->getName() << ':' << edit.getParent() << "\nFrom original " - << PrintReg(vrm_.getOriginal(edit.getReg())) << '\n'); + << PrintReg(VRM.getOriginal(edit.getReg())) << '\n'); assert(edit.getParent().isSpillable() && "Attempting to spill already spilled value."); // Share a stack slot among all descendants of Orig. - unsigned Orig = vrm_.getOriginal(edit.getReg()); - stackSlot_ = vrm_.getStackSlot(Orig); + unsigned Orig = VRM.getOriginal(edit.getReg()); + StackSlot = VRM.getStackSlot(Orig); collectRegsToSpill(); reMaterializeAll(); // Remat may handle everything. - if (edit_->getParent().empty()) + if (Edit->getParent().empty()) return; - rc_ = mri_.getRegClass(edit.getReg()); + RC = MRI.getRegClass(edit.getReg()); - if (stackSlot_ == VirtRegMap::NO_STACK_SLOT) - stackSlot_ = vrm_.assignVirt2StackSlot(Orig); + if (StackSlot == VirtRegMap::NO_STACK_SLOT) + StackSlot = VRM.assignVirt2StackSlot(Orig); if (Orig != edit.getReg()) - vrm_.assignVirt2StackSlot(edit.getReg(), stackSlot_); + VRM.assignVirt2StackSlot(edit.getReg(), StackSlot); // Update LiveStacks now that we are committed to spilling. - LiveInterval &stacklvr = lss_.getOrCreateInterval(stackSlot_, rc_); + LiveInterval &stacklvr = LSS.getOrCreateInterval(StackSlot, RC); if (!stacklvr.hasAtLeastOneValue()) - stacklvr.getNextValue(SlotIndex(), 0, lss_.getVNInfoAllocator()); + stacklvr.getNextValue(SlotIndex(), 0, LSS.getVNInfoAllocator()); for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) - stacklvr.MergeRangesInAsValue(lis_.getInterval(RegsToSpill[i]), + stacklvr.MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]), stacklvr.getValNumInfo(0)); // Spill around uses of all RegsToSpill. @@ -564,15 +562,15 @@ spillAroundUses(RegsToSpill[i]); // Finally delete the SnippetCopies. - for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(edit.getReg()); + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(edit.getReg()); MachineInstr *MI = RI.skipInstruction();) { assert(SnippetCopies.count(MI) && "Remaining use wasn't a snippet copy"); // FIXME: Do this with a LiveRangeEdit callback. - vrm_.RemoveMachineInstrFromMaps(MI); - lis_.RemoveMachineInstrFromMaps(MI); + VRM.RemoveMachineInstrFromMaps(MI); + LIS.RemoveMachineInstrFromMaps(MI); MI->eraseFromParent(); } for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) - edit.eraseVirtReg(RegsToSpill[i], lis_); + edit.eraseVirtReg(RegsToSpill[i], LIS); } From rjmccall at apple.com Mon Mar 14 15:01:21 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 14 Mar 2011 20:01:21 -0000 Subject: [llvm-commits] [llvm] r127608 - in /llvm/trunk/include/llvm/Support: Compiler.h ErrorHandling.h Message-ID: <20110314200121.CBF742A6C12C@llvm.org> Author: rjmccall Date: Mon Mar 14 15:01:21 2011 New Revision: 127608 URL: http://llvm.org/viewvc/llvm-project?rev=127608&view=rev Log: Make llvm_unreachable evaluate to __builtin_unreachable() in -Asserts builds, which was the apparent consensus of PR8973 and llvmdev. Modified: llvm/trunk/include/llvm/Support/Compiler.h llvm/trunk/include/llvm/Support/ErrorHandling.h Modified: llvm/trunk/include/llvm/Support/Compiler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Compiler.h?rev=127608&r1=127607&r2=127608&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Compiler.h (original) +++ llvm/trunk/include/llvm/Support/Compiler.h Mon Mar 14 15:01:21 2011 @@ -126,4 +126,19 @@ decl #endif +// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands +// to an expression which states that it is undefined behavior for the +// compiler to reach this point. +#if defined(__clang__) || (__GNUC__ > 4) \ + || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() +#else +#ifdef __cplusplus +extern "C" LLVM_ATTRIBUTE_NORETURN void abort(); +#else +extern LLVM_ATTRIBUTE_NORETURN void abort(); +#endif +# define LLVM_BUILTIN_UNREACHABLE abort() +#endif + #endif Modified: llvm/trunk/include/llvm/Support/ErrorHandling.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ErrorHandling.h?rev=127608&r1=127607&r2=127608&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ErrorHandling.h (original) +++ llvm/trunk/include/llvm/Support/ErrorHandling.h Mon Mar 14 15:01:21 2011 @@ -97,7 +97,7 @@ #define llvm_unreachable(msg) \ ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__) #else -#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal() +#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE #endif #endif From rjmccall at apple.com Mon Mar 14 15:10:50 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 14 Mar 2011 20:10:50 -0000 Subject: [llvm-commits] [llvm] r127610 - /llvm/trunk/include/llvm/Support/Compiler.h Message-ID: <20110314201050.2C2BC2A6C12C@llvm.org> Author: rjmccall Date: Mon Mar 14 15:10:50 2011 New Revision: 127610 URL: http://llvm.org/viewvc/llvm-project?rev=127610&view=rev Log: Fix the exception-specification of abort() when declaring it in C++. Modified: llvm/trunk/include/llvm/Support/Compiler.h Modified: llvm/trunk/include/llvm/Support/Compiler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Compiler.h?rev=127610&r1=127609&r2=127610&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Compiler.h (original) +++ llvm/trunk/include/llvm/Support/Compiler.h Mon Mar 14 15:10:50 2011 @@ -134,7 +134,7 @@ # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #else #ifdef __cplusplus -extern "C" LLVM_ATTRIBUTE_NORETURN void abort(); +extern "C" LLVM_ATTRIBUTE_NORETURN void abort() throw(); #else extern LLVM_ATTRIBUTE_NORETURN void abort(); #endif From rjmccall at apple.com Mon Mar 14 15:20:29 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 14 Mar 2011 20:20:29 -0000 Subject: [llvm-commits] [llvm] r127612 - /llvm/trunk/include/llvm/Support/Compiler.h Message-ID: <20110314202029.A97B72A6C12C@llvm.org> Author: rjmccall Date: Mon Mar 14 15:20:29 2011 New Revision: 127612 URL: http://llvm.org/viewvc/llvm-project?rev=127612&view=rev Log: Okay, some compilers complain if you provide the exception-specification where none was before. Just don't declare it and hope it's declared in every translation unit that needs it. Modified: llvm/trunk/include/llvm/Support/Compiler.h Modified: llvm/trunk/include/llvm/Support/Compiler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Compiler.h?rev=127612&r1=127611&r2=127612&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Compiler.h (original) +++ llvm/trunk/include/llvm/Support/Compiler.h Mon Mar 14 15:20:29 2011 @@ -133,11 +133,6 @@ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #else -#ifdef __cplusplus -extern "C" LLVM_ATTRIBUTE_NORETURN void abort() throw(); -#else -extern LLVM_ATTRIBUTE_NORETURN void abort(); -#endif # define LLVM_BUILTIN_UNREACHABLE abort() #endif From stoklund at 2pi.dk Mon Mar 14 15:57:14 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 14 Mar 2011 20:57:14 -0000 Subject: [llvm-commits] [llvm] r127618 - in /llvm/trunk: include/llvm/CodeGen/ProcessImplicitDefs.h lib/CodeGen/ProcessImplicitDefs.cpp Message-ID: <20110314205714.C07542A6C12C@llvm.org> Author: stoklund Date: Mon Mar 14 15:57:14 2011 New Revision: 127618 URL: http://llvm.org/viewvc/llvm-project?rev=127618&view=rev Log: Place context in member variables instead of passing around pointers. Use the opportunity to get rid of the trailing underscore variable names. Modified: llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp Modified: llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h?rev=127618&r1=127617&r2=127618&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h (original) +++ llvm/trunk/include/llvm/CodeGen/ProcessImplicitDefs.h Mon Mar 14 15:57:14 2011 @@ -18,14 +18,20 @@ class MachineInstr; class TargetInstrInfo; + class TargetRegisterInfo; + class MachineRegisterInfo; + class LiveVariables; /// Process IMPLICIT_DEF instructions and make sure there is one implicit_def /// for each use. Add isUndef marker to implicit_def defs and their uses. class ProcessImplicitDefs : public MachineFunctionPass { - private: + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + MachineRegisterInfo *MRI; + LiveVariables *LV; bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, - unsigned OpIdx, const TargetInstrInfo *tii_, + unsigned OpIdx, SmallSet &ImpDefRegs); public: Modified: llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp?rev=127618&r1=127617&r2=127618&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp (original) +++ llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp Mon Mar 14 15:57:14 2011 @@ -47,7 +47,6 @@ bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, unsigned OpIdx, - const TargetInstrInfo *tii_, SmallSet &ImpDefRegs) { switch(OpIdx) { case 1: @@ -61,7 +60,6 @@ } static bool isUndefCopy(MachineInstr *MI, unsigned Reg, - const TargetInstrInfo *tii_, SmallSet &ImpDefRegs) { if (MI->isCopy()) { MachineOperand &MO0 = MI->getOperand(0); @@ -86,11 +84,10 @@ bool Changed = false; - const TargetInstrInfo *tii_ = fn.getTarget().getInstrInfo(); - const TargetRegisterInfo *tri_ = fn.getTarget().getRegisterInfo(); - MachineRegisterInfo *mri_ = &fn.getRegInfo(); - - LiveVariables *lv_ = &getAnalysis(); + TII = fn.getTarget().getInstrInfo(); + TRI = fn.getTarget().getRegisterInfo(); + MRI = &fn.getRegInfo(); + LV = &getAnalysis(); SmallSet ImpDefRegs; SmallVector ImpDefMIs; @@ -113,7 +110,7 @@ unsigned Reg = MI->getOperand(0).getReg(); ImpDefRegs.insert(Reg); if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS) + for (const unsigned *SS = TRI->getSubRegisters(Reg); *SS; ++SS) ImpDefRegs.insert(*SS); } ImpDefMIs.push_back(MI); @@ -125,7 +122,7 @@ MachineOperand &MO = MI->getOperand(1); if (MO.isUndef() || ImpDefRegs.count(MO.getReg())) { if (MO.isKill()) { - LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg()); + LiveVariables::VarInfo& vi = LV->getVarInfo(MO.getReg()); vi.removeKill(MI); } MI->eraseFromParent(); @@ -145,14 +142,14 @@ if (!ImpDefRegs.count(Reg)) continue; // Use is a copy, just turn it into an implicit_def. - if (CanTurnIntoImplicitDef(MI, Reg, i, tii_, ImpDefRegs)) { + if (CanTurnIntoImplicitDef(MI, Reg, i, ImpDefRegs)) { bool isKill = MO.isKill(); - MI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); + MI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF)); for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j) MI->RemoveOperand(j); if (isKill) { ImpDefRegs.erase(Reg); - LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); + LiveVariables::VarInfo& vi = LV->getVarInfo(Reg); vi.removeKill(MI); } ChangedToImpDef = true; @@ -210,8 +207,8 @@ // uses. bool Skip = false; SmallVector DeadImpDefs; - for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg), - DE = mri_->def_end(); DI != DE; ++DI) { + for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(Reg), + DE = MRI->def_end(); DI != DE; ++DI) { MachineInstr *DeadImpDef = &*DI; if (!DeadImpDef->isImplicitDef()) { Skip = true; @@ -229,8 +226,8 @@ Changed = true; // Process each use instruction once. - for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), - UE = mri_->use_end(); UI != UE; ++UI) { + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg), + UE = MRI->use_end(); UI != UE; ++UI) { if (UI.getOperand().isUndef()) continue; MachineInstr *RMI = &*UI; @@ -242,8 +239,8 @@ MachineInstr *RMI = RUses[i]; // Turn a copy use into an implicit_def. - if (isUndefCopy(RMI, Reg, tii_, ImpDefRegs)) { - RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); + if (isUndefCopy(RMI, Reg, ImpDefRegs)) { + RMI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF)); bool isKill = false; SmallVector Ops; @@ -263,15 +260,15 @@ // Update LiveVariables varinfo if the instruction is a kill. if (isKill) { - LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg); + LiveVariables::VarInfo& vi = LV->getVarInfo(Reg); vi.removeKill(RMI); } continue; } // Replace Reg with a new vreg that's marked implicit. - const TargetRegisterClass* RC = mri_->getRegClass(Reg); - unsigned NewVReg = mri_->createVirtualRegister(RC); + const TargetRegisterClass* RC = MRI->getRegClass(Reg); + unsigned NewVReg = MRI->createVirtualRegister(RC); bool isKill = true; for (unsigned j = 0, ee = RMI->getNumOperands(); j != ee; ++j) { MachineOperand &RRMO = RMI->getOperand(j); From renato.golin at arm.com Mon Mar 14 16:02:29 2011 From: renato.golin at arm.com (Renato Golin) Date: Mon, 14 Mar 2011 21:02:29 +0000 Subject: [llvm-commits] LLVM-diff refactoring Message-ID: This patch is a big refactoring of llvm-diff. It doesn't add new features, but it re-organizes the old features, so I can insert the MetadataEngine to use the same infrastructure. -- cheers, --renato -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-diff-refactoring.patch Type: text/x-patch Size: 14406 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110314/8317121e/attachment.bin From resistor at mac.com Mon Mar 14 15:58:49 2011 From: resistor at mac.com (Owen Anderson) Date: Mon, 14 Mar 2011 20:58:49 -0000 Subject: [llvm-commits] [llvm] r127619 - /llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Message-ID: <20110314205849.9062D2A6C12C@llvm.org> Author: resistor Date: Mon Mar 14 15:58:49 2011 New Revision: 127619 URL: http://llvm.org/viewvc/llvm-project?rev=127619&view=rev Log: Ignore isCodeGenOnly instructions when generating diassembly tables. Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=127619&r1=127618&r2=127619&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Mon Mar 14 15:58:49 2011 @@ -1224,7 +1224,8 @@ if (Bits.allInComplete()) return false; // Ignore "asm parser only" instructions. - if (Def.getValueAsBit("isAsmParserOnly")) + if (Def.getValueAsBit("isAsmParserOnly") || + Def.getValueAsBit("isCodeGenOnly")) return false; std::vector InsnOperands; From grosbach at apple.com Mon Mar 14 15:59:06 2011 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 14 Mar 2011 20:59:06 -0000 Subject: [llvm-commits] [llvm] r127620 - /llvm/trunk/include/llvm-c/EnhancedDisassembly.h Message-ID: <20110314205907.02AF42A6C12C@llvm.org> Author: grosbach Date: Mon Mar 14 15:59:06 2011 New Revision: 127620 URL: http://llvm.org/viewvc/llvm-project?rev=127620&view=rev Log: Trailing whitespace. Modified: llvm/trunk/include/llvm-c/EnhancedDisassembly.h Modified: llvm/trunk/include/llvm-c/EnhancedDisassembly.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/EnhancedDisassembly.h?rev=127620&r1=127619&r2=127620&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/EnhancedDisassembly.h (original) +++ llvm/trunk/include/llvm-c/EnhancedDisassembly.h Mon Mar 14 15:59:06 2011 @@ -44,7 +44,7 @@ @param arg An anonymous argument for client use. @result 0 if the register could be read; -1 otherwise. */ -typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID, +typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID, void* arg); /*! @@ -83,7 +83,7 @@ Encapsulates an operand of an instruction. */ typedef void *EDOperandRef; - + /*! @functiongroup Getting a disassembler */ @@ -91,7 +91,7 @@ /*! @function EDGetDisassembler Gets the disassembler for a given target. - @param disassembler A pointer whose target will be filled in with the + @param disassembler A pointer whose target will be filled in with the disassembler. @param triple Identifies the target. Example: "x86_64-apple-darwin10" @param syntax The assembly syntax to use when decoding instructions. @@ -104,12 +104,12 @@ /*! @functiongroup Generic architectural queries */ - + /*! @function EDGetRegisterName Gets the human-readable name for a given register. @param regName A pointer whose target will be pointed at the name of the - register. The name does not need to be deallocated and will be + register. The name does not need to be deallocated and will be @param disassembler The disassembler to query for the name. @param regID The register identifier, as returned by EDRegisterTokenValue. @result 0 on success; -1 otherwise. @@ -117,7 +117,7 @@ int EDGetRegisterName(const char** regName, EDDisassemblerRef disassembler, unsigned regID); - + /*! @function EDRegisterIsStackPointer Determines if a register is one of the platform's stack-pointer registers. @@ -137,16 +137,16 @@ */ int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler, unsigned regID); - + /*! @functiongroup Creating and querying instructions */ - + /*! @function EDCreateInst Gets a set of contiguous instructions from a disassembler. @param insts A pointer to an array that will be filled in with the - instructions. Must have at least count entries. Entries not filled in will + instructions. Must have at least count entries. Entries not filled in will be set to NULL. @param count The maximum number of instructions to fill in. @param disassembler The disassembler to use when decoding the instructions. @@ -197,7 +197,7 @@ @result 0 on success; -1 otherwise. */ int EDInstID(unsigned *instID, EDInstRef inst); - + /*! @function EDInstIsBranch @param inst The instruction to be queried. @@ -217,7 +217,7 @@ /*! @function EDBranchTargetID @param inst The instruction to be queried. - @result The ID of the branch target operand, suitable for use with + @result The ID of the branch target operand, suitable for use with EDCopyOperand. -1 if no such operand exists. */ int EDBranchTargetID(EDInstRef inst); @@ -225,7 +225,7 @@ /*! @function EDMoveSourceID @param inst The instruction to be queried. - @result The ID of the move source operand, suitable for use with + @result The ID of the move source operand, suitable for use with EDCopyOperand. -1 if no such operand exists. */ int EDMoveSourceID(EDInstRef inst); @@ -233,7 +233,7 @@ /*! @function EDMoveTargetID @param inst The instruction to be queried. - @result The ID of the move source operand, suitable for use with + @result The ID of the move source operand, suitable for use with EDCopyOperand. -1 if no such operand exists. */ int EDMoveTargetID(EDInstRef inst); @@ -241,7 +241,7 @@ /*! @functiongroup Creating and querying tokens */ - + /*! @function EDNumTokens @param inst The instruction to be queried. @@ -261,7 +261,7 @@ int EDGetToken(EDTokenRef *token, EDInstRef inst, int index); - + /*! @function EDGetTokenString Gets the disassembled text for a token. @@ -287,7 +287,7 @@ @result 1 if the token is whitespace; 0 if not; -1 on error. */ int EDTokenIsWhitespace(EDTokenRef token); - + /*! @function EDTokenIsPunctuation @param token The token to be queried. @@ -335,18 +335,18 @@ /*! @function EDRegisterTokenValue - @param registerID A pointer whose target will be filled in with the LLVM + @param registerID A pointer whose target will be filled in with the LLVM register identifier for the token. @param token The token to be queried. @result 0 on success; -1 otherwise. */ int EDRegisterTokenValue(unsigned *registerID, EDTokenRef token); - + /*! @functiongroup Creating and querying operands */ - + /*! @function EDNumOperands @param inst The instruction to be queried. @@ -366,7 +366,7 @@ int EDGetOperand(EDOperandRef *operand, EDInstRef inst, int index); - + /*! @function EDOperandIsRegister @param operand The operand to be queried. @@ -391,13 +391,13 @@ /*! @function EDRegisterOperandValue @param value A pointer whose target will be filled in with the LLVM register ID - of the register named by the operand. + of the register named by the operand. @param operand The operand to be queried. @result 0 on success; -1 otherwise. */ int EDRegisterOperandValue(unsigned *value, EDOperandRef operand); - + /*! @function EDImmediateOperandValue @param value A pointer whose target will be filled in with the value of the @@ -427,7 +427,7 @@ EDOperandRef operand, EDRegisterReaderCallback regReader, void *arg); - + #ifdef __BLOCKS__ /*! @@ -458,13 +458,13 @@ typedef int (^EDTokenVisitor_t)(EDTokenRef token); /*! @functiongroup Block-based interfaces */ - + /*! @function EDBlockCreateInsts Gets a set of contiguous instructions from a disassembler, using a block to read memory. @param insts A pointer to an array that will be filled in with the - instructions. Must have at least count entries. Entries not filled in will + instructions. Must have at least count entries. Entries not filled in will be set to NULL. @param count The maximum number of instructions to fill in. @param disassembler The disassembler to use when decoding the instructions. @@ -505,7 +505,7 @@ EDTokenVisitor_t visitor); #endif - + #ifdef __cplusplus } #endif From eli.friedman at gmail.com Mon Mar 14 16:09:21 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 14 Mar 2011 17:09:21 -0400 Subject: [llvm-commits] [llvm] r127591 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp In-Reply-To: <20110314172802.877602A6C12C@llvm.org> References: <20110314172802.877602A6C12C@llvm.org> Message-ID: On Mon, Mar 14, 2011 at 1:28 PM, Andrew Trick wrote: > Author: atrick > Date: Mon Mar 14 12:28:02 2011 > New Revision: 127591 > > URL: http://llvm.org/viewvc/llvm-project?rev=127591&view=rev > Log: > HowFarToZero can compute a trip count as long as the recurrence has no-self-wrap. Have you read http://llvm.org/bugs/show_bug.cgi?id=8942#c3 ? That goes a bit into why depending on no-self-wrap requires some infrastructure changes. -Eli > Modified: > ? ?llvm/trunk/lib/Analysis/ScalarEvolution.cpp > > Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127591&r1=127590&r2=127591&view=diff > ============================================================================== > --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) > +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 14 12:28:02 2011 > @@ -4978,15 +4978,6 @@ > ? const SCEV *Start = getSCEVAtScope(AddRec->getStart(), L->getParentLoop()); > ? const SCEV *Step = getSCEVAtScope(AddRec->getOperand(1), L->getParentLoop()); > > - ?// If the AddRec is NUW, then (in an unsigned sense) it cannot be counting up > - ?// to wrap to 0, it must be counting down to equal 0. ?Also, while counting > - ?// down, it cannot "miss" 0 (which would cause it to wrap), regardless of what > - ?// the stride is. ?As such, NUW addrec's will always become zero in > - ?// "start / -stride" steps, and we know that the division is exact. > - ?if (AddRec->getNoWrapFlags(SCEV::FlagNUW)) > - ? ?// FIXME: We really want an "isexact" bit for udiv. > - ? ?return getUDivExpr(Start, getNegativeSCEV(Step)); > - > ? // For now we handle only constant steps. > ? // > ? // TODO: Handle a nonconstant Step given AddRec. If the > @@ -5002,15 +4993,28 @@ > ? // For negative steps (counting down to zero): > ? // ? N = Start/-Step > ? // First compute the unsigned distance from zero in the direction of Step. > - ?const SCEV *Distance = StepC->getValue()->getValue().isNonNegative() ? > - ? ?getNegativeSCEV(Start) : Start; > + ?bool CountDown = StepC->getValue()->getValue().isNegative(); > + ?const SCEV *Distance = CountDown ? Start : getNegativeSCEV(Start); > > ? // Handle unitary steps, which cannot wraparound. > - ?if (StepC->getValue()->equalsInt(1)) ? ? ?// 1*N = -Start (mod 2^BW), so: > - ? ?return Distance; ? ? ? ? ? ? ? ? ? ? ? ?// ? N = -Start (as unsigned) > - > - ?if (StepC->getValue()->isAllOnesValue()) ?// -1*N = -Start (mod 2^BW), so: > - ? ?return Distance; ? ? ? ? ? ? ? ? ? ? ? ?// ? ?N = Start (as unsigned) > + ?// 1*N = -Start; -1*N = Start (mod 2^BW), so: > + ?// ? N = Distance (as unsigned) > + ?if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) > + ? ?return Distance; > + > + ?// If the recurrence is known not to wraparound, unsigned divide computes the > + ?// back edge count. We know that the value will either become zero (and thus > + ?// the loop terminates), that the loop will terminate through some other exit > + ?// condition first, or that the loop has undefined behavior. ?This means > + ?// we can't "miss" the exit value, even with nonunit stride. > + ?// > + ?// FIXME: Prove that loops always exhibits *acceptable* undefined > + ?// behavior. Loops must exhibit defined behavior until a wrapped value is > + ?// actually used. So the trip count computed by udiv could be smaller than the > + ?// number of well-defined iterations. > + ?if (AddRec->getNoWrapFlags(SCEV::FlagNW)) > + ? ?// FIXME: We really want an "isexact" bit for udiv. > + ? ?return getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step); > > ? // Then, try to solve the above equation provided that Start is constant. > ? if (const SCEVConstant *StartC = dyn_cast(Start)) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From echristo at apple.com Mon Mar 14 16:05:21 2011 From: echristo at apple.com (Eric Christopher) Date: Mon, 14 Mar 2011 21:05:21 -0000 Subject: [llvm-commits] [llvm] r127621 - /llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll Message-ID: <20110314210521.C0D692A6C12C@llvm.org> Author: echristo Date: Mon Mar 14 16:05:21 2011 New Revision: 127621 URL: http://llvm.org/viewvc/llvm-project?rev=127621&view=rev Log: Fix this test up a bit. Modified: llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll Modified: llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll?rev=127621&r1=127620&r2=127621&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll Mon Mar 14 16:05:21 2011 @@ -1,6 +1,4 @@ -; RUN: llc < %s -O0 -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64-n32" -target triple = "armv7-apple-darwin" +; RUN: llc -O0 -mtriple=armv7-apple-darwin < %s define i32 @main() nounwind ssp { entry: From rjmccall at apple.com Mon Mar 14 16:14:47 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 14 Mar 2011 14:14:47 -0700 Subject: [llvm-commits] LLVM-diff refactoring In-Reply-To: References: Message-ID: <5A6942F3-CE96-4375-99B7-02FE071C15CD@apple.com> On Mar 14, 2011, at 2:02 PM, Renato Golin wrote: > This patch is a big refactoring of llvm-diff. It doesn't add new > features, but it re-organizes the old features, so I can insert the > MetadataEngine to use the same infrastructure. Your patch is missing the new files. John. From Renato.Golin at arm.com Mon Mar 14 16:28:20 2011 From: Renato.Golin at arm.com (Renato Golin) Date: Mon, 14 Mar 2011 21:28:20 +0000 Subject: [llvm-commits] LLVM-diff refactoring In-Reply-To: <5A6942F3-CE96-4375-99B7-02FE071C15CD@apple.com> References: , <5A6942F3-CE96-4375-99B7-02FE071C15CD@apple.com> Message-ID: Hi John, I know, they were just mock-ups, and not adding new features, so I thought I could omit them for now. I can put them back, if you want. --renato ________________________________________ From: John McCall [rjmccall at apple.com] Sent: 14 March 2011 21:14 To: Renato Golin Cc: llvm-commits at cs.uiuc.edu for LLVM Subject: Re: [llvm-commits] LLVM-diff refactoring On Mar 14, 2011, at 2:02 PM, Renato Golin wrote: > This patch is a big refactoring of llvm-diff. It doesn't add new > features, but it re-organizes the old features, so I can insert the > MetadataEngine to use the same infrastructure. Your patch is missing the new files. John. -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. From rjmccall at apple.com Mon Mar 14 16:43:27 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 14 Mar 2011 14:43:27 -0700 Subject: [llvm-commits] LLVM-diff refactoring In-Reply-To: References: <5A6942F3-CE96-4375-99B7-02FE071C15CD@apple.com> Message-ID: <5784B40E-C324-49A6-8C07-F1DE75C2E5EC@apple.com> On Mar 14, 2011, at 2:28 PM, Renato Golin wrote: > I know, they were just mock-ups, and not adding new features, so I thought I could omit them for now. > > I can put them back, if you want. If you mean they just contain the code that you removed from the other files, then your patch seems fine; please go ahead and commit. John. From Renato.Golin at arm.com Mon Mar 14 16:47:25 2011 From: Renato.Golin at arm.com (Renato Golin) Date: Mon, 14 Mar 2011 21:47:25 +0000 Subject: [llvm-commits] LLVM-diff refactoring In-Reply-To: <5784B40E-C324-49A6-8C07-F1DE75C2E5EC@apple.com> References: <5A6942F3-CE96-4375-99B7-02FE071C15CD@apple.com> , <5784B40E-C324-49A6-8C07-F1DE75C2E5EC@apple.com> Message-ID: > If you mean they just contain the code that you removed from the > other files, then your patch seems fine; please go ahead and commit. Sorry, I forgot to 'svn add'. :/ I'm omitting the MetadataEngine.cpp/h that weren't adding new features. The rest is there, now. cheers, --renato -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-diff-refactoring.patch Type: text/x-patch Size: 27820 bytes Desc: llvm-diff-refactoring.patch Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110314/efe77873/attachment-0001.bin From rjmccall at apple.com Mon Mar 14 16:54:36 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 14 Mar 2011 14:54:36 -0700 Subject: [llvm-commits] LLVM-diff refactoring In-Reply-To: References: <5A6942F3-CE96-4375-99B7-02FE071C15CD@apple.com> <5784B40E-C324-49A6-8C07-F1DE75C2E5EC@apple.com> Message-ID: <8E9B1043-0CF6-474D-81C0-CFCE50076929@apple.com> On Mar 14, 2011, at 2:47 PM, Renato Golin wrote: >> If you mean they just contain the code that you removed from the >> other files, then your patch seems fine; please go ahead and commit. > > Sorry, I forgot to 'svn add'. :/ > > I'm omitting the MetadataEngine.cpp/h that weren't adding new features. The rest is there, now. Okay, looks fine. John. From geek4civic at gmail.com Mon Mar 14 17:00:28 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Tue, 15 Mar 2011 07:00:28 +0900 Subject: [llvm-commits] [PATCH] Suppress "Unused" warnings on Release-Asserts. In-Reply-To: References: Message-ID: Ping. filed PR9480. http://llvm.org/bugs/show_bug.cgi?id=9480 On Tue, Mar 8, 2011 at 9:32 PM, NAKAMURA Takumi wrote: > --- > ?lib/Analysis/LazyValueInfo.cpp ? ? ? ? ? ? ? ? ? | ? ?2 ++ > ?lib/Transforms/Instrumentation/PathProfiling.cpp | ? ?2 ++ > ?2 files changed, 4 insertions(+), 0 deletions(-) > > --- > I saw two warnings on --disable-assertions with clang++. > I am dubious whether they would be proper. > > ...Takumi From renato.golin at arm.com Mon Mar 14 17:22:46 2011 From: renato.golin at arm.com (Renato Golin) Date: Mon, 14 Mar 2011 22:22:46 -0000 Subject: [llvm-commits] [llvm] r127627 - in /llvm/trunk/tools/llvm-diff: CMakeLists.txt DiffConsumer.cpp DiffConsumer.h DiffLog.cpp DiffLog.h DifferenceEngine.cpp DifferenceEngine.h llvm-diff.cpp Message-ID: <20110314222246.607042A6C12C@llvm.org> Author: rengolin Date: Mon Mar 14 17:22:46 2011 New Revision: 127627 URL: http://llvm.org/viewvc/llvm-project?rev=127627&view=rev Log: This patch is a big refactoring of llvm-diff. It doesn't add new features, but it re-organizes the old features, so I can insert the MetadataEngine to use the same infrastructure. Added: llvm/trunk/tools/llvm-diff/DiffConsumer.cpp llvm/trunk/tools/llvm-diff/DiffConsumer.h llvm/trunk/tools/llvm-diff/DiffLog.cpp llvm/trunk/tools/llvm-diff/DiffLog.h Modified: llvm/trunk/tools/llvm-diff/CMakeLists.txt llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp llvm/trunk/tools/llvm-diff/DifferenceEngine.h llvm/trunk/tools/llvm-diff/llvm-diff.cpp Modified: llvm/trunk/tools/llvm-diff/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/CMakeLists.txt?rev=127627&r1=127626&r2=127627&view=diff ============================================================================== --- llvm/trunk/tools/llvm-diff/CMakeLists.txt (original) +++ llvm/trunk/tools/llvm-diff/CMakeLists.txt Mon Mar 14 17:22:46 2011 @@ -2,5 +2,7 @@ add_llvm_tool(llvm-diff llvm-diff.cpp + DiffConsumer.cpp + DiffLog.cpp DifferenceEngine.cpp ) Added: llvm/trunk/tools/llvm-diff/DiffConsumer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffConsumer.cpp?rev=127627&view=auto ============================================================================== --- llvm/trunk/tools/llvm-diff/DiffConsumer.cpp (added) +++ llvm/trunk/tools/llvm-diff/DiffConsumer.cpp Mon Mar 14 17:22:46 2011 @@ -0,0 +1,209 @@ +//===-- DiffConsumer.cpp - Difference Consumer ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This files implements the the LLVM difference Consumer +// +//===----------------------------------------------------------------------===// + +#include "DiffConsumer.h" + +#include "llvm/Module.h" +#include "llvm/Instructions.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +static void ComputeNumbering(Function *F, DenseMap &Numbering){ + unsigned IN = 0; + + // Arguments get the first numbers. + for (Function::arg_iterator + AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI) + if (!AI->hasName()) + Numbering[&*AI] = IN++; + + // Walk the basic blocks in order. + for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) { + if (!FI->hasName()) + Numbering[&*FI] = IN++; + + // Walk the instructions in order. + for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) + // void instructions don't get numbers. + if (!BI->hasName() && !BI->getType()->isVoidTy()) + Numbering[&*BI] = IN++; + } + + assert(!Numbering.empty() && "asked for numbering but numbering was no-op"); +} + + +void DiffConsumer::printValue(Value *V, bool isL) { + if (V->hasName()) { + out << (isa(V) ? '@' : '%') << V->getName(); + return; + } + if (V->getType()->isVoidTy()) { + if (isa(V)) { + out << "store to "; + printValue(cast(V)->getPointerOperand(), isL); + } else if (isa(V)) { + out << "call to "; + printValue(cast(V)->getCalledValue(), isL); + } else if (isa(V)) { + out << "invoke to "; + printValue(cast(V)->getCalledValue(), isL); + } else { + out << *V; + } + return; + } + + unsigned N = contexts.size(); + while (N > 0) { + --N; + DiffContext &ctxt = contexts[N]; + if (!ctxt.IsFunction) continue; + if (isL) { + if (ctxt.LNumbering.empty()) + ComputeNumbering(cast(ctxt.L), ctxt.LNumbering); + out << '%' << ctxt.LNumbering[V]; + return; + } else { + if (ctxt.RNumbering.empty()) + ComputeNumbering(cast(ctxt.R), ctxt.RNumbering); + out << '%' << ctxt.RNumbering[V]; + return; + } + } + + out << ""; +} + +void DiffConsumer::header() { + if (contexts.empty()) return; + for (SmallVectorImpl::iterator + I = contexts.begin(), E = contexts.end(); I != E; ++I) { + if (I->Differences) continue; + if (isa(I->L)) { + // Extra newline between functions. + if (Differences) out << "\n"; + + Function *L = cast(I->L); + Function *R = cast(I->R); + if (L->getName() != R->getName()) + out << "in function " << L->getName() + << " / " << R->getName() << ":\n"; + else + out << "in function " << L->getName() << ":\n"; + } else if (isa(I->L)) { + BasicBlock *L = cast(I->L); + BasicBlock *R = cast(I->R); + if (L->hasName() && R->hasName() && L->getName() == R->getName()) + out << " in block %" << L->getName() << ":\n"; + else { + out << " in block "; + printValue(L, true); + out << " / "; + printValue(R, false); + out << ":\n"; + } + } else if (isa(I->L)) { + out << " in instruction "; + printValue(I->L, true); + out << " / "; + printValue(I->R, false); + out << ":\n"; + } + + I->Differences = true; + } +} + +void DiffConsumer::indent() { + unsigned N = Indent; + while (N--) out << ' '; +} + +bool DiffConsumer::hadDifferences() const { + return Differences; +} + +void DiffConsumer::enterContext(Value *L, Value *R) { + contexts.push_back(DiffContext(L, R)); + Indent += 2; +} + +void DiffConsumer::exitContext() { + Differences |= contexts.back().Differences; + contexts.pop_back(); + Indent -= 2; +} + +void DiffConsumer::log(StringRef text) { + header(); + indent(); + out << text << '\n'; +} + +void DiffConsumer::logf(const LogBuilder &Log) { + header(); + indent(); + + unsigned arg = 0; + + StringRef format = Log.getFormat(); + while (true) { + size_t percent = format.find('%'); + if (percent == StringRef::npos) { + out << format; + break; + } + assert(format[percent] == '%'); + + if (percent > 0) out << format.substr(0, percent); + + switch (format[percent+1]) { + case '%': out << '%'; break; + case 'l': printValue(Log.getArgument(arg++), true); break; + case 'r': printValue(Log.getArgument(arg++), false); break; + default: llvm_unreachable("unknown format character"); + } + + format = format.substr(percent+2); + } + + out << '\n'; +} + +void DiffConsumer::logd(const DiffLogBuilder &Log) { + header(); + + for (unsigned I = 0, E = Log.getNumLines(); I != E; ++I) { + indent(); + switch (Log.getLineKind(I)) { + case DC_match: + out << " "; + Log.getLeft(I)->dump(); + //printValue(Log.getLeft(I), true); + break; + case DC_left: + out << "< "; + Log.getLeft(I)->dump(); + //printValue(Log.getLeft(I), true); + break; + case DC_right: + out << "> "; + Log.getRight(I)->dump(); + //printValue(Log.getRight(I), false); + break; + } + //out << "\n"; + } +} Added: llvm/trunk/tools/llvm-diff/DiffConsumer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffConsumer.h?rev=127627&view=auto ============================================================================== --- llvm/trunk/tools/llvm-diff/DiffConsumer.h (added) +++ llvm/trunk/tools/llvm-diff/DiffConsumer.h Mon Mar 14 17:22:46 2011 @@ -0,0 +1,91 @@ +//===-- DiffConsumer.h - Difference Consumer --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header defines the interface to the LLVM difference Consumer +// +//===----------------------------------------------------------------------===// + +#ifndef _LLVM_DIFFCONSUMER_H_ +#define _LLVM_DIFFCONSUMER_H_ + +#include "DiffLog.h" + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Casting.h" + +namespace llvm { + class Module; + class Value; + class Function; + + /// The interface for consumers of difference data. + struct Consumer { + /// Record that a local context has been entered. Left and + /// Right are IR "containers" of some sort which are being + /// considered for structural equivalence: global variables, + /// functions, blocks, instructions, etc. + virtual void enterContext(Value *Left, Value *Right) = 0; + + /// Record that a local context has been exited. + virtual void exitContext() = 0; + + /// Record a difference within the current context. + virtual void log(StringRef Text) = 0; + + /// Record a formatted difference within the current context. + virtual void logf(const LogBuilder &Log) = 0; + + /// Record a line-by-line instruction diff. + virtual void logd(const DiffLogBuilder &Log) = 0; + + protected: + virtual ~Consumer() {} + }; + + class DiffConsumer : public Consumer { + private: + struct DiffContext { + DiffContext(Value *L, Value *R) + : L(L), R(R), Differences(false), IsFunction(isa(L)) {} + Value *L; + Value *R; + bool Differences; + bool IsFunction; + DenseMap LNumbering; + DenseMap RNumbering; + }; + + raw_ostream &out; + Module *LModule; + Module *RModule; + SmallVector contexts; + bool Differences; + unsigned Indent; + + void printValue(Value *V, bool isL); + void header(); + void indent(); + + public: + DiffConsumer(Module *L, Module *R) + : out(errs()), LModule(L), RModule(R), Differences(false), Indent(0) {} + + bool hadDifferences() const; + void enterContext(Value *L, Value *R); + void exitContext(); + void log(StringRef text); + void logf(const LogBuilder &Log); + void logd(const DiffLogBuilder &Log); + }; +} + +#endif Added: llvm/trunk/tools/llvm-diff/DiffLog.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffLog.cpp?rev=127627&view=auto ============================================================================== --- llvm/trunk/tools/llvm-diff/DiffLog.cpp (added) +++ llvm/trunk/tools/llvm-diff/DiffLog.cpp Mon Mar 14 17:22:46 2011 @@ -0,0 +1,53 @@ +//===-- DiffLog.h - Difference Log Builder and accessories ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header defines the interface to the LLVM difference log builder. +// +//===----------------------------------------------------------------------===// + +#include "DiffLog.h" +#include "DiffConsumer.h" + +#include "llvm/Instructions.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +using namespace llvm; + +LogBuilder::~LogBuilder() { + consumer.logf(*this); +} + +StringRef LogBuilder::getFormat() const { return Format; } + +unsigned LogBuilder::getNumArguments() const { return Arguments.size(); } +Value *LogBuilder::getArgument(unsigned I) const { return Arguments[I]; } + +DiffLogBuilder::~DiffLogBuilder() { consumer.logd(*this); } + +void DiffLogBuilder::addMatch(Instruction *L, Instruction *R) { + Diff.push_back(DiffRecord(L, R)); +} +void DiffLogBuilder::addLeft(Instruction *L) { + // HACK: VS 2010 has a bug in the stdlib that requires this. + Diff.push_back(DiffRecord(L, DiffRecord::second_type(0))); +} +void DiffLogBuilder::addRight(Instruction *R) { + // HACK: VS 2010 has a bug in the stdlib that requires this. + Diff.push_back(DiffRecord(DiffRecord::first_type(0), R)); +} + +unsigned DiffLogBuilder::getNumLines() const { return Diff.size(); } + +DiffChange DiffLogBuilder::getLineKind(unsigned I) const { + return (Diff[I].first ? (Diff[I].second ? DC_match : DC_left) + : DC_right); +} +Instruction *DiffLogBuilder::getLeft(unsigned I) const { return Diff[I].first; } +Instruction *DiffLogBuilder::getRight(unsigned I) const { return Diff[I].second; } Added: llvm/trunk/tools/llvm-diff/DiffLog.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffLog.h?rev=127627&view=auto ============================================================================== --- llvm/trunk/tools/llvm-diff/DiffLog.h (added) +++ llvm/trunk/tools/llvm-diff/DiffLog.h Mon Mar 14 17:22:46 2011 @@ -0,0 +1,80 @@ +//===-- DiffLog.h - Difference Log Builder and accessories ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header defines the interface to the LLVM difference log builder. +// +//===----------------------------------------------------------------------===// + +#ifndef _LLVM_DIFFLOG_H_ +#define _LLVM_DIFFLOG_H_ + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +namespace llvm { + class Instruction; + class Value; + class Consumer; + + /// Trichotomy assumption + enum DiffChange { DC_match, DC_left, DC_right }; + + /// A temporary-object class for building up log messages. + class LogBuilder { + Consumer &consumer; + + /// The use of a stored StringRef here is okay because + /// LogBuilder should be used only as a temporary, and as a + /// temporary it will be destructed before whatever temporary + /// might be initializing this format. + StringRef Format; + + SmallVector Arguments; + + public: + LogBuilder(Consumer &c, StringRef Format) + : consumer(c), Format(Format) {} + + LogBuilder &operator<<(Value *V) { + Arguments.push_back(V); + return *this; + } + + ~LogBuilder(); + + StringRef getFormat() const; + unsigned getNumArguments() const; + Value *getArgument(unsigned I) const; + }; + + /// A temporary-object class for building up diff messages. + class DiffLogBuilder { + typedef std::pair DiffRecord; + SmallVector Diff; + + Consumer &consumer; + + public: + DiffLogBuilder(Consumer &c) : consumer(c) {} + ~DiffLogBuilder(); + + void addMatch(Instruction *L, Instruction *R); + // HACK: VS 2010 has a bug in the stdlib that requires this. + void addLeft(Instruction *L); + void addRight(Instruction *R); + + unsigned getNumLines() const; + DiffChange getLineKind(unsigned I) const; + Instruction *getLeft(unsigned I) const; + Instruction *getRight(unsigned I) const; + }; + +} + +#endif Modified: llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp?rev=127627&r1=127626&r2=127627&view=diff ============================================================================== --- llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp (original) +++ llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp Mon Mar 14 17:22:46 2011 @@ -506,30 +506,30 @@ for (unsigned I = 0; I != NL+1; ++I) { Cur[I].Cost = I * LeftCost; for (unsigned J = 0; J != I; ++J) - Cur[I].Path.push_back(DifferenceEngine::DC_left); + Cur[I].Path.push_back(DC_left); } for (BasicBlock::iterator RI = RStart; RI != RE; ++RI) { // Initialize the first row. Next[0] = Cur[0]; Next[0].Cost += RightCost; - Next[0].Path.push_back(DifferenceEngine::DC_right); + Next[0].Path.push_back(DC_right); unsigned Index = 1; for (BasicBlock::iterator LI = LStart; LI != LE; ++LI, ++Index) { if (matchForBlockDiff(&*LI, &*RI)) { Next[Index] = Cur[Index-1]; Next[Index].Cost += MatchCost; - Next[Index].Path.push_back(DifferenceEngine::DC_match); + Next[Index].Path.push_back(DC_match); TentativeValues.insert(std::make_pair(&*LI, &*RI)); } else if (Next[Index-1].Cost <= Cur[Index].Cost) { Next[Index] = Next[Index-1]; Next[Index].Cost += LeftCost; - Next[Index].Path.push_back(DifferenceEngine::DC_left); + Next[Index].Path.push_back(DC_left); } else { Next[Index] = Cur[Index]; Next[Index].Cost += RightCost; - Next[Index].Path.push_back(DifferenceEngine::DC_right); + Next[Index].Path.push_back(DC_right); } } @@ -543,23 +543,23 @@ SmallVectorImpl &Path = Cur[NL].Path; BasicBlock::iterator LI = LStart, RI = RStart; - DifferenceEngine::DiffLogBuilder Diff(Engine); + DiffLogBuilder Diff(Engine.getConsumer()); // Drop trailing matches. - while (Path.back() == DifferenceEngine::DC_match) + while (Path.back() == DC_match) Path.pop_back(); // Skip leading matches. SmallVectorImpl::iterator PI = Path.begin(), PE = Path.end(); - while (PI != PE && *PI == DifferenceEngine::DC_match) { + while (PI != PE && *PI == DC_match) { unify(&*LI, &*RI); ++PI, ++LI, ++RI; } for (; PI != PE; ++PI) { - switch (static_cast(*PI)) { - case DifferenceEngine::DC_match: + switch (static_cast(*PI)) { + case DC_match: assert(LI != LE && RI != RE); { Instruction *L = &*LI, *R = &*RI; @@ -569,13 +569,13 @@ ++LI; ++RI; break; - case DifferenceEngine::DC_left: + case DC_left: assert(LI != LE); Diff.addLeft(&*LI); ++LI; break; - case DifferenceEngine::DC_right: + case DC_right: assert(RI != RE); Diff.addRight(&*RI); ++RI; Modified: llvm/trunk/tools/llvm-diff/DifferenceEngine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DifferenceEngine.h?rev=127627&r1=127626&r2=127627&view=diff ============================================================================== --- llvm/trunk/tools/llvm-diff/DifferenceEngine.h (original) +++ llvm/trunk/tools/llvm-diff/DifferenceEngine.h Mon Mar 14 17:22:46 2011 @@ -17,6 +17,8 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "DiffLog.h" +#include "DiffConsumer.h" #include @@ -32,95 +34,6 @@ /// A class for performing structural comparisons of LLVM assembly. class DifferenceEngine { public: - /// A temporary-object class for building up log messages. - class LogBuilder { - DifferenceEngine &Engine; - - /// The use of a stored StringRef here is okay because - /// LogBuilder should be used only as a temporary, and as a - /// temporary it will be destructed before whatever temporary - /// might be initializing this format. - StringRef Format; - - SmallVector Arguments; - - public: - LogBuilder(DifferenceEngine &Engine, StringRef Format) - : Engine(Engine), Format(Format) {} - - LogBuilder &operator<<(Value *V) { - Arguments.push_back(V); - return *this; - } - - ~LogBuilder() { - Engine.consumer.logf(*this); - } - - StringRef getFormat() const { return Format; } - - unsigned getNumArguments() const { return Arguments.size(); } - Value *getArgument(unsigned I) const { return Arguments[I]; } - }; - - enum DiffChange { DC_match, DC_left, DC_right }; - - /// A temporary-object class for building up diff messages. - class DiffLogBuilder { - typedef std::pair DiffRecord; - SmallVector Diff; - - DifferenceEngine &Engine; - - public: - DiffLogBuilder(DifferenceEngine &Engine) : Engine(Engine) {} - ~DiffLogBuilder() { Engine.consumer.logd(*this); } - - void addMatch(Instruction *L, Instruction *R) { - Diff.push_back(DiffRecord(L, R)); - } - void addLeft(Instruction *L) { - // HACK: VS 2010 has a bug in the stdlib that requires this. - Diff.push_back(DiffRecord(L, DiffRecord::second_type(0))); - } - void addRight(Instruction *R) { - // HACK: VS 2010 has a bug in the stdlib that requires this. - Diff.push_back(DiffRecord(DiffRecord::first_type(0), R)); - } - - unsigned getNumLines() const { return Diff.size(); } - DiffChange getLineKind(unsigned I) const { - return (Diff[I].first ? (Diff[I].second ? DC_match : DC_left) - : DC_right); - } - Instruction *getLeft(unsigned I) const { return Diff[I].first; } - Instruction *getRight(unsigned I) const { return Diff[I].second; } - }; - - /// The interface for consumers of difference data. - struct Consumer { - /// Record that a local context has been entered. Left and - /// Right are IR "containers" of some sort which are being - /// considered for structural equivalence: global variables, - /// functions, blocks, instructions, etc. - virtual void enterContext(Value *Left, Value *Right) = 0; - - /// Record that a local context has been exited. - virtual void exitContext() = 0; - - /// Record a difference within the current context. - virtual void log(StringRef Text) = 0; - - /// Record a formatted difference within the current context. - virtual void logf(const LogBuilder &Log) = 0; - - /// Record a line-by-line instruction diff. - virtual void logd(const DiffLogBuilder &Log) = 0; - - protected: - virtual ~Consumer() {} - }; - /// A RAII object for recording the current context. struct Context { Context(DifferenceEngine &Engine, Value *L, Value *R) : Engine(Engine) { @@ -149,14 +62,13 @@ void diff(Module *L, Module *R); void diff(Function *L, Function *R); - void log(StringRef text) { consumer.log(text); } - LogBuilder logf(StringRef text) { - return LogBuilder(*this, text); + return LogBuilder(consumer, text); } + Consumer& getConsumer() const { return consumer; } /// Installs an oracle to decide whether two global values are /// equivalent as operands. Without an oracle, global values are Modified: llvm/trunk/tools/llvm-diff/llvm-diff.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/llvm-diff.cpp?rev=127627&r1=127626&r2=127627&view=diff ============================================================================== --- llvm/trunk/tools/llvm-diff/llvm-diff.cpp (original) +++ llvm/trunk/tools/llvm-diff/llvm-diff.cpp Mon Mar 14 17:22:46 2011 @@ -11,9 +11,9 @@ // //===----------------------------------------------------------------------===// +#include "DiffLog.h" #include "DifferenceEngine.h" -#include "llvm/Instructions.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/Type.h" @@ -21,7 +21,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/IRReader.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -43,221 +42,6 @@ return M; } -namespace { - struct DiffContext { - DiffContext(Value *L, Value *R) - : L(L), R(R), Differences(false), IsFunction(isa(L)) {} - Value *L; - Value *R; - bool Differences; - bool IsFunction; - DenseMap LNumbering; - DenseMap RNumbering; - }; -} - -static void ComputeNumbering(Function *F, DenseMap &Numbering){ - unsigned IN = 0; - - // Arguments get the first numbers. - for (Function::arg_iterator - AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI) - if (!AI->hasName()) - Numbering[&*AI] = IN++; - - // Walk the basic blocks in order. - for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) { - if (!FI->hasName()) - Numbering[&*FI] = IN++; - - // Walk the instructions in order. - for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) - // void instructions don't get numbers. - if (!BI->hasName() && !BI->getType()->isVoidTy()) - Numbering[&*BI] = IN++; - } - - assert(!Numbering.empty() && "asked for numbering but numbering was no-op"); -} - -namespace { -class DiffConsumer : public DifferenceEngine::Consumer { -private: - raw_ostream &out; - Module *LModule; - Module *RModule; - SmallVector contexts; - bool Differences; - unsigned Indent; - - void printValue(Value *V, bool isL) { - if (V->hasName()) { - out << (isa(V) ? '@' : '%') << V->getName(); - return; - } - if (V->getType()->isVoidTy()) { - if (isa(V)) { - out << "store to "; - printValue(cast(V)->getPointerOperand(), isL); - } else if (isa(V)) { - out << "call to "; - printValue(cast(V)->getCalledValue(), isL); - } else if (isa(V)) { - out << "invoke to "; - printValue(cast(V)->getCalledValue(), isL); - } else { - out << *V; - } - return; - } - - unsigned N = contexts.size(); - while (N > 0) { - --N; - DiffContext &ctxt = contexts[N]; - if (!ctxt.IsFunction) continue; - if (isL) { - if (ctxt.LNumbering.empty()) - ComputeNumbering(cast(ctxt.L), ctxt.LNumbering); - out << '%' << ctxt.LNumbering[V]; - return; - } else { - if (ctxt.RNumbering.empty()) - ComputeNumbering(cast(ctxt.R), ctxt.RNumbering); - out << '%' << ctxt.RNumbering[V]; - return; - } - } - - out << ""; - } - - void header() { - if (contexts.empty()) return; - for (SmallVectorImpl::iterator - I = contexts.begin(), E = contexts.end(); I != E; ++I) { - if (I->Differences) continue; - if (isa(I->L)) { - // Extra newline between functions. - if (Differences) out << "\n"; - - Function *L = cast(I->L); - Function *R = cast(I->R); - if (L->getName() != R->getName()) - out << "in function " << L->getName() - << " / " << R->getName() << ":\n"; - else - out << "in function " << L->getName() << ":\n"; - } else if (isa(I->L)) { - BasicBlock *L = cast(I->L); - BasicBlock *R = cast(I->R); - if (L->hasName() && R->hasName() && L->getName() == R->getName()) - out << " in block %" << L->getName() << ":\n"; - else { - out << " in block "; - printValue(L, true); - out << " / "; - printValue(R, false); - out << ":\n"; - } - } else if (isa(I->L)) { - out << " in instruction "; - printValue(I->L, true); - out << " / "; - printValue(I->R, false); - out << ":\n"; - } - - I->Differences = true; - } - } - - void indent() { - unsigned N = Indent; - while (N--) out << ' '; - } - -public: - DiffConsumer(Module *L, Module *R) - : out(errs()), LModule(L), RModule(R), Differences(false), Indent(0) {} - - bool hadDifferences() const { return Differences; } - - void enterContext(Value *L, Value *R) { - contexts.push_back(DiffContext(L, R)); - Indent += 2; - } - void exitContext() { - Differences |= contexts.back().Differences; - contexts.pop_back(); - Indent -= 2; - } - - void log(StringRef text) { - header(); - indent(); - out << text << '\n'; - } - - void logf(const DifferenceEngine::LogBuilder &Log) { - header(); - indent(); - - unsigned arg = 0; - - StringRef format = Log.getFormat(); - while (true) { - size_t percent = format.find('%'); - if (percent == StringRef::npos) { - out << format; - break; - } - assert(format[percent] == '%'); - - if (percent > 0) out << format.substr(0, percent); - - switch (format[percent+1]) { - case '%': out << '%'; break; - case 'l': printValue(Log.getArgument(arg++), true); break; - case 'r': printValue(Log.getArgument(arg++), false); break; - default: llvm_unreachable("unknown format character"); - } - - format = format.substr(percent+2); - } - - out << '\n'; - } - - void logd(const DifferenceEngine::DiffLogBuilder &Log) { - header(); - - for (unsigned I = 0, E = Log.getNumLines(); I != E; ++I) { - indent(); - switch (Log.getLineKind(I)) { - case DifferenceEngine::DC_match: - out << " "; - Log.getLeft(I)->dump(); - //printValue(Log.getLeft(I), true); - break; - case DifferenceEngine::DC_left: - out << "< "; - Log.getLeft(I)->dump(); - //printValue(Log.getLeft(I), true); - break; - case DifferenceEngine::DC_right: - out << "> "; - Log.getRight(I)->dump(); - //printValue(Log.getRight(I), false); - break; - } - //out << "\n"; - } - } - -}; -} // end anonymous namespace - static void diffGlobal(DifferenceEngine &Engine, Module *L, Module *R, StringRef Name) { // Drop leading sigils from the global name. From atrick at apple.com Mon Mar 14 17:35:42 2011 From: atrick at apple.com (Andrew Trick) Date: Mon, 14 Mar 2011 15:35:42 -0700 Subject: [llvm-commits] [llvm] r127591 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp In-Reply-To: References: <20110314172802.877602A6C12C@llvm.org> Message-ID: On Mar 14, 2011, at 2:09 PM, Eli Friedman wrote: > On Mon, Mar 14, 2011 at 1:28 PM, Andrew Trick wrote: >> Author: atrick >> Date: Mon Mar 14 12:28:02 2011 >> New Revision: 127591 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127591&view=rev >> Log: >> HowFarToZero can compute a trip count as long as the recurrence has no-self-wrap. > > Have you read http://llvm.org/bugs/show_bug.cgi?id=8942#c3 ? That > goes a bit into why depending on no-self-wrap requires some > infrastructure changes. > > -Eli If I understand your comments in PR8942, you have the same concern that I expressed in the FIXME with this commit. I cannot take credit for the comment above the FIXME, "If the recurrence is known not to wraparound". I copied that text from getMinusSCEVForExitTest() in preparation for removing that function. The problem you brought up needs to be addressed, and I don't have the answer yet. In the meantime, I'm working to clarify the underlying logic. That will make issues like this more obvious and help me fix existing bugs. As to the safety of this change, there are two things to consider: (1) NUW was already being used as an alias for no-self-wrap in some cases. I'm only making the logic explicit and avoiding the use of NUW unless it stricly applies. (2) The theoretical issue that you raise is still a problem for NUW recurences with non-unit stride, which could "miss" the exit test before "unnatural loop termination". I believe the resulting BECount satisfies the intention of ComputeBackedgeTakenCountFromExit: /// Compute the number of times the backedge of the specified loop will execute /// *if it exits via the specified block*. But I also realize other clients of SCEV may have a different interpretation. I could really use help identifying specific situations that could fail. Without that, I don't think I'll be able to come up with an infrastructure change that makes the analysis more robust. Thanks for reviewing! -Andy >> Modified: >> llvm/trunk/lib/Analysis/ScalarEvolution.cpp >> >> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127591&r1=127590&r2=127591&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) >> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 14 12:28:02 2011 >> @@ -4978,15 +4978,6 @@ >> const SCEV *Start = getSCEVAtScope(AddRec->getStart(), L->getParentLoop()); >> const SCEV *Step = getSCEVAtScope(AddRec->getOperand(1), L->getParentLoop()); >> >> - // If the AddRec is NUW, then (in an unsigned sense) it cannot be counting up >> - // to wrap to 0, it must be counting down to equal 0. Also, while counting >> - // down, it cannot "miss" 0 (which would cause it to wrap), regardless of what >> - // the stride is. As such, NUW addrec's will always become zero in >> - // "start / -stride" steps, and we know that the division is exact. >> - if (AddRec->getNoWrapFlags(SCEV::FlagNUW)) >> - // FIXME: We really want an "isexact" bit for udiv. >> - return getUDivExpr(Start, getNegativeSCEV(Step)); >> - >> // For now we handle only constant steps. >> // >> // TODO: Handle a nonconstant Step given AddRec. If the >> @@ -5002,15 +4993,28 @@ >> // For negative steps (counting down to zero): >> // N = Start/-Step >> // First compute the unsigned distance from zero in the direction of Step. >> - const SCEV *Distance = StepC->getValue()->getValue().isNonNegative() ? >> - getNegativeSCEV(Start) : Start; >> + bool CountDown = StepC->getValue()->getValue().isNegative(); >> + const SCEV *Distance = CountDown ? Start : getNegativeSCEV(Start); >> >> // Handle unitary steps, which cannot wraparound. >> - if (StepC->getValue()->equalsInt(1)) // 1*N = -Start (mod 2^BW), so: >> - return Distance; // N = -Start (as unsigned) >> - >> - if (StepC->getValue()->isAllOnesValue()) // -1*N = -Start (mod 2^BW), so: >> - return Distance; // N = Start (as unsigned) >> + // 1*N = -Start; -1*N = Start (mod 2^BW), so: >> + // N = Distance (as unsigned) >> + if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) >> + return Distance; >> + >> + // If the recurrence is known not to wraparound, unsigned divide computes the >> + // back edge count. We know that the value will either become zero (and thus >> + // the loop terminates), that the loop will terminate through some other exit >> + // condition first, or that the loop has undefined behavior. This means >> + // we can't "miss" the exit value, even with nonunit stride. >> + // >> + // FIXME: Prove that loops always exhibits *acceptable* undefined >> + // behavior. Loops must exhibit defined behavior until a wrapped value is >> + // actually used. So the trip count computed by udiv could be smaller than the >> + // number of well-defined iterations. >> + if (AddRec->getNoWrapFlags(SCEV::FlagNW)) >> + // FIXME: We really want an "isexact" bit for udiv. >> + return getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step); >> >> // Then, try to solve the above equation provided that Start is constant. >> if (const SCEVConstant *StartC = dyn_cast(Start)) >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> From rjmccall at apple.com Mon Mar 14 17:41:50 2011 From: rjmccall at apple.com (John McCall) Date: Mon, 14 Mar 2011 22:41:50 -0000 Subject: [llvm-commits] [llvm] r127629 - in /llvm/trunk/include/llvm/Support: Compiler.h ErrorHandling.h Message-ID: <20110314224150.5ECAD2A6C12C@llvm.org> Author: rjmccall Date: Mon Mar 14 17:41:50 2011 New Revision: 127629 URL: http://llvm.org/viewvc/llvm-project?rev=127629&view=rev Log: Version N of the llvm_unreachable patch: VC++ doesn't recognize that abort() doesn't return, so just go back to using the old runtime function instead of trying to use abort() when __builtin_unreachable (or an equivalent) isn't supported. Modified: llvm/trunk/include/llvm/Support/Compiler.h llvm/trunk/include/llvm/Support/ErrorHandling.h Modified: llvm/trunk/include/llvm/Support/Compiler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Compiler.h?rev=127629&r1=127628&r2=127629&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/Compiler.h (original) +++ llvm/trunk/include/llvm/Support/Compiler.h Mon Mar 14 17:41:50 2011 @@ -128,12 +128,10 @@ // LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands // to an expression which states that it is undefined behavior for the -// compiler to reach this point. +// compiler to reach this point. Otherwise is not defined. #if defined(__clang__) || (__GNUC__ > 4) \ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() -#else -# define LLVM_BUILTIN_UNREACHABLE abort() #endif #endif Modified: llvm/trunk/include/llvm/Support/ErrorHandling.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ErrorHandling.h?rev=127629&r1=127628&r2=127629&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/ErrorHandling.h (original) +++ llvm/trunk/include/llvm/Support/ErrorHandling.h Mon Mar 14 17:41:50 2011 @@ -86,18 +86,21 @@ unsigned line=0); } -/// Prints the message and location info to stderr in !NDEBUG builds. -/// This is intended to be used for "impossible" situations that imply -/// a bug in the compiler. +/// Marks that the current location is not supposed to be reachable. +/// In !NDEBUG builds, prints the message and location info to stderr. +/// In NDEBUG builds, becomes an optimizer hint that the current location +/// is not supposed to be reachable. On compilers that don't support +/// such hints, prints a reduced message instead. /// -/// In NDEBUG mode it only prints "UNREACHABLE executed". -/// Use this instead of assert(0), so that the compiler knows this path -/// is not reachable even for NDEBUG builds. +/// Use this instead of assert(0). It conveys intent more clearly and +/// allows compilers to omit some unnecessary code. #ifndef NDEBUG #define llvm_unreachable(msg) \ ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__) -#else +#elif defined(LLVM_BUILTIN_UNREACHABLE) #define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE +#else +#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal() #endif #endif From isanbard at gmail.com Mon Mar 14 18:02:38 2011 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 14 Mar 2011 23:02:38 -0000 Subject: [llvm-commits] [llvm] r127630 - in /llvm/trunk: lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h test/CodeGen/ARM/vext.ll Message-ID: <20110314230238.AC3CF2A6C12C@llvm.org> Author: void Date: Mon Mar 14 18:02:38 2011 New Revision: 127630 URL: http://llvm.org/viewvc/llvm-project?rev=127630&view=rev Log: Generate a VTBL instruction instead of a series of loads and stores when we can. As Nate pointed out, VTBL isn't super performant, but it *has* to be better than this: _shuf: @ BB#0: @ %entry push {r4, r7, lr} add r7, sp, #4 sub sp, #12 mov r4, sp bic r4, r4, #7 mov sp, r4 mov r2, sp vmov d16, r0, r1 orr r0, r2, #6 orr r3, r2, #7 vst1.8 {d16[0]}, [r3] vst1.8 {d16[5]}, [r0] subs r4, r7, #4 orr r0, r2, #5 vst1.8 {d16[4]}, [r0] orr r0, r2, #4 vst1.8 {d16[4]}, [r0] orr r0, r2, #3 vst1.8 {d16[0]}, [r0] orr r0, r2, #2 vst1.8 {d16[2]}, [r0] orr r0, r2, #1 vst1.8 {d16[1]}, [r0] vst1.8 {d16[3]}, [r2] vldr.64 d16, [sp] vmov r0, r1, d16 mov sp, r4 pop {r4, r7, pc} The "illegal" testcase in vext.ll is no longer illegal. Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/test/CodeGen/ARM/vext.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=127630&r1=127629&r2=127630&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon Mar 14 18:02:38 2011 @@ -2842,6 +2842,35 @@ break; } + case ARMISD::VTBL1: { + DebugLoc dl = N->getDebugLoc(); + EVT VT = N->getValueType(0); + SmallVector Ops; + + Ops.push_back(N->getOperand(0)); + Ops.push_back(N->getOperand(1)); + Ops.push_back(getAL(CurDAG)); // Predicate + Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // Predicate Register + return CurDAG->getMachineNode(ARM::VTBL1, dl, VT, Ops.data(), Ops.size()); + } + case ARMISD::VTBL2: { + DebugLoc dl = N->getDebugLoc(); + EVT VT = N->getValueType(0); + + // Form a REG_SEQUENCE to force register allocation. + SDValue V0 = N->getOperand(0); + SDValue V1 = N->getOperand(1); + SDValue RegSeq = SDValue(PairDRegs(MVT::v16i8, V0, V1), 0); + + SmallVector Ops; + Ops.push_back(RegSeq); + Ops.push_back(N->getOperand(2)); + Ops.push_back(getAL(CurDAG)); // Predicate + Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // Predicate Register + return CurDAG->getMachineNode(ARM::VTBL2Pseudo, dl, VT, + Ops.data(), Ops.size()); + } + case ISD::CONCAT_VECTORS: return SelectConcatVector(N); } Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127630&r1=127629&r2=127630&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Mar 14 18:02:38 2011 @@ -852,6 +852,10 @@ case ARMISD::VZIP: return "ARMISD::VZIP"; case ARMISD::VUZP: return "ARMISD::VUZP"; case ARMISD::VTRN: return "ARMISD::VTRN"; + case ARMISD::VTBL1: return "ARMISD::VTBL1"; + case ARMISD::VTBL2: return "ARMISD::VTBL2"; + case ARMISD::VTBL3: return "ARMISD::VTBL3"; + case ARMISD::VTBL4: return "ARMISD::VTBL4"; case ARMISD::VMULLs: return "ARMISD::VMULLs"; case ARMISD::VMULLu: return "ARMISD::VMULLu"; case ARMISD::BUILD_VECTOR: return "ARMISD::BUILD_VECTOR"; @@ -4055,6 +4059,29 @@ } } +static SDValue LowerVECTOR_SHUFFLEv8i8(SDValue Op, + SmallVectorImpl &ShuffleMask, + SelectionDAG &DAG) { + // Check to see if we can use the VTBL instruction. + SDValue V1 = Op.getOperand(0); + SDValue V2 = Op.getOperand(1); + DebugLoc DL = Op.getDebugLoc(); + + SmallVector VTBLMask; + for (SmallVectorImpl::iterator + I = ShuffleMask.begin(), E = ShuffleMask.end(); I != E; ++I) + VTBLMask.push_back(DAG.getConstant(*I, MVT::i32)); + + if (V2.getNode()->getOpcode() == ISD::UNDEF) + return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1, + DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, + &VTBLMask[0], 8)); + else + return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2, + DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, + &VTBLMask[0], 8)); +} + static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { SDValue V1 = Op.getOperand(0); SDValue V2 = Op.getOperand(1); @@ -4172,6 +4199,12 @@ return DAG.getNode(ISD::BITCAST, dl, VT, Val); } + if (VT == MVT::v8i8) { + SDValue NewOp = LowerVECTOR_SHUFFLEv8i8(Op, ShuffleMask, DAG); + if (NewOp.getNode()) + return NewOp; + } + return SDValue(); } @@ -4534,7 +4567,7 @@ case ISD::GlobalAddress: return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) : LowerGlobalAddressELF(Op, DAG); - case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); + case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::SELECT: return LowerSELECT(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=127630&r1=127629&r2=127630&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Mon Mar 14 18:02:38 2011 @@ -153,6 +153,10 @@ VZIP, // zip (interleave) VUZP, // unzip (deinterleave) VTRN, // transpose + VTBL1, // 1-register shuffle with mask + VTBL2, // 2-register shuffle with mask + VTBL3, // 3-register shuffle with mask + VTBL4, // 4-register shuffle with mask // Vector multiply long: VMULLs, // ...signed Modified: llvm/trunk/test/CodeGen/ARM/vext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vext.ll?rev=127630&r1=127629&r2=127630&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vext.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vext.ll Mon Mar 14 18:02:38 2011 @@ -121,15 +121,3 @@ %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <4 x i32> ret <4 x i16> %tmp2 } - -; The actual shuffle code only handles some cases, make sure we check -; this rather than blindly emitting a VECTOR_SHUFFLE (infinite -; lowering loop can result otherwise). -define <8 x i8> @test_illegal(<16 x i8>* %A, <16 x i8>* %B) nounwind { -;CHECK: test_illegal: -;CHECK: vst1.8 - %tmp1 = load <16 x i8>* %A - %tmp2 = load <16 x i8>* %B - %tmp3 = shufflevector <16 x i8> %tmp1, <16 x i8> %tmp2, <8 x i32> - ret <8 x i8> %tmp3 -} From pichet2000 at gmail.com Mon Mar 14 18:07:21 2011 From: pichet2000 at gmail.com (Francois Pichet) Date: Mon, 14 Mar 2011 23:07:21 -0000 Subject: [llvm-commits] [llvm] r127632 - /llvm/trunk/tools/llvm-diff/DiffConsumer.h Message-ID: <20110314230721.4D1E22A6C12C@llvm.org> Author: fpichet Date: Mon Mar 14 18:07:21 2011 New Revision: 127632 URL: http://llvm.org/viewvc/llvm-project?rev=127632&view=rev Log: Make llvm::Consumer a class (to remove a MSVC warning since Consumer is later forward declared as a struct) Modified: llvm/trunk/tools/llvm-diff/DiffConsumer.h Modified: llvm/trunk/tools/llvm-diff/DiffConsumer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffConsumer.h?rev=127632&r1=127631&r2=127632&view=diff ============================================================================== --- llvm/trunk/tools/llvm-diff/DiffConsumer.h (original) +++ llvm/trunk/tools/llvm-diff/DiffConsumer.h Mon Mar 14 18:07:21 2011 @@ -28,7 +28,8 @@ class Function; /// The interface for consumers of difference data. - struct Consumer { + class Consumer { + public: /// Record that a local context has been entered. Left and /// Right are IR "containers" of some sort which are being /// considered for structural equivalence: global variables, From eli.friedman at gmail.com Mon Mar 14 18:32:36 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 14 Mar 2011 19:32:36 -0400 Subject: [llvm-commits] [llvm] r127591 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp In-Reply-To: References: <20110314172802.877602A6C12C@llvm.org> Message-ID: On Mon, Mar 14, 2011 at 6:35 PM, Andrew Trick wrote: > On Mar 14, 2011, at 2:09 PM, Eli Friedman wrote: >> On Mon, Mar 14, 2011 at 1:28 PM, Andrew Trick wrote: >>> Author: atrick >>> Date: Mon Mar 14 12:28:02 2011 >>> New Revision: 127591 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=127591&view=rev >>> Log: >>> HowFarToZero can compute a trip count as long as the recurrence has no-self-wrap. >> >> Have you read http://llvm.org/bugs/show_bug.cgi?id=8942#c3 ? ?That >> goes a bit into why depending on no-self-wrap requires some >> infrastructure changes. >> >> -Eli > > If I understand your comments in PR8942, you have the same concern > that I expressed in the FIXME with this commit. I cannot take credit for the > comment above the FIXME, "If the recurrence is known not to wraparound". > I copied that text from getMinusSCEVForExitTest() in preparation for > removing that function. > > The problem you brought up needs to be addressed, and I don't have the > answer yet. In the meantime, I'm working to clarify the underlying > logic. That will make issues like this more obvious and help me fix > existing bugs. > > As to the safety of this change, there are two things to consider: > > (1) NUW was already being used as an alias for no-self-wrap in some > cases. I'm only making the logic explicit and avoiding the use of NUW > unless it stricly applies. > > (2) The theoretical issue that you raise is still a problem for NUW > recurences with non-unit stride, which could "miss" the exit test > before "unnatural loop termination". > > I believe the resulting BECount satisfies the intention of > ComputeBackedgeTakenCountFromExit: > /// Compute the number of times the backedge of the specified loop will execute > /// *if it exits via the specified block*. > > But I also realize other clients of SCEV may have a different > interpretation. I could really use help identifying specific > situations that could fail. Without that, I don't think I'll be able > to come up with an infrastructure change that makes the analysis more > robust. Hmm... getBackedgeTakenCount and getMaxBackedgeTakenCount have surprisingly few users. One user of getBackedgeTakenCount is IndVars, which will try to rewrite the exit condition in terms of the backedge taken count. It assumes that the count is both the exit count and the maximum loop count of the loop. On the other hand, LoopIdiomRecognize doesn't really care what the max iteration count is (I'm not completely sure it's safe for other reasons, but that isn't really related). I'm not sure I really follow what LSR is doing with the backedge taken count. LoopDeletion uses the MaxBackedgeTakenCount to make sure a loop isn't infinite. And I think that actually exhaustively covers all the uses of the backedge counts. So basically, if we can't actually do an indvars transform, very little actually looks at the backedge count directly. Some places that use LoopInfo::getTripCount() and friends could probably be changed to be more aggressive, though. -Eli From evan.cheng at apple.com Mon Mar 14 18:37:10 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 14 Mar 2011 16:37:10 -0700 Subject: [llvm-commits] [llvm] r127598 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/ARM/shifter_operand.ll test/CodeGen/ARM/undef-sext.ll In-Reply-To: References: <20110314181555.6A48F2A6C12D@llvm.org> Message-ID: On Mar 14, 2011, at 11:25 AM, Frits van Bommel wrote: > On Mon, Mar 14, 2011 at 7:15 PM, Evan Cheng wrote: >> Log: >> Minor optimization. sign-ext/anyext of undef is still undef. > > I can believe this for anyext, but a sext'ed undef should probably > still have equal high bits, which is not a requirement for the bigger > undef you're replacing it with. I don't see the problem, the high-bit of an undef is an unknown value. zero-extend is definitely not safe, but sign-extend should be fine. Evan From echristo at apple.com Mon Mar 14 19:25:41 2011 From: echristo at apple.com (Eric Christopher) Date: Tue, 15 Mar 2011 00:25:41 -0000 Subject: [llvm-commits] [llvm] r127636 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/strcpy_chk-64.ll Message-ID: <20110315002541.ABF452A6C12C@llvm.org> Author: echristo Date: Mon Mar 14 19:25:41 2011 New Revision: 127636 URL: http://llvm.org/viewvc/llvm-project?rev=127636&view=rev Log: If we don't know how long a string is we can't fold an _chk version to the normal version. Fixes rdar://9123638 Added: llvm/trunk/test/Transforms/InstCombine/strcpy_chk-64.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=127636&r1=127635&r2=127636&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Mar 14 19:25:41 2011 @@ -759,9 +759,13 @@ dyn_cast(CI->getArgOperand(SizeCIOp))) { if (SizeCI->isAllOnesValue()) return true; - if (isString) - return SizeCI->getZExtValue() >= - GetStringLength(CI->getArgOperand(SizeArgOp)); + if (isString) { + uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp)); + // If the length is 0 we don't know how long it is and so we can't + // remove the check. + if (Len == 0) return false; + return SizeCI->getZExtValue() >= Len; + } if (ConstantInt *Arg = dyn_cast( CI->getArgOperand(SizeArgOp))) return SizeCI->getZExtValue() >= Arg->getZExtValue(); Added: llvm/trunk/test/Transforms/InstCombine/strcpy_chk-64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strcpy_chk-64.ll?rev=127636&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/strcpy_chk-64.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/strcpy_chk-64.ll Mon Mar 14 19:25:41 2011 @@ -0,0 +1,18 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin10.0.0" + +define void @func(i8* %i) nounwind ssp { +; CHECK: @func +; CHECK: @__strcpy_chk(i8* %arraydecay, i8* %i, i64 32) +entry: + %s = alloca [32 x i8], align 16 + %arraydecay = getelementptr inbounds [32 x i8]* %s, i32 0, i32 0 + %call = call i8* @__strcpy_chk(i8* %arraydecay, i8* %i, i64 32) + call void @func2(i8* %arraydecay) + ret void +} + +declare i8* @__strcpy_chk(i8*, i8*, i64) nounwind + +declare void @func2(i8*) From grosbach at apple.com Mon Mar 14 19:30:40 2011 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 15 Mar 2011 00:30:40 -0000 Subject: [llvm-commits] [llvm] r127637 - in /llvm/trunk: lib/Target/ARM/ARMAsmPrinter.cpp lib/Target/ARM/ARMFrameLowering.cpp lib/Target/ARM/ARMInstrInfo.td test/CodeGen/ARM/call-tc.ll Message-ID: <20110315003040.746E92A6C12C@llvm.org> Author: grosbach Date: Mon Mar 14 19:30:40 2011 New Revision: 127637 URL: http://llvm.org/viewvc/llvm-project?rev=127637&view=rev Log: Clean up ARM tail calls a bit. They're pseudo-instructions for normal branches. Also more cleanly separate the ARM vs. Thumb functionality. Previously, the encoding would be incorrect for some Thumb instructions (the indirect calls). Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/test/CodeGen/ARM/call-tc.ll Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=127637&r1=127636&r2=127637&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon Mar 14 19:30:40 2011 @@ -1707,6 +1707,49 @@ } return; } + // Tail jump branches are really just branch instructions with additional + // code-gen attributes. Convert them to the cannonical form here. + case ARM::TAILJMPd: + case ARM::TAILJMPdND: { + MCInst TmpInst, TmpInst2; + // Lower the instruction as-is to get the operands properly converted. + LowerARMMachineInstrToMCInst(MI, TmpInst2, *this); + TmpInst.setOpcode(ARM::Bcc); + TmpInst.addOperand(TmpInst2.getOperand(0)); + // Add predicate operands. + TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + TmpInst.addOperand(MCOperand::CreateReg(0)); + OutStreamer.AddComment("TAILCALL"); + OutStreamer.EmitInstruction(TmpInst); + return; + } + case ARM::tTAILJMPd: + case ARM::tTAILJMPdND: { + MCInst TmpInst, TmpInst2; + LowerARMMachineInstrToMCInst(MI, TmpInst2, *this); + TmpInst.setOpcode(ARM::tB); + TmpInst.addOperand(TmpInst2.getOperand(0)); + OutStreamer.AddComment("TAILCALL"); + OutStreamer.EmitInstruction(TmpInst); + return; + } + case ARM::TAILJMPrND: + case ARM::tTAILJMPrND: + case ARM::TAILJMPr: + case ARM::tTAILJMPr: { + unsigned newOpc = (Opc == ARM::TAILJMPr || Opc == ARM::TAILJMPrND) + ? ARM::BX : ARM::tBX; + MCInst TmpInst; + TmpInst.setOpcode(newOpc); + TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); + // Predicate. + TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + TmpInst.addOperand(MCOperand::CreateReg(0)); + OutStreamer.AddComment("TAILCALL"); + OutStreamer.EmitInstruction(TmpInst); + return; + } + // These are the pseudos created to comply with stricter operand restrictions // on ARMv5. Lower them now to "normal" instructions, since all the // restrictions are already satisfied. Modified: llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp?rev=127637&r1=127636&r2=127637&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp Mon Mar 14 19:30:40 2011 @@ -400,8 +400,8 @@ // Jump to label or value in register. if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND) { unsigned TCOpcode = (RetOpcode == ARM::TCRETURNdi) - ? (STI.isThumb() ? ARM::TAILJMPdt : ARM::TAILJMPd) - : (STI.isThumb() ? ARM::TAILJMPdNDt : ARM::TAILJMPdND); + ? (STI.isThumb() ? ARM::tTAILJMPd : ARM::TAILJMPd) + : (STI.isThumb() ? ARM::tTAILJMPdND : ARM::TAILJMPdND); MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(TCOpcode)); if (JumpTarget.isGlobal()) MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), @@ -412,10 +412,12 @@ JumpTarget.getTargetFlags()); } } else if (RetOpcode == ARM::TCRETURNri) { - BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPr)). + BuildMI(MBB, MBBI, dl, + TII.get(STI.isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)). addReg(JumpTarget.getReg(), RegState::Kill); } else if (RetOpcode == ARM::TCRETURNriND) { - BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPrND)). + BuildMI(MBB, MBBI, dl, + TII.get(STI.isThumb() ? ARM::tTAILJMPrND : ARM::TAILJMPrND)). addReg(JumpTarget.getReg(), RegState::Kill); } Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=127637&r1=127636&r2=127637&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Mar 14 19:30:40 2011 @@ -1408,11 +1408,7 @@ // Tail calls. -// FIXME: These should probably be xformed into the non-TC versions of the -// instructions as part of MC lowering. -// FIXME: These seem to be used for both Thumb and ARM instruction selection. -// Thumb should have its own version since the instruction is actually -// different, even though the mnemonic is the same. +// FIXME: The Thumb versions of these should live in ARMInstrThumb.td let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { // Darwin versions. let Defs = [R0, R1, R2, R3, R9, R12, @@ -1426,21 +1422,21 @@ def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops), IIC_Br, []>, Requires<[IsDarwin]>; - def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), - IIC_Br, "b\t$dst @ TAILCALL", + def TAILJMPd : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops), + Size4Bytes, IIC_Br, []>, Requires<[IsARM, IsDarwin]>; - def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), - IIC_Br, "b.w\t$dst @ TAILCALL", + def tTAILJMPd: tPseudoInst<(outs), (ins brtarget:$dst, variable_ops), + Size4Bytes, IIC_Br, []>, Requires<[IsThumb, IsDarwin]>; - def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops), - BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL", - []>, Requires<[IsDarwin]> { - bits<4> dst; - let Inst{31-4} = 0b1110000100101111111111110001; - let Inst{3-0} = dst; - } + def TAILJMPr : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops), + Size4Bytes, IIC_Br, + []>, Requires<[IsARM, IsDarwin]>; + + def tTAILJMPr : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops), + Size4Bytes, IIC_Br, + []>, Requires<[IsThumb, IsDarwin]>; } // Non-Darwin versions (the difference is R9). @@ -1455,21 +1451,20 @@ def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops), IIC_Br, []>, Requires<[IsNotDarwin]>; - def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), - IIC_Br, "b\t$dst @ TAILCALL", + def TAILJMPdND : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops), + Size4Bytes, IIC_Br, []>, Requires<[IsARM, IsNotDarwin]>; - def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops), - IIC_Br, "b.w\t$dst @ TAILCALL", + def tTAILJMPdND : tPseudoInst<(outs), (ins brtarget:$dst, variable_ops), + Size4Bytes, IIC_Br, []>, Requires<[IsThumb, IsNotDarwin]>; - def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops), - BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL", - []>, Requires<[IsNotDarwin]> { - bits<4> dst; - let Inst{31-4} = 0b1110000100101111111111110001; - let Inst{3-0} = dst; - } + def TAILJMPrND : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops), + Size4Bytes, IIC_Br, + []>, Requires<[IsARM, IsNotDarwin]>; + def tTAILJMPrND : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops), + Size4Bytes, IIC_Br, + []>, Requires<[IsThumb, IsNotDarwin]>; } } Modified: llvm/trunk/test/CodeGen/ARM/call-tc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/call-tc.ll?rev=127637&r1=127636&r2=127637&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/call-tc.ll (original) +++ llvm/trunk/test/CodeGen/ARM/call-tc.ll Mon Mar 14 19:30:40 2011 @@ -74,7 +74,7 @@ ; CHECKT2: t7: ; CHECKT2: blxeq _foo ; CHECKT2-NEXT: pop.w -; CHECKT2-NEXT: b.w _foo +; CHECKT2-NEXT: b _foo br i1 undef, label %bb, label %bb1.lr.ph bb1.lr.ph: From clattner at apple.com Mon Mar 14 19:39:22 2011 From: clattner at apple.com (Chris Lattner) Date: Mon, 14 Mar 2011 17:39:22 -0700 Subject: [llvm-commits] [llvm] r127598 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/ARM/shifter_operand.ll test/CodeGen/ARM/undef-sext.ll In-Reply-To: References: <20110314181555.6A48F2A6C12D@llvm.org> Message-ID: On Mar 14, 2011, at 4:37 PM, Evan Cheng wrote: > > On Mar 14, 2011, at 11:25 AM, Frits van Bommel wrote: > >> On Mon, Mar 14, 2011 at 7:15 PM, Evan Cheng wrote: >>> Log: >>> Minor optimization. sign-ext/anyext of undef is still undef. >> >> I can believe this for anyext, but a sext'ed undef should probably >> still have equal high bits, which is not a requirement for the bigger >> undef you're replacing it with. > > I don't see the problem, the high-bit of an undef is an unknown value. zero-extend is definitely not safe, but sign-extend should be fine. Sign extend doesn't specify what the top bit is, but it does guarantee that the top bits are all the same. Instead of folding to undef, sext(undef) should fold to 0. This is what happens at the IR level: Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, const Type *DestTy) { if (isa(V)) { // zext(undef) = 0, because the top bits will be zero. // sext(undef) = 0, because the top bits will all be the same. // [us]itofp(undef) = 0, because the result value is bounded. if (opc == Instruction::ZExt || opc == Instruction::SExt || opc == Instruction::UIToFP || opc == Instruction::SIToFP) return Constant::getNullValue(DestTy); return UndefValue::get(DestTy); } -Chris From atrick at apple.com Mon Mar 14 19:37:00 2011 From: atrick at apple.com (Andrew Trick) Date: Tue, 15 Mar 2011 00:37:00 -0000 Subject: [llvm-commits] [llvm] r127638 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/nsw-offset.ll test/Analysis/ScalarEvolution/nsw.ll test/Analysis/ScalarEvolution/sext-iv-0.ll Message-ID: <20110315003700.911BC2A6C12E@llvm.org> Author: atrick Date: Mon Mar 14 19:37:00 2011 New Revision: 127638 URL: http://llvm.org/viewvc/llvm-project?rev=127638&view=rev Log: Propagate SCEV no-wrap flags whenever possible. This needs review. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/test/Analysis/ScalarEvolution/nsw-offset.ll llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll llvm/trunk/test/Analysis/ScalarEvolution/sext-iv-0.ll Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127638&r1=127637&r2=127638&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 14 19:37:00 2011 @@ -932,8 +932,7 @@ if (AR->getNoWrapFlags(SCEV::FlagNUW)) return getAddRecExpr(getZeroExtendExpr(Start, Ty), getZeroExtendExpr(Step, Ty), - // FIXME: Can use SCEV::FlagNUW - L, SCEV::FlagAnyWrap); + L, AR->getNoWrapFlags()); // Check whether the backedge-taken count is SCEVCouldNotCompute. // Note that this serves two purposes: It filters out loops that are @@ -963,13 +962,14 @@ getAddExpr(getZeroExtendExpr(Start, WideTy), getMulExpr(getZeroExtendExpr(CastedMaxBECount, WideTy), getZeroExtendExpr(Step, WideTy))); - if (getZeroExtendExpr(Add, WideTy) == OperandExtendedAdd) + if (getZeroExtendExpr(Add, WideTy) == OperandExtendedAdd) { + // Cache knowledge of AR NUW, which is propagated to this AddRec. + const_cast(AR)->setNoWrapFlags(SCEV::FlagNUW); // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), getZeroExtendExpr(Step, Ty), - // FIXME: can use FlagNUW - L, SCEV::FlagAnyWrap); - + L, AR->getNoWrapFlags()); + } // Similar to above, only this time treat the step value as signed. // This covers loops that count down. const SCEV *SMul = getMulExpr(CastedMaxBECount, Step); @@ -978,12 +978,15 @@ getAddExpr(getZeroExtendExpr(Start, WideTy), getMulExpr(getZeroExtendExpr(CastedMaxBECount, WideTy), getSignExtendExpr(Step, WideTy))); - if (getZeroExtendExpr(Add, WideTy) == OperandExtendedAdd) + if (getZeroExtendExpr(Add, WideTy) == OperandExtendedAdd) { + // Cache knowledge of AR NW, which is propagated to this AddRec. + // Negative step causes unsigned wrap, but it still can't self-wrap. + const_cast(AR)->setNoWrapFlags(SCEV::FlagNW); // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - // FIXME: can use FlagNW - L, SCEV::FlagAnyWrap); + L, AR->getNoWrapFlags()); + } } // If the backedge is guarded by a comparison with the pre-inc value @@ -996,25 +999,29 @@ if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT, AR, N) || (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_ULT, Start, N) && isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_ULT, - AR->getPostIncExpr(*this), N))) + AR->getPostIncExpr(*this), N))) { + // Cache knowledge of AR NUW, which is propagated to this AddRec. + const_cast(AR)->setNoWrapFlags(SCEV::FlagNUW); // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), getZeroExtendExpr(Step, Ty), - // FIXME: can use FlagNUW - L, SCEV::FlagAnyWrap); + L, AR->getNoWrapFlags()); + } } else if (isKnownNegative(Step)) { const SCEV *N = getConstant(APInt::getMaxValue(BitWidth) - getSignedRange(Step).getSignedMin()); if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT, AR, N) || (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_UGT, Start, N) && isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT, - AR->getPostIncExpr(*this), N))) - // Return the expression with the addrec on the outside. The - // negative step causes unsigned wrap, but it still can't self-wrap. + AR->getPostIncExpr(*this), N))) { + // Cache knowledge of AR NW, which is propagated to this AddRec. + // Negative step causes unsigned wrap, but it still can't self-wrap. + const_cast(AR)->setNoWrapFlags(SCEV::FlagNW); + // Return the expression with the addrec on the outside. return getAddRecExpr(getZeroExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - // FIXME: can use FlagNW - L, SCEV::FlagAnyWrap); + L, AR->getNoWrapFlags()); + } } } } @@ -1092,8 +1099,7 @@ if (AR->getNoWrapFlags(SCEV::FlagNSW)) return getAddRecExpr(getSignExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - // FIXME: can use SCEV::FlagNSW - L, SCEV::FlagAnyWrap); + L, SCEV::FlagNSW); // Check whether the backedge-taken count is SCEVCouldNotCompute. // Note that this serves two purposes: It filters out loops that are @@ -1123,13 +1129,14 @@ getAddExpr(getSignExtendExpr(Start, WideTy), getMulExpr(getZeroExtendExpr(CastedMaxBECount, WideTy), getSignExtendExpr(Step, WideTy))); - if (getSignExtendExpr(Add, WideTy) == OperandExtendedAdd) + if (getSignExtendExpr(Add, WideTy) == OperandExtendedAdd) { + // Cache knowledge of AR NSW, which is propagated to this AddRec. + const_cast(AR)->setNoWrapFlags(SCEV::FlagNSW); // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - // FIXME: can use SCEV::FlagNSW - L, SCEV::FlagAnyWrap); - + L, AR->getNoWrapFlags()); + } // Similar to above, only this time treat the step value as unsigned. // This covers loops that count up with an unsigned step. const SCEV *UMul = getMulExpr(CastedMaxBECount, Step); @@ -1138,12 +1145,14 @@ getAddExpr(getSignExtendExpr(Start, WideTy), getMulExpr(getZeroExtendExpr(CastedMaxBECount, WideTy), getZeroExtendExpr(Step, WideTy))); - if (getSignExtendExpr(Add, WideTy) == OperandExtendedAdd) + if (getSignExtendExpr(Add, WideTy) == OperandExtendedAdd) { + // Cache knowledge of AR NSW, which is propagated to this AddRec. + const_cast(AR)->setNoWrapFlags(SCEV::FlagNSW); // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), getZeroExtendExpr(Step, Ty), - // FIXME: can use SCEV::FlagNSW - L, SCEV::FlagAnyWrap); + L, AR->getNoWrapFlags()); + } } // If the backedge is guarded by a comparison with the pre-inc value @@ -1156,24 +1165,28 @@ if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SLT, AR, N) || (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SLT, Start, N) && isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SLT, - AR->getPostIncExpr(*this), N))) + AR->getPostIncExpr(*this), N))) { + // Cache knowledge of AR NSW, which is propagated to this AddRec. + const_cast(AR)->setNoWrapFlags(SCEV::FlagNSW); // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - // FIXME: can use SCEV::FlagNSW - L, SCEV::FlagAnyWrap); + L, AR->getNoWrapFlags()); + } } else if (isKnownNegative(Step)) { const SCEV *N = getConstant(APInt::getSignedMaxValue(BitWidth) - getSignedRange(Step).getSignedMin()); if (isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SGT, AR, N) || (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SGT, Start, N) && isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_SGT, - AR->getPostIncExpr(*this), N))) + AR->getPostIncExpr(*this), N))) { + // Cache knowledge of AR NSW, which is propagated to this AddRec. + const_cast(AR)->setNoWrapFlags(SCEV::FlagNSW); // Return the expression with the addrec on the outside. return getAddRecExpr(getSignExtendExpr(Start, Ty), getSignExtendExpr(Step, Ty), - // FIXME: can use SCEV::FlagNSW - L, SCEV::FlagAnyWrap); + L, AR->getNoWrapFlags()); + } } } } @@ -1227,8 +1240,7 @@ for (SCEVAddRecExpr::op_iterator I = AR->op_begin(), E = AR->op_end(); I != E; ++I) Ops.push_back(getAnyExtendExpr(*I, Ty)); - // FIXME: can use AR->getNoWrapFlags(SCEV::FlagNW) - return getAddRecExpr(Ops, AR->getLoop(), SCEV::FlagAnyWrap); + return getAddRecExpr(Ops, AR->getLoop(), SCEV::FlagNW); } // As a special case, fold anyext(undef) to undef. We don't want to @@ -1362,7 +1374,10 @@ #endif // If FlagNSW is true and all the operands are non-negative, infer FlagNUW. - if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) { + // And vice-versa. + int SignOrUnsignMask = SCEV::FlagNUW | SCEV::FlagNSW; + SCEV::NoWrapFlags SignOrUnsignWrap = maskFlags(Flags, SignOrUnsignMask); + if (SignOrUnsignWrap && (SignOrUnsignWrap != SignOrUnsignMask)) { bool All = true; for (SmallVectorImpl::const_iterator I = Ops.begin(), E = Ops.end(); I != E; ++I) @@ -1370,7 +1385,7 @@ All = false; break; } - if (All) Flags = setFlags(Flags, SCEV::FlagNUW); + if (All) Flags = setFlags(Flags, (SCEV::NoWrapFlags)SignOrUnsignMask); } // Sort by complexity, this groups all similar expression types together. @@ -1642,9 +1657,8 @@ // Build the new addrec. Propagate the NUW and NSW flags if both the // outer add and the inner addrec are guaranteed to have no overflow. - // FIXME: Always propagate NW - // AddRec->getNoWrapFlags(setFlags(Flags, SCEV::FlagNW)) - Flags = AddRec->getNoWrapFlags(Flags); + // Always propagate NW. + Flags = AddRec->getNoWrapFlags(setFlags(Flags, SCEV::FlagNW)); const SCEV *NewRec = getAddRecExpr(AddRecOps, AddRecLoop, Flags); // If all of the other operands were loop invariant, we are done. @@ -1731,7 +1745,10 @@ #endif // If FlagNSW is true and all the operands are non-negative, infer FlagNUW. - if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) { + // And vice-versa. + int SignOrUnsignMask = SCEV::FlagNUW | SCEV::FlagNSW; + SCEV::NoWrapFlags SignOrUnsignWrap = maskFlags(Flags, SignOrUnsignMask); + if (SignOrUnsignWrap && (SignOrUnsignWrap != SignOrUnsignMask)) { bool All = true; for (SmallVectorImpl::const_iterator I = Ops.begin(), E = Ops.end(); I != E; ++I) @@ -1739,7 +1756,7 @@ All = false; break; } - if (All) Flags = setFlags(Flags, SCEV::FlagNUW); + if (All) Flags = setFlags(Flags, (SCEV::NoWrapFlags)SignOrUnsignMask); } // Sort by complexity, this groups all similar expression types together. @@ -1977,8 +1994,7 @@ for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i) Operands.push_back(getUDivExpr(AR->getOperand(i), RHS)); return getAddRecExpr(Operands, AR->getLoop(), - // FIXME: AR->getNoWrapFlags(SCEV::FlagNW) - SCEV::FlagAnyWrap); + SCEV::FlagNW); } // (A*B)/C --> A*(B/C) if safe and B/C can be folded. if (const SCEVMulExpr *M = dyn_cast(LHS)) { @@ -2050,8 +2066,7 @@ if (const SCEVAddRecExpr *StepChrec = dyn_cast(Step)) if (StepChrec->getLoop() == L) { Operands.append(StepChrec->op_begin(), StepChrec->op_end()); - // FIXME: can use maskFlags(Flags, SCEV::FlagNW) - return getAddRecExpr(Operands, L, SCEV::FlagAnyWrap); + return getAddRecExpr(Operands, L, maskFlags(Flags, SCEV::FlagNW)); } Operands.push_back(Step); @@ -2086,7 +2101,10 @@ // with a SCEVCouldNotCompute as the cached BE count). // If FlagNSW is true and all the operands are non-negative, infer FlagNUW. - if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) { + // And vice-versa. + int SignOrUnsignMask = SCEV::FlagNUW | SCEV::FlagNSW; + SCEV::NoWrapFlags SignOrUnsignWrap = maskFlags(Flags, SignOrUnsignMask); + if (SignOrUnsignWrap && (SignOrUnsignWrap != SignOrUnsignMask)) { bool All = true; for (SmallVectorImpl::const_iterator I = Operands.begin(), E = Operands.end(); I != E; ++I) @@ -2094,7 +2112,7 @@ All = false; break; } - if (All) Flags = setFlags(Flags, SCEV::FlagNUW); + if (All) Flags = setFlags(Flags, (SCEV::NoWrapFlags)SignOrUnsignMask); } // Canonicalize nested AddRecs in by nesting them in order of loop depth. @@ -2119,11 +2137,10 @@ if (AllInvariant) { // Create a recurrence for the outer loop with the same step size. // - // FIXME: // The outer recurrence keeps its NW flag but only keeps NUW/NSW if the // inner recurrence has the same property. - // maskFlags(Flags, SCEV::FlagNW | NestedAR->getNoWrapFlags()); - SCEV::NoWrapFlags OuterFlags = SCEV::FlagAnyWrap; + SCEV::NoWrapFlags OuterFlags = + maskFlags(Flags, SCEV::FlagNW | NestedAR->getNoWrapFlags()); NestedOperands[0] = getAddRecExpr(Operands, L, OuterFlags); AllInvariant = true; @@ -2135,11 +2152,10 @@ if (AllInvariant) { // Ok, both add recurrences are valid after the transformation. // - // FIXME: // The inner recurrence keeps its NW flag but only keeps NUW/NSW if // the outer recurrence has the same property. - // maskFlags(NestedAR->getNoWrapFlags(), SCEV::FlagNW | Flags); - SCEV::NoWrapFlags InnerFlags = SCEV::FlagAnyWrap; + SCEV::NoWrapFlags InnerFlags = + maskFlags(NestedAR->getNoWrapFlags(), SCEV::FlagNW | Flags); return getAddRecExpr(NestedOperands, NestedLoop, InnerFlags); } } @@ -2840,8 +2856,7 @@ // unsigned but we may have a negative index from the base // pointer. if (GEP->isInBounds()) - // FIXME: should be SCEV::FlagNW - Flags = setFlags(Flags, SCEV::FlagNSW); + Flags = setFlags(Flags, SCEV::FlagNW); } const SCEV *StartVal = getSCEV(StartValueV); @@ -3119,7 +3134,6 @@ if (const SCEVAddRecExpr *AddRec = dyn_cast(S)) { // If there's no unsigned wrap, the value will never be less than its // initial value. - // FIXME: can broaden to FlagNW? if (AddRec->getNoWrapFlags(SCEV::FlagNUW)) if (const SCEVConstant *C = dyn_cast(AddRec->getStart())) if (!C->getValue()->isZero()) @@ -4755,8 +4769,7 @@ AddRec = cast( getAddRecExpr(NewOps, AddRec->getLoop(), - // FIXME: AddRec->getNoWrapFlags(SCEV::FlagNW) - SCEV::FlagAnyWrap)); + AddRec->getNoWrapFlags(SCEV::FlagNW))); break; } @@ -5880,8 +5893,7 @@ SmallVector Operands(op_begin(), op_end()); Operands[0] = SE.getConstant(SC->getType(), 0); const SCEV *Shifted = SE.getAddRecExpr(Operands, getLoop(), - // FIXME: getNoWrapFlags(FlagNW) - FlagAnyWrap); + getNoWrapFlags(FlagNW)); if (const SCEVAddRecExpr *ShiftedAddRec = dyn_cast(Shifted)) return ShiftedAddRec->getNumIterationsInRange( Modified: llvm/trunk/test/Analysis/ScalarEvolution/nsw-offset.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/nsw-offset.ll?rev=127638&r1=127637&r2=127638&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/nsw-offset.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/nsw-offset.ll Mon Mar 14 19:37:00 2011 @@ -19,11 +19,11 @@ %i.01 = phi i32 [ %16, %bb1 ], [ 0, %bb.nph ] ; [#uses=5] ; CHECK: %1 = sext i32 %i.01 to i64 -; CHECK: --> {0,+,2}<%bb> +; CHECK: --> {0,+,2}<%bb> %1 = sext i32 %i.01 to i64 ; [#uses=1] ; CHECK: %2 = getelementptr inbounds double* %d, i64 %1 -; CHECK: --> {%d,+,16}<%bb> +; CHECK: --> {%d,+,16}<%bb> %2 = getelementptr inbounds double* %d, i64 %1 ; [#uses=1] %3 = load double* %2, align 8 ; [#uses=1] @@ -33,11 +33,11 @@ %7 = or i32 %i.01, 1 ; [#uses=1] ; CHECK: %8 = sext i32 %7 to i64 -; CHECK: --> {1,+,2}<%bb> +; CHECK: --> {1,+,2}<%bb> %8 = sext i32 %7 to i64 ; [#uses=1] ; CHECK: %9 = getelementptr inbounds double* %q, i64 %8 -; CHECK: {(8 + %q),+,16}<%bb> +; CHECK: {(8 + %q),+,16}<%bb> %9 = getelementptr inbounds double* %q, i64 %8 ; [#uses=1] ; Artificially repeat the above three instructions, this time using @@ -45,11 +45,11 @@ %t7 = add nsw i32 %i.01, 1 ; [#uses=1] ; CHECK: %t8 = sext i32 %t7 to i64 -; CHECK: --> {1,+,2}<%bb> +; CHECK: --> {1,+,2}<%bb> %t8 = sext i32 %t7 to i64 ; [#uses=1] ; CHECK: %t9 = getelementptr inbounds double* %q, i64 %t8 -; CHECK: {(8 + %q),+,16}<%bb> +; CHECK: {(8 + %q),+,16}<%bb> %t9 = getelementptr inbounds double* %q, i64 %t8 ; [#uses=1] %10 = load double* %9, align 8 ; [#uses=1] Modified: llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll?rev=127638&r1=127637&r2=127638&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll Mon Mar 14 19:37:00 2011 @@ -35,7 +35,7 @@ bb1: ; preds = %bb %phitmp = sext i32 %tmp8 to i64 ; [#uses=1] ; CHECK: %phitmp -; CHECK-NEXT: --> {1,+,1}<%bb> +; CHECK-NEXT: --> {1,+,1}<%bb> %tmp9 = getelementptr double* %p, i64 %phitmp ; [#uses=1] ; CHECK: %tmp9 ; CHECK-NEXT: --> {(8 + %p),+,8}<%bb> @@ -62,11 +62,11 @@ for.body.i.i: ; preds = %for.body.i.i, %for.body.lr.ph.i.i %__first.addr.02.i.i = phi i32* [ %begin, %for.body.lr.ph.i.i ], [ %ptrincdec.i.i, %for.body.i.i ] ; CHECK: %__first.addr.02.i.i -; CHECK-NEXT: --> {%begin,+,4}<%for.body.i.i> +; CHECK-NEXT: --> {%begin,+,4}<%for.body.i.i> store i32 0, i32* %__first.addr.02.i.i, align 4 %ptrincdec.i.i = getelementptr inbounds i32* %__first.addr.02.i.i, i64 1 ; CHECK: %ptrincdec.i.i -; CHECK-NEXT: --> {(4 + %begin),+,4}<%for.body.i.i> +; CHECK-NEXT: --> {(4 + %begin),+,4}<%for.body.i.i> %cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end br i1 %cmp.i.i, label %for.cond.for.end_crit_edge.i.i, label %for.body.i.i @@ -88,7 +88,7 @@ ; CHECK: %indvar.i.i ; CHECK: {0,+,1}<%for.body.i.i> %tmp = add nsw i64 %indvar.i.i, 1 -; CHECK: %tmp = +; CHECK: %tmp = ; CHECK: {1,+,1}<%for.body.i.i> %ptrincdec.i.i = getelementptr inbounds i32* %begin, i64 %tmp ; CHECK: %ptrincdec.i.i = @@ -99,8 +99,8 @@ store i32 0, i32* %__first.addr.08.i.i, align 4 %cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end br i1 %cmp.i.i, label %_ZSt4fillIPiiEvT_S1_RKT0_.exit, label %for.body.i.i -; CHECK: Loop %for.body.i.i: Unpredictable backedge-taken count. -; CHECK: Loop %for.body.i.i: Unpredictable max backedge-taken count. +; CHECK: Loop %for.body.i.i: backedge-taken count is ((-4 + (-1 * %begin) + %end) /u 4) +; CHECK: Loop %for.body.i.i: max backedge-taken count is ((-4 + (-1 * %begin) + %end) /u 4) _ZSt4fillIPiiEvT_S1_RKT0_.exit: ; preds = %for.body.i.i, %entry ret void } \ No newline at end of file Modified: llvm/trunk/test/Analysis/ScalarEvolution/sext-iv-0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/sext-iv-0.ll?rev=127638&r1=127637&r2=127638&view=diff ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/sext-iv-0.ll (original) +++ llvm/trunk/test/Analysis/ScalarEvolution/sext-iv-0.ll Mon Mar 14 19:37:00 2011 @@ -1,5 +1,4 @@ -; RUN: opt < %s -scalar-evolution -analyze \ -; RUN: | grep { --> \{-128,+,1\}<%bb1> Exits: 127} | count 5 +; RUN: opt < %s -scalar-evolution -analyze | FileCheck %s ; Convert (sext {-128,+,1}) to {sext(-128),+,sext(1)}, since the ; trip count is within range where this is safe. @@ -13,9 +12,17 @@ bb1: ; preds = %bb1, %bb1.thread %i.0.reg2mem.0 = phi i64 [ -128, %bb1.thread ], [ %8, %bb1 ] ; [#uses=3] +; CHECK: %i.0.reg2mem.0 +; CHECK-NEXT: --> {-128,+,1}<%bb1> Exits: 127 %0 = trunc i64 %i.0.reg2mem.0 to i8 ; [#uses=1] +; CHECK: %0 +; CHECK-NEXT: --> {-128,+,1}<%bb1> Exits: 127 %1 = trunc i64 %i.0.reg2mem.0 to i9 ; [#uses=1] +; CHECK: %1 +; CHECK-NEXT: --> {-128,+,1}<%bb1> Exits: 127 %2 = sext i9 %1 to i64 ; [#uses=1] +; CHECK: %2 +; CHECK-NEXT: --> {-128,+,1}<%bb1> Exits: 127 %3 = getelementptr double* %x, i64 %2 ; [#uses=1] %4 = load double* %3, align 8 ; [#uses=1] %5 = fmul double %4, 3.900000e+00 ; [#uses=1] From evan.cheng at apple.com Mon Mar 14 19:54:35 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 14 Mar 2011 17:54:35 -0700 Subject: [llvm-commits] [llvm] r127598 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/ARM/shifter_operand.ll test/CodeGen/ARM/undef-sext.ll In-Reply-To: References: <20110314181555.6A48F2A6C12D@llvm.org> Message-ID: <438E7BFE-C3A0-4DBC-8B1C-704ED9000F37@apple.com> On Mar 14, 2011, at 5:39 PM, Chris Lattner wrote: > > On Mar 14, 2011, at 4:37 PM, Evan Cheng wrote: > >> >> On Mar 14, 2011, at 11:25 AM, Frits van Bommel wrote: >> >>> On Mon, Mar 14, 2011 at 7:15 PM, Evan Cheng wrote: >>>> Log: >>>> Minor optimization. sign-ext/anyext of undef is still undef. >>> >>> I can believe this for anyext, but a sext'ed undef should probably >>> still have equal high bits, which is not a requirement for the bigger >>> undef you're replacing it with. >> >> I don't see the problem, the high-bit of an undef is an unknown value. zero-extend is definitely not safe, but sign-extend should be fine. > > Sign extend doesn't specify what the top bit is, but it does guarantee that the top bits are all the same. Instead of folding to undef, sext(undef) should fold to 0. This is what happens at the IR level: That makes sense. I'll fix. Evan > > Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, > const Type *DestTy) { > if (isa(V)) { > // zext(undef) = 0, because the top bits will be zero. > // sext(undef) = 0, because the top bits will all be the same. > // [us]itofp(undef) = 0, because the result value is bounded. > if (opc == Instruction::ZExt || opc == Instruction::SExt || > opc == Instruction::UIToFP || opc == Instruction::SIToFP) > return Constant::getNullValue(DestTy); > return UndefValue::get(DestTy); > } > > -Chris From atrick at apple.com Mon Mar 14 19:56:25 2011 From: atrick at apple.com (Andrew Trick) Date: Mon, 14 Mar 2011 17:56:25 -0700 Subject: [llvm-commits] [llvm] r127591 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp In-Reply-To: References: <20110314172802.877602A6C12C@llvm.org> Message-ID: On Mar 14, 2011, at 4:32 PM, Eli Friedman wrote: > Hmm... getBackedgeTakenCount and getMaxBackedgeTakenCount have > surprisingly few users. One user of getBackedgeTakenCount is IndVars, > which will try to rewrite the exit condition in terms of the backedge > taken count. It assumes that the count is both the exit count and the > maximum loop count of the loop. On the other hand, LoopIdiomRecognize > doesn't really care what the max iteration count is (I'm not > completely sure it's safe for other reasons, but that isn't really > related). I'm not sure I really follow what LSR is doing with the > backedge taken count. LoopDeletion uses the MaxBackedgeTakenCount to > make sure a loop isn't infinite. And I think that actually > exhaustively covers all the uses of the backedge counts. So > basically, if we can't actually do an indvars transform, very little > actually looks at the backedge count directly. Some places that use > LoopInfo::getTripCount() and friends could probably be changed to be > more aggressive, though. > > -Eli Thanks for the analysis. FYI: I'm working toward suppressing some of the indvars transforms. Particularly the canonicalization of induction vars. Doing this will make LSR an optional pass--we can turn it off without pessimizing the code. LSR needs work, but I'm not there yet. -Andy From isanbard at gmail.com Mon Mar 14 20:03:17 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 15 Mar 2011 01:03:17 -0000 Subject: [llvm-commits] [llvm] r127640 - /llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp Message-ID: <20110315010317.9611B2A6C12C@llvm.org> Author: void Date: Mon Mar 14 20:03:17 2011 New Revision: 127640 URL: http://llvm.org/viewvc/llvm-project?rev=127640&view=rev Log: There are some situations which can cause the URoR hack to infinitely recurse and then go kablooie. The problem was that it was tracking the PHI nodes anew each time into this function. But it didn't need to. And because the recursion didn't know that a PHINode was visited before, it would go ahead and call itself. There is a testcase, but unfortunately it's too big to add. This problem will go away with the EH rewrite. Modified: llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp Modified: llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp?rev=127640&r1=127639&r2=127640&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfEHPrepare.cpp Mon Mar 14 20:03:17 2011 @@ -93,7 +93,8 @@ /// with the eh.exception call. This recursively looks past instructions /// which don't change the EH pointer value, like casts or PHI nodes. bool FindSelectorAndURoR(Instruction *Inst, bool &URoRInvoke, - SmallPtrSet &SelCalls); + SmallPtrSet &SelCalls, + SmallPtrSet &SeenPHIs); public: static char ID; // Pass identification, replacement for typeid. @@ -199,8 +200,8 @@ /// change the EH pointer value, like casts or PHI nodes. bool DwarfEHPrepare::FindSelectorAndURoR(Instruction *Inst, bool &URoRInvoke, - SmallPtrSet &SelCalls) { - SmallPtrSet SeenPHIs; + SmallPtrSet &SelCalls, + SmallPtrSet &SeenPHIs) { bool Changed = false; for (Value::use_iterator @@ -215,11 +216,11 @@ if (Invoke->getCalledFunction() == URoR) URoRInvoke = true; } else if (CastInst *CI = dyn_cast(II)) { - Changed |= FindSelectorAndURoR(CI, URoRInvoke, SelCalls); + Changed |= FindSelectorAndURoR(CI, URoRInvoke, SelCalls, SeenPHIs); } else if (PHINode *PN = dyn_cast(II)) { if (SeenPHIs.insert(PN)) // Don't process a PHI node more than once. - Changed |= FindSelectorAndURoR(PN, URoRInvoke, SelCalls); + Changed |= FindSelectorAndURoR(PN, URoRInvoke, SelCalls, SeenPHIs); } } @@ -294,7 +295,8 @@ bool URoRInvoke = false; SmallPtrSet SelCalls; - Changed |= FindSelectorAndURoR(EHPtr, URoRInvoke, SelCalls); + SmallPtrSet SeenPHIs; + Changed |= FindSelectorAndURoR(EHPtr, URoRInvoke, SelCalls, SeenPHIs); if (URoRInvoke) { // This EH pointer is being used by an invoke of an URoR instruction and From johnny.chen at apple.com Mon Mar 14 20:13:18 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 15 Mar 2011 01:13:18 -0000 Subject: [llvm-commits] [llvm] r127642 - in /llvm/trunk: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110315011318.19A7E2A6C12C@llvm.org> Author: johnny Date: Mon Mar 14 20:13:17 2011 New Revision: 127642 URL: http://llvm.org/viewvc/llvm-project?rev=127642&view=rev Log: Fixed an ARM disassembler bug where it does not handle STRi12 correctly because an extra register operand was erroneously added. Remove an incorrect assert which triggers the bug. rdar://problem/9131529 Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=127642&r1=127641&r2=127642&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Mon Mar 14 20:13:17 2011 @@ -1079,18 +1079,21 @@ if (OpIdx + 1 >= NumOps) return false; - assert((OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) && - (OpInfo[OpIdx+1].RegClass < 0) && - "Expect 1 reg operand followed by 1 imm operand"); - ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub; if (getIBit(insn) == 0) { - MI.addOperand(MCOperand::CreateReg(0)); + // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2). + // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already + // been populated. + if (isPrePost) { + MI.addOperand(MCOperand::CreateReg(0)); + OpIdx += 1; + } // Disassemble the 12-bit immediate offset. unsigned Imm12 = slice(insn, 11, 0); unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift); MI.addOperand(MCOperand::CreateImm(Offset)); + OpIdx += 1; } else { // Disassemble the offset reg (Rm), shift type, and immediate shift length. MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, @@ -1104,8 +1107,8 @@ getImmShiftSE(ShOp, ShImm); MI.addOperand(MCOperand::CreateImm( ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp))); + OpIdx += 2; } - OpIdx += 2; return true; } Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=127642&r1=127641&r2=127642&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Mon Mar 14 20:13:17 2011 @@ -142,3 +142,15 @@ # CHECK: uqadd16mi r6, r11, r8 0x18 0x60 0x6b 0x46 + +# CHECK: str r0, [sp, #4] +0x04 0x00 0x8d 0xe5 + +# CHECK: str r1, [sp] +0x00 0x10 0x8d 0xe5 + +# CHECK: ldr r3, [pc, #144] +0x90 0x30 0x9f 0xe5 + +# CHECK: strdeq r2, r3, [r0], -r8 +0xf8 0x24 0x00 0x00 From atrick at apple.com Mon Mar 14 20:16:14 2011 From: atrick at apple.com (Andrew Trick) Date: Tue, 15 Mar 2011 01:16:14 -0000 Subject: [llvm-commits] [llvm] r127643 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <20110315011614.8E5FA2A6C12C@llvm.org> Author: atrick Date: Mon Mar 14 20:16:14 2011 New Revision: 127643 URL: http://llvm.org/viewvc/llvm-project?rev=127643&view=rev Log: Remove getMinusSCEVForExitTest(). This function performed acrobatics to prove no-self-wrap, which we now have for free. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127643&r1=127642&r2=127643&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 14 20:16:14 2011 @@ -2577,10 +2577,10 @@ } /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1. -/// -/// FIXME: prohibit FlagNUW here, as soon as getMinusSCEVForExitTest goes. const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags) { + assert(!maskFlags(Flags, SCEV::FlagNUW) && "subtraction does not have NUW"); + // Fast path: X - X --> 0. if (LHS == RHS) return getConstant(LHS->getType(), 0); @@ -4080,106 +4080,6 @@ return ComputeBackedgeTakenCountExhaustively(L, ExitCond, !L->contains(TBB)); } -static const SCEVAddRecExpr * -isSimpleUnwrappingAddRec(const SCEV *S, const Loop *L) { - const SCEVAddRecExpr *SA = dyn_cast(S); - - // The SCEV must be an addrec of this loop. - if (!SA || SA->getLoop() != L || !SA->isAffine()) - return 0; - - // The SCEV must be known to not wrap in some way to be interesting. - if (!SA->getNoWrapFlags(SCEV::FlagNW)) - return 0; - - // The stride must be a constant so that we know if it is striding up or down. - if (!isa(SA->getOperand(1))) - return 0; - return SA; -} - -/// getMinusSCEVForExitTest - When considering an exit test for a loop with a -/// "x != y" exit test, we turn this into a computation that evaluates x-y != 0, -/// and this function returns the expression to use for x-y. We know and take -/// advantage of the fact that this subtraction is only being used in a -/// comparison by zero context. -/// -/// FIXME: this can be completely removed once AddRec FlagNWs are propagated. -static const SCEV *getMinusSCEVForExitTest(const SCEV *LHS, const SCEV *RHS, - const Loop *L, ScalarEvolution &SE) { - // If either LHS or RHS is an AddRec SCEV (of this loop) that is known to not - // self-wrap, then we know that the value will either become the other one - // (and thus the loop terminates), that the loop will terminate through some - // other exit condition first, or that the loop has undefined behavior. This - // information is useful when the addrec has a stride that is != 1 or -1, - // because it means we can't "miss" the exit value. - // - // In any of these three cases, it is safe to turn the exit condition into a - // "counting down" AddRec (to zero) by subtracting the two inputs as normal, - // but since we know that the "end cannot be missed" we can force the - // resulting AddRec to be a NUW addrec. Since it is counting down, this means - // that the AddRec *cannot* pass zero. - - // See if LHS and RHS are addrec's we can handle. - const SCEVAddRecExpr *LHSA = isSimpleUnwrappingAddRec(LHS, L); - const SCEVAddRecExpr *RHSA = isSimpleUnwrappingAddRec(RHS, L); - - // If neither addrec is interesting, just return a minus. - if (RHSA == 0 && LHSA == 0) - return SE.getMinusSCEV(LHS, RHS); - - // If only one of LHS and RHS are an AddRec of this loop, make sure it is LHS. - if (RHSA && LHSA == 0) { - // Safe because a-b === b-a for comparisons against zero. - std::swap(LHS, RHS); - std::swap(LHSA, RHSA); - } - - // Handle the case when only one is advancing in a non-overflowing way. - if (RHSA == 0) { - // If RHS is loop varying, then we can't predict when LHS will cross it. - if (!SE.isLoopInvariant(RHS, L)) - return SE.getMinusSCEV(LHS, RHS); - - // If LHS has a positive stride, then we compute RHS-LHS, because the loop - // is counting up until it crosses RHS (which must be larger than LHS). If - // it is negative, we compute LHS-RHS because we're counting down to RHS. - const ConstantInt *Stride = - cast(LHSA->getOperand(1))->getValue(); - if (Stride->getValue().isNegative()) - std::swap(LHS, RHS); - - return SE.getMinusSCEV(RHS, LHS, SCEV::FlagNUW); - } - - // If both LHS and RHS are interesting, we have something like: - // a+i*4 != b+i*8. - const ConstantInt *LHSStride = - cast(LHSA->getOperand(1))->getValue(); - const ConstantInt *RHSStride = - cast(RHSA->getOperand(1))->getValue(); - - // If the strides are equal, then this is just a (complex) loop invariant - // comparison of a and b. - if (LHSStride == RHSStride) - return SE.getMinusSCEV(LHSA->getStart(), RHSA->getStart()); - - // If the signs of the strides differ, then the negative stride is counting - // down to the positive stride. - if (LHSStride->getValue().isNegative() != RHSStride->getValue().isNegative()){ - if (RHSStride->getValue().isNegative()) - std::swap(LHS, RHS); - } else { - // If LHS's stride is smaller than RHS's stride, then "b" must be less than - // "a" and "b" is RHS is counting up (catching up) to LHS. This is true - // whether the strides are positive or negative. - if (RHSStride->getValue().slt(LHSStride->getValue())) - std::swap(LHS, RHS); - } - - return SE.getMinusSCEV(LHS, RHS, SCEV::FlagNUW); -} - /// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of times the /// backedge of the specified loop will execute if its exit condition /// were a conditional branch of the ICmpInst ExitCond, TBB, and FBB. @@ -4239,10 +4139,7 @@ switch (Cond) { case ICmpInst::ICMP_NE: { // while (X != Y) // Convert to: while (X-Y != 0) - // FIXME: Once AddRec FlagNW are propagated, should be: - // BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEV(LHS, RHS), L); - BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEVForExitTest(LHS, RHS, L, - *this), L); + BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEV(LHS, RHS), L); if (BTI.hasAnyInfo()) return BTI; break; } From scallanan at apple.com Mon Mar 14 20:23:15 2011 From: scallanan at apple.com (Sean Callanan) Date: Tue, 15 Mar 2011 01:23:15 -0000 Subject: [llvm-commits] [llvm] r127644 - in /llvm/trunk: lib/Target/X86/Disassembler/X86Disassembler.cpp lib/Target/X86/Disassembler/X86DisassemblerDecoder.c lib/Target/X86/Disassembler/X86DisassemblerDecoder.h lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h utils/TableGen/X86DisassemblerTables.cpp utils/TableGen/X86RecognizableInstr.cpp utils/TableGen/X86RecognizableInstr.h Message-ID: <20110315012315.484772A6C12C@llvm.org> Author: spyffe Date: Mon Mar 14 20:23:15 2011 New Revision: 127644 URL: http://llvm.org/viewvc/llvm-project?rev=127644&view=rev Log: X86 table-generator and disassembler support for the AVX instruction set. This code adds support for the VEX prefix and for the YMM registers accessible on AVX-enabled architectures. Instruction table support that enables AVX instructions for the disassembler is in an upcoming patch. Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp llvm/trunk/utils/TableGen/X86RecognizableInstr.h Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp?rev=127644&r1=127643&r2=127644&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp Mon Mar 14 20:23:15 2011 @@ -409,6 +409,7 @@ case TYPE_XMM32: case TYPE_XMM64: case TYPE_XMM128: + case TYPE_XMM256: case TYPE_DEBUGREG: case TYPE_CONTROLREG: return translateRMRegister(mcInst, insn); @@ -418,6 +419,7 @@ case TYPE_M32: case TYPE_M64: case TYPE_M128: + case TYPE_M256: case TYPE_M512: case TYPE_Mv: case TYPE_M32FP: @@ -500,6 +502,9 @@ case ENCODING_Rv: translateRegister(mcInst, insn.opcodeRegister); return false; + case ENCODING_VVVV: + translateRegister(mcInst, insn.vvvv); + return false; case ENCODING_DUP: return translateOperand(mcInst, insn.spec->operands[operand.type - TYPE_DUP0], Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c?rev=127644&r1=127643&r2=127644&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c Mon Mar 14 20:23:15 2011 @@ -368,29 +368,109 @@ if (isPrefix) dbgprintf(insn, "Found prefix 0x%hhx", byte); } + + insn->vexSize = 0; - if (insn->mode == MODE_64BIT) { - if ((byte & 0xf0) == 0x40) { - uint8_t opcodeByte; + if (byte == 0xc4) { + uint8_t byte1; - if (lookAtByte(insn, &opcodeByte) || ((opcodeByte & 0xf0) == 0x40)) { - dbgprintf(insn, "Redundant REX prefix"); - return -1; + if (lookAtByte(insn, &byte1)) { + dbgprintf(insn, "Couldn't read second byte of VEX"); + return -1; + } + + if (insn->mode == MODE_64BIT || byte1 & 0x8) { + insn->vexSize = 3; + insn->necessaryPrefixLocation = insn->readerCursor - 1; + } + else { + unconsumeByte(insn); + insn->necessaryPrefixLocation = insn->readerCursor - 1; + } + + if (insn->vexSize == 3) { + insn->vexPrefix[0] = byte; + consumeByte(insn, &insn->vexPrefix[1]); + consumeByte(insn, &insn->vexPrefix[2]); + + /* We simulate the REX prefix for simplicity's sake */ + + insn->rexPrefix = 0x40 + | (wFromVEX3of3(insn->vexPrefix[2]) << 3) + | (rFromVEX2of3(insn->vexPrefix[1]) << 2) + | (xFromVEX2of3(insn->vexPrefix[1]) << 1) + | (bFromVEX2of3(insn->vexPrefix[1]) << 0); + + switch (ppFromVEX3of3(insn->vexPrefix[2])) + { + default: + break; + case VEX_PREFIX_66: + hasOpSize = TRUE; + break; } + + dbgprintf(insn, "Found VEX prefix 0x%hhx 0x%hhx 0x%hhx", insn->vexPrefix[0], insn->vexPrefix[1], insn->vexPrefix[2]); + } + } + else if (byte == 0xc5) { + uint8_t byte1; + + if (lookAtByte(insn, &byte1)) { + dbgprintf(insn, "Couldn't read second byte of VEX"); + return -1; + } - insn->rexPrefix = byte; - insn->necessaryPrefixLocation = insn->readerCursor - 2; - - dbgprintf(insn, "Found REX prefix 0x%hhx", byte); - } else { + if (insn->mode == MODE_64BIT || byte1 & 0x8) { + insn->vexSize = 2; + } + else { + unconsumeByte(insn); + } + + if (insn->vexSize == 2) { + insn->vexPrefix[0] = byte; + consumeByte(insn, &insn->vexPrefix[1]); + + insn->rexPrefix = 0x40 + | (rFromVEX2of2(insn->vexPrefix[1]) << 2); + + switch (ppFromVEX2of2(insn->vexPrefix[1])) + { + default: + break; + case VEX_PREFIX_66: + hasOpSize = TRUE; + break; + } + + dbgprintf(insn, "Found VEX prefix 0x%hhx 0x%hhx", insn->vexPrefix[0], insn->vexPrefix[1]); + } + } + else { + if (insn->mode == MODE_64BIT) { + if ((byte & 0xf0) == 0x40) { + uint8_t opcodeByte; + + if (lookAtByte(insn, &opcodeByte) || ((opcodeByte & 0xf0) == 0x40)) { + dbgprintf(insn, "Redundant REX prefix"); + return -1; + } + + insn->rexPrefix = byte; + insn->necessaryPrefixLocation = insn->readerCursor - 2; + + dbgprintf(insn, "Found REX prefix 0x%hhx", byte); + } else { + unconsumeByte(insn); + insn->necessaryPrefixLocation = insn->readerCursor - 1; + } + } else { unconsumeByte(insn); insn->necessaryPrefixLocation = insn->readerCursor - 1; } - } else { - unconsumeByte(insn); - insn->necessaryPrefixLocation = insn->readerCursor - 1; } - + if (insn->mode == MODE_16BIT) { insn->registerSize = (hasOpSize ? 4 : 2); insn->addressSize = (hasAdSize ? 4 : 2); @@ -438,6 +518,39 @@ dbgprintf(insn, "readOpcode()"); insn->opcodeType = ONEBYTE; + + if (insn->vexSize == 3) + { + switch (mmmmmFromVEX2of3(insn->vexPrefix[1])) + { + default: + dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)", mmmmmFromVEX2of3(insn->vexPrefix[1])); + return -1; + case 0: + break; + case VEX_LOB_0F: + insn->twoByteEscape = 0x0f; + insn->opcodeType = TWOBYTE; + return consumeByte(insn, &insn->opcode); + case VEX_LOB_0F38: + insn->twoByteEscape = 0x0f; + insn->threeByteEscape = 0x38; + insn->opcodeType = THREEBYTE_38; + return consumeByte(insn, &insn->opcode); + case VEX_LOB_0F3A: + insn->twoByteEscape = 0x0f; + insn->threeByteEscape = 0x3a; + insn->opcodeType = THREEBYTE_3A; + return consumeByte(insn, &insn->opcode); + } + } + else if (insn->vexSize == 2) + { + insn->twoByteEscape = 0x0f; + insn->opcodeType = TWOBYTE; + return consumeByte(insn, &insn->opcode); + } + if (consumeByte(insn, ¤t)) return -1; @@ -600,20 +713,64 @@ dbgprintf(insn, "getID()"); attrMask = ATTR_NONE; - + if (insn->mode == MODE_64BIT) attrMask |= ATTR_64BIT; - - if (insn->rexPrefix & 0x08) - attrMask |= ATTR_REXW; - - if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) - attrMask |= ATTR_OPSIZE; - else if (isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation)) - attrMask |= ATTR_XS; - else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation)) - attrMask |= ATTR_XD; - + + if (insn->vexSize) { + attrMask |= ATTR_VEX; + + if (insn->vexSize == 3) { + switch (ppFromVEX3of3(insn->vexPrefix[2])) { + case VEX_PREFIX_66: + attrMask |= ATTR_OPSIZE; + break; + case VEX_PREFIX_F3: + attrMask |= ATTR_XS; + break; + case VEX_PREFIX_F2: + attrMask |= ATTR_XD; + break; + } + + if (wFromVEX3of3(insn->vexPrefix[2])) + attrMask |= ATTR_REXW; + if (lFromVEX3of3(insn->vexPrefix[2])) + attrMask |= ATTR_VEXL; + } + else if (insn->vexSize == 2) { + switch (ppFromVEX2of2(insn->vexPrefix[1])) { + case VEX_PREFIX_66: + attrMask |= ATTR_OPSIZE; + break; + case VEX_PREFIX_F3: + attrMask |= ATTR_XS; + break; + case VEX_PREFIX_F2: + attrMask |= ATTR_XD; + break; + } + + if (lFromVEX2of2(insn->vexPrefix[1])) + attrMask |= ATTR_VEXL; + } + else { + return -1; + } + } + else { + if (insn->rexPrefix & 0x08) + attrMask |= ATTR_REXW; + + if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) + attrMask |= ATTR_OPSIZE; + else if (isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation)) + attrMask |= ATTR_XS; + else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation)) + attrMask |= ATTR_XD; + + } + if (getIDWithAttrMask(&instructionID, insn, attrMask)) return -1; @@ -1012,6 +1169,8 @@ return prefix##_EAX + index; \ case TYPE_R64: \ return prefix##_RAX + index; \ + case TYPE_XMM256: \ + return prefix##_YMM0 + index; \ case TYPE_XMM128: \ case TYPE_XMM64: \ case TYPE_XMM32: \ @@ -1073,6 +1232,14 @@ default: debug("Expected a REG or R/M encoding in fixupReg"); return -1; + case ENCODING_VVVV: + insn->vvvv = (Reg)fixupRegValue(insn, + (OperandType)op->type, + insn->vvvv, + &valid); + if (!valid) + return -1; + break; case ENCODING_REG: insn->reg = (Reg)fixupRegValue(insn, (OperandType)op->type, @@ -1237,6 +1404,27 @@ } /* + * readVVVV - Consumes an immediate operand from an instruction, given the + * desired operand size. + * + * @param insn - The instruction whose operand is to be read. + * @return - 0 if the immediate was successfully consumed; nonzero + * otherwise. + */ +static int readVVVV(struct InternalInstruction* insn) { + dbgprintf(insn, "readVVVV()"); + + if (insn->vexSize == 3) + insn->vvvv = vvvvFromVEX3of3(insn->vexPrefix[2]); + else if (insn->vexSize == 2) + insn->vvvv = vvvvFromVEX2of2(insn->vexPrefix[1]); + else + return -1; + + return 0; +} + +/* * readOperands - Consults the specifier for an instruction and consumes all * operands for that instruction, interpreting them as it goes. * @@ -1317,6 +1505,13 @@ case ENCODING_I: if (readOpcodeModifier(insn)) return -1; + break; + case ENCODING_VVVV: + if (readVVVV(insn)) + return -1; + if (fixupReg(insn, &insn->spec->operands[index])) + return -1; + break; case ENCODING_DUP: break; default: Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h?rev=127644&r1=127643&r2=127644&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h Mon Mar 14 20:23:15 2011 @@ -34,16 +34,30 @@ /* * Accessor functions for various fields of an Intel instruction */ -#define modFromModRM(modRM) ((modRM & 0xc0) >> 6) -#define regFromModRM(modRM) ((modRM & 0x38) >> 3) -#define rmFromModRM(modRM) (modRM & 0x7) -#define scaleFromSIB(sib) ((sib & 0xc0) >> 6) -#define indexFromSIB(sib) ((sib & 0x38) >> 3) -#define baseFromSIB(sib) (sib & 0x7) -#define wFromREX(rex) ((rex & 0x8) >> 3) -#define rFromREX(rex) ((rex & 0x4) >> 2) -#define xFromREX(rex) ((rex & 0x2) >> 1) -#define bFromREX(rex) (rex & 0x1) +#define modFromModRM(modRM) (((modRM) & 0xc0) >> 6) +#define regFromModRM(modRM) (((modRM) & 0x38) >> 3) +#define rmFromModRM(modRM) ((modRM) & 0x7) +#define scaleFromSIB(sib) (((sib) & 0xc0) >> 6) +#define indexFromSIB(sib) (((sib) & 0x38) >> 3) +#define baseFromSIB(sib) ((sib) & 0x7) +#define wFromREX(rex) (((rex) & 0x8) >> 3) +#define rFromREX(rex) (((rex) & 0x4) >> 2) +#define xFromREX(rex) (((rex) & 0x2) >> 1) +#define bFromREX(rex) ((rex) & 0x1) + +#define rFromVEX2of3(vex) (((~(vex)) & 0x80) >> 7) +#define xFromVEX2of3(vex) (((~(vex)) & 0x40) >> 6) +#define bFromVEX2of3(vex) (((~(vex)) & 0x20) >> 5) +#define mmmmmFromVEX2of3(vex) ((vex) & 0x1f) +#define wFromVEX3of3(vex) (((vex) & 0x80) >> 7) +#define vvvvFromVEX3of3(vex) (((~(vex)) & 0x78) >> 3) +#define lFromVEX3of3(vex) (((vex) & 0x4) >> 2) +#define ppFromVEX3of3(vex) ((vex) & 0x3) + +#define rFromVEX2of2(vex) (((~(vex)) & 0x80) >> 7) +#define vvvvFromVEX2of2(vex) (((~(vex)) & 0x78) >> 3) +#define lFromVEX2of2(vex) (((vex) & 0x4) >> 2) +#define ppFromVEX2of2(vex) ((vex) & 0x3) /* * These enums represent Intel registers for use by the decoder. @@ -206,7 +220,25 @@ ENTRY(XMM13) \ ENTRY(XMM14) \ ENTRY(XMM15) - + +#define REGS_YMM \ + ENTRY(YMM0) \ + ENTRY(YMM1) \ + ENTRY(YMM2) \ + ENTRY(YMM3) \ + ENTRY(YMM4) \ + ENTRY(YMM5) \ + ENTRY(YMM6) \ + ENTRY(YMM7) \ + ENTRY(YMM8) \ + ENTRY(YMM9) \ + ENTRY(YMM10) \ + ENTRY(YMM11) \ + ENTRY(YMM12) \ + ENTRY(YMM13) \ + ENTRY(YMM14) \ + ENTRY(YMM15) + #define REGS_SEGMENT \ ENTRY(ES) \ ENTRY(CS) \ @@ -252,6 +284,7 @@ REGS_64BIT \ REGS_MMX \ REGS_XMM \ + REGS_YMM \ REGS_SEGMENT \ REGS_DEBUG \ REGS_CONTROL \ @@ -332,6 +365,27 @@ SEG_OVERRIDE_GS, SEG_OVERRIDE_max } SegmentOverride; + +/* + * VEXLeadingOpcodeByte - Possible values for the VEX.m-mmmm field + */ + +typedef enum { + VEX_LOB_0F = 0x1, + VEX_LOB_0F38 = 0x2, + VEX_LOB_0F3A = 0x3 +} VEXLeadingOpcodeByte; + +/* + * VEXPrefixCode - Possible values for the VEX.pp field + */ + +typedef enum { + VEX_PREFIX_NONE = 0x0, + VEX_PREFIX_66 = 0x1, + VEX_PREFIX_F3 = 0x2, + VEX_PREFIX_F2 = 0x3 +} VEXPrefixCode; typedef uint8_t BOOL; @@ -389,10 +443,12 @@ uint8_t prefixPresent[0x100]; /* contains the location (for use with the reader) of the prefix byte */ uint64_t prefixLocations[0x100]; + /* The value of the VEX prefix, if present */ + uint8_t vexPrefix[3]; + /* The length of the VEX prefix (0 if not present) */ + uint8_t vexSize; /* The value of the REX prefix, if present */ uint8_t rexPrefix; - /* The location of the REX prefix */ - uint64_t rexLocation; /* The location where a mandatory prefix would have to be (i.e., right before the opcode, or right before the REX prefix if one is present) */ uint64_t necessaryPrefixLocation; @@ -428,6 +484,10 @@ /* state for additional bytes, consumed during operand decode. Pattern: consumed___ indicates that the byte was already consumed and does not need to be consumed again */ + + /* The VEX.vvvv field, which contains a thrid register operand for some AVX + instructions */ + Reg vvvv; /* The ModR/M byte, which contains most register operands and some portion of all memory operands */ Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h?rev=127644&r1=127643&r2=127644&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h Mon Mar 14 20:23:15 2011 @@ -49,7 +49,9 @@ ENUM_ENTRY(ATTR_XS, 0x02) \ ENUM_ENTRY(ATTR_XD, 0x04) \ ENUM_ENTRY(ATTR_REXW, 0x08) \ - ENUM_ENTRY(ATTR_OPSIZE, 0x10) + ENUM_ENTRY(ATTR_OPSIZE, 0x10) \ + ENUM_ENTRY(ATTR_VEX, 0x20) \ + ENUM_ENTRY(ATTR_VEXL, 0x40) #define ENUM_ENTRY(n, v) n = v, enum attributeBits { @@ -87,7 +89,20 @@ "IC_64BIT_REXW_XS") \ ENUM_ENTRY(IC_64BIT_REXW_OPSIZE, 7, "The Dynamic Duo! Prefer over all " \ "else because this changes most " \ - "operands' meaning") + "operands' meaning") \ + ENUM_ENTRY(IC_VEX, 1, "requires a VEX prefix") \ + ENUM_ENTRY(IC_VEX_XS, 2, "requires VEX and the XS prefix") \ + ENUM_ENTRY(IC_VEX_XD, 2, "requires VEX and the XD prefix") \ + ENUM_ENTRY(IC_VEX_OPSIZE, 2, "requires VEX and the OpSize prefix") \ + ENUM_ENTRY(IC_VEX_W, 3, "requires VEX and the W prefix") \ + ENUM_ENTRY(IC_VEX_W_XS, 4, "requires VEX, W, and XS prefix") \ + ENUM_ENTRY(IC_VEX_W_XD, 4, "requires VEX, W, and XD prefix") \ + ENUM_ENTRY(IC_VEX_W_OPSIZE, 4, "requires VEX, W, and OpSize") \ + ENUM_ENTRY(IC_VEX_L, 3, "requires VEX and the L prefix") \ + ENUM_ENTRY(IC_VEX_L_XS, 4, "requires VEX and the L and XS prefix")\ + ENUM_ENTRY(IC_VEX_L_XD, 4, "requires VEX and the L and XS prefix")\ + ENUM_ENTRY(IC_VEX_L_OPSIZE, 4, "requires VEX, L, and OpSize") + #define ENUM_ENTRY(n, r, d) n, typedef enum { @@ -183,6 +198,7 @@ ENUM_ENTRY(ENCODING_NONE, "") \ ENUM_ENTRY(ENCODING_REG, "Register operand in ModR/M byte.") \ ENUM_ENTRY(ENCODING_RM, "R/M operand in ModR/M byte.") \ + ENUM_ENTRY(ENCODING_VVVV, "Register operand in VEX.vvvv byte.") \ ENUM_ENTRY(ENCODING_CB, "1-byte code offset (possible new CS value)") \ ENUM_ENTRY(ENCODING_CW, "2-byte") \ ENUM_ENTRY(ENCODING_CD, "4-byte") \ @@ -278,6 +294,7 @@ ENUM_ENTRY(TYPE_XMM32, "4-byte XMM register or memory operand") \ ENUM_ENTRY(TYPE_XMM64, "8-byte") \ ENUM_ENTRY(TYPE_XMM128, "16-byte") \ + ENUM_ENTRY(TYPE_XMM256, "32-byte") \ ENUM_ENTRY(TYPE_XMM0, "Implicit use of XMM0") \ ENUM_ENTRY(TYPE_SEGMENTREG, "Segment register operand") \ ENUM_ENTRY(TYPE_DEBUGREG, "Debug register operand") \ Modified: llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp?rev=127644&r1=127643&r2=127644&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp (original) +++ llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp Mon Mar 14 20:23:15 2011 @@ -46,9 +46,11 @@ case IC_OPSIZE: return(inheritsFrom(child, IC_64BIT_OPSIZE)); case IC_XD: - return(inheritsFrom(child, IC_64BIT_XD)); + return(inheritsFrom(child, IC_64BIT_XD) || + inheritsFrom(child, IC_VEX_XD)); case IC_XS: - return(inheritsFrom(child, IC_64BIT_XS)); + return(inheritsFrom(child, IC_64BIT_XS) || + inheritsFrom(child, IC_VEX_XS)); case IC_64BIT_REXW: return(inheritsFrom(child, IC_64BIT_REXW_XS) || inheritsFrom(child, IC_64BIT_REXW_XD) || @@ -65,6 +67,35 @@ return false; case IC_64BIT_REXW_OPSIZE: return false; + case IC_VEX: + return(inheritsFrom(child, IC_VEX_XS) || + inheritsFrom(child, IC_VEX_XD) || + inheritsFrom(child, IC_VEX_L) || + inheritsFrom(child, IC_VEX_W) || + inheritsFrom(child, IC_VEX_OPSIZE)); + case IC_VEX_XS: + return(inheritsFrom(child, IC_VEX_L_XS) || + inheritsFrom(child, IC_VEX_W_XS)); + case IC_VEX_XD: + return(inheritsFrom(child, IC_VEX_L_XD) || + inheritsFrom(child, IC_VEX_W_XD)); + case IC_VEX_L: + return(inheritsFrom(child, IC_VEX_L_XS) || + inheritsFrom(child, IC_VEX_L_XD)); + case IC_VEX_L_XS: + return false; + case IC_VEX_L_XD: + return false; + case IC_VEX_W: + return(inheritsFrom(child, IC_VEX_W_XS) || + inheritsFrom(child, IC_VEX_W_XD) || + inheritsFrom(child, IC_VEX_W_OPSIZE)); + case IC_VEX_W_XS: + return false; + case IC_VEX_W_XD: + return false; + case IC_VEX_OPSIZE: + return inheritsFrom(child, IC_VEX_W_OPSIZE); default: return false; } @@ -461,7 +492,29 @@ for (index = 0; index < 256; ++index) { o.indent(i * 2); - if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) + if ((index & ATTR_VEXL) && (index & ATTR_OPSIZE)) + o << "IC_VEX_L_OPSIZE"; + else if ((index & ATTR_VEXL) && (index & ATTR_XD)) + o << "IC_VEX_L_XD"; + else if ((index & ATTR_VEXL) && (index & ATTR_XS)) + o << "IC_VEX_L_XS"; + else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) + o << "IC_VEX_W_OPSIZE"; + else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XD)) + o << "IC_VEX_W_XD"; + else if ((index & ATTR_VEX) && (index & ATTR_REXW) && (index & ATTR_XS)) + o << "IC_VEX_W_XS"; + else if (index & ATTR_VEXL) + o << "IC_VEX_L"; + else if ((index & ATTR_VEX) && (index & ATTR_REXW)) + o << "IC_VEX_W"; + else if ((index & ATTR_VEX) && (index & ATTR_OPSIZE)) + o << "IC_VEX_OPSIZE"; + else if ((index & ATTR_VEX) && (index & ATTR_XD)) + o << "IC_VEX_XD"; + else if ((index & ATTR_VEX) && (index & ATTR_XS)) + o << "IC_VEX_XS"; + else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) o << "IC_64BIT_REXW_XS"; else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) o << "IC_64BIT_REXW_XD"; @@ -484,6 +537,8 @@ o << "IC_XD"; else if (index & ATTR_OPSIZE) o << "IC_OPSIZE"; + else if (index & ATTR_VEX) + o << "IC_VEX"; else o << "IC"; Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp?rev=127644&r1=127643&r2=127644&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp (original) +++ llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp Mon Mar 14 20:23:15 2011 @@ -214,7 +214,9 @@ HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix"); HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix"); + HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix"); HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix"); + HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix"); HasLockPrefix = Rec->getValueAsBit("hasLockPrefix"); IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); @@ -224,7 +226,8 @@ Operands = &insn.Operands.OperandList; IsSSE = HasOpSizePrefix && (Name.find("16") == Name.npos); - HasFROperands = false; + HasFROperands = hasFROperands(); + HasVEX_LPrefix = has256BitOperands() || Rec->getValueAsBit("hasVEX_L"); ShouldBeEmitted = true; } @@ -248,7 +251,32 @@ InstructionContext RecognizableInstr::insnContext() const { InstructionContext insnContext; - if (Name.find("64") != Name.npos || HasREX_WPrefix) { + if (HasVEX_4VPrefix || HasVEXPrefix) { + if (HasOpSizePrefix && HasVEX_LPrefix) + insnContext = IC_VEX_L_OPSIZE; + else if (HasOpSizePrefix && HasVEX_WPrefix) + insnContext = IC_VEX_W_OPSIZE; + else if (HasOpSizePrefix) + insnContext = IC_VEX_OPSIZE; + else if (HasVEX_LPrefix && Prefix == X86Local::XS) + insnContext = IC_VEX_L_XS; + else if (HasVEX_LPrefix && Prefix == X86Local::XD) + insnContext = IC_VEX_L_XD; + else if (HasVEX_WPrefix && Prefix == X86Local::XS) + insnContext = IC_VEX_W_XS; + else if (HasVEX_WPrefix && Prefix == X86Local::XD) + insnContext = IC_VEX_W_XD; + else if (HasVEX_WPrefix) + insnContext = IC_VEX_W; + else if (HasVEX_LPrefix) + insnContext = IC_VEX_L; + else if (Prefix == X86Local::XD) + insnContext = IC_VEX_XD; + else if (Prefix == X86Local::XS) + insnContext = IC_VEX_XS; + else + insnContext = IC_VEX; + } else if (Name.find("64") != Name.npos || HasREX_WPrefix) { if (HasREX_WPrefix && HasOpSizePrefix) insnContext = IC_64BIT_REXW_OPSIZE; else if (HasOpSizePrefix) @@ -280,6 +308,10 @@ } RecognizableInstr::filter_ret RecognizableInstr::filter() const { + /////////////////// + // FILTER_STRONG + // + // Filter out intrinsics if (!Rec->isSubClassOf("X86Inst")) @@ -291,26 +323,71 @@ if (Form == X86Local::MRMInitReg) return FILTER_STRONG; + + + // TEMPORARY pending bug fixes - + if (Name.find("VMOVDQU") != Name.npos || + Name.find("VMOVDQA") != Name.npos || + Name.find("VROUND") != Name.npos) + return FILTER_STRONG; + + // Filter out artificial instructions + + if (Name.find("TAILJMP") != Name.npos || + Name.find("_Int") != Name.npos || + Name.find("_int") != Name.npos || + Name.find("Int_") != Name.npos || + Name.find("_NOREX") != Name.npos || + Name.find("_TC") != Name.npos || + Name.find("EH_RETURN") != Name.npos || + Name.find("V_SET") != Name.npos || + Name.find("LOCK_") != Name.npos || + Name.find("WIN") != Name.npos || + Name.find("_AVX") != Name.npos || + Name.find("2SDL") != Name.npos) + return FILTER_STRONG; + + // Filter out instructions with segment override prefixes. + // They're too messy to handle now and we'll special case them if needed. + + if (SegOvr) + return FILTER_STRONG; + + // Filter out instructions that can't be printed. + + if (AsmString.size() == 0) + return FILTER_STRONG; + + // Filter out instructions with subreg operands. + + if (AsmString.find("subreg") != AsmString.npos) + return FILTER_STRONG; + + ///////////////// + // FILTER_WEAK + // + + // Filter out instructions with a LOCK prefix; // prefer forms that do not have the prefix if (HasLockPrefix) return FILTER_WEAK; - - // Filter out artificial instructions - if (Name.find("TAILJMP") != Name.npos || - Name.find("_Int") != Name.npos || - Name.find("_int") != Name.npos || - Name.find("Int_") != Name.npos || - Name.find("_NOREX") != Name.npos || - Name.find("_TC") != Name.npos || - Name.find("EH_RETURN") != Name.npos || - Name.find("V_SET") != Name.npos || - Name.find("LOCK_") != Name.npos || - Name.find("WIN") != Name.npos) - return FILTER_STRONG; + // Filter out alternate forms of AVX instructions + if (Name.find("_alt") != Name.npos || + Name.find("XrYr") != Name.npos || + Name.find("r64r") != Name.npos || + Name.find("_64mr") != Name.npos || + Name.find("Xrr") != Name.npos || + Name.find("rr64") != Name.npos) + return FILTER_WEAK; + + if (Name == "VMASKMOVDQU64" || + Name == "VEXTRACTPSrr64" || + Name == "VMOVQd64rr" || + Name == "VMOVQs64rr") + return FILTER_WEAK; // Special cases. @@ -339,6 +416,7 @@ Name == "PUSH32i16" || Name == "PUSH64i16" || Name == "MOVPQI2QImr" || + Name == "VMOVPQI2QImr" || Name == "MOVSDmr" || Name == "MOVSDrm" || Name == "MOVSSmr" || @@ -349,22 +427,6 @@ Name == "CRC32r16") return FILTER_WEAK; - // Filter out instructions with segment override prefixes. - // They're too messy to handle now and we'll special case them if needed. - - if (SegOvr) - return FILTER_STRONG; - - // Filter out instructions that can't be printed. - - if (AsmString.size() == 0) - return FILTER_STRONG; - - // Filter out instructions with subreg operands. - - if (AsmString.find("subreg") != AsmString.npos) - return FILTER_STRONG; - if (HasFROperands && Name.find("MOV") != Name.npos && ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) || (Name.find("to") != Name.npos))) @@ -372,6 +434,33 @@ return FILTER_NORMAL; } + +bool RecognizableInstr::hasFROperands() const { + const std::vector &OperandList = *Operands; + unsigned numOperands = OperandList.size(); + + for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { + const std::string &recName = OperandList[operandIndex].Rec->getName(); + + if (recName.find("FR") != recName.npos) + return true; + } + return false; +} + +bool RecognizableInstr::has256BitOperands() const { + const std::vector &OperandList = *Operands; + unsigned numOperands = OperandList.size(); + + for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { + const std::string &recName = OperandList[operandIndex].Rec->getName(); + + if (!recName.compare("VR256") || !recName.compare("f256mem")) { + return true; + } + } + return false; +} void RecognizableInstr::handleOperand( bool optional, @@ -395,13 +484,13 @@ } const std::string &typeName = (*Operands)[operandIndex].Rec->getName(); - + Spec->operands[operandIndex].encoding = encodingFromString(typeName, HasOpSizePrefix); Spec->operands[operandIndex].type = typeFromString(typeName, - IsSSE, - HasREX_WPrefix, - HasOpSizePrefix); + IsSSE, + HasREX_WPrefix, + HasOpSizePrefix); ++operandIndex; ++physicalOperandIndex; @@ -530,31 +619,45 @@ case X86Local::MRMSrcReg: // Operand 1 is a register operand in the Reg/Opcode field. // Operand 2 is a register operand in the R/M field. + // - In AVX, there is a register operand in the VEX.vvvv field here - // Operand 3 (optional) is an immediate. - assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && - "Unexpected number of operands for MRMSrcRegFrm"); - HANDLE_OPERAND(roRegister) - HANDLE_OPERAND(rmRegister) if (HasVEX_4VPrefix) + assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && + "Unexpected number of operands for MRMSrcRegFrm with VEX_4V"); + else + assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && + "Unexpected number of operands for MRMSrcRegFrm"); + + HANDLE_OPERAND(roRegister) + + if (HasVEX_4VPrefix) // FIXME: In AVX, the register below becomes the one encoded // in ModRMVEX and the one above the one in the VEX.VVVV field - HANDLE_OPTIONAL(rmRegister) - else - HANDLE_OPTIONAL(immediate) + HANDLE_OPERAND(vvvvRegister) + + HANDLE_OPERAND(rmRegister) + HANDLE_OPTIONAL(immediate) break; case X86Local::MRMSrcMem: // Operand 1 is a register operand in the Reg/Opcode field. // Operand 2 is a memory operand (possibly SIB-extended) + // - In AVX, there is a register operand in the VEX.vvvv field here - // Operand 3 (optional) is an immediate. - assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && - "Unexpected number of operands for MRMSrcMemFrm"); + + if (HasVEX_4VPrefix) + assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && + "Unexpected number of operands for MRMSrcMemFrm with VEX_4V"); + else + assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && + "Unexpected number of operands for MRMSrcMemFrm"); + HANDLE_OPERAND(roRegister) if (HasVEX_4VPrefix) // FIXME: In AVX, the register below becomes the one encoded // in ModRMVEX and the one above the one in the VEX.VVVV field - HANDLE_OPTIONAL(rmRegister) + HANDLE_OPERAND(vvvvRegister) HANDLE_OPERAND(memory) HANDLE_OPTIONAL(immediate) @@ -569,8 +672,14 @@ case X86Local::MRM7r: // Operand 1 is a register operand in the R/M field. // Operand 2 (optional) is an immediate or relocation. - assert(numPhysicalOperands <= 2 && - "Unexpected number of operands for MRMnRFrm"); + if (HasVEX_4VPrefix) + assert(numPhysicalOperands <= 3 && + "Unexpected number of operands for MRMSrcMemFrm with VEX_4V"); + else + assert(numPhysicalOperands <= 2 && + "Unexpected number of operands for MRMnRFrm"); + if (HasVEX_4VPrefix) + HANDLE_OPERAND(vvvvRegister); HANDLE_OPTIONAL(rmRegister) HANDLE_OPTIONAL(relocation) break; @@ -854,6 +963,7 @@ TYPE("ssmem", TYPE_M32FP) TYPE("RST", TYPE_ST) TYPE("i128mem", TYPE_M128) + TYPE("i256mem", TYPE_M256) TYPE("i64i32imm_pcrel", TYPE_REL64) TYPE("i16imm_pcrel", TYPE_REL16) TYPE("i32imm_pcrel", TYPE_REL32) @@ -878,6 +988,7 @@ TYPE("offset16", TYPE_MOFFS16) TYPE("offset32", TYPE_MOFFS32) TYPE("offset64", TYPE_MOFFS64) + TYPE("VR256", TYPE_XMM256) errs() << "Unhandled type string " << s << "\n"; llvm_unreachable("Unhandled type string"); } @@ -900,6 +1011,10 @@ ENCODING("i64i32imm", ENCODING_ID) ENCODING("i64i8imm", ENCODING_IB) ENCODING("i8imm", ENCODING_IB) + // This is not a typo. Instructions like BLENDVPD put + // register IDs in 8-bit immediates nowadays. + ENCODING("VR256", ENCODING_IB) + ENCODING("VR128", ENCODING_IB) errs() << "Unhandled immediate encoding " << s << "\n"; llvm_unreachable("Unhandled immediate encoding"); } @@ -915,6 +1030,7 @@ ENCODING("FR64", ENCODING_RM) ENCODING("FR32", ENCODING_RM) ENCODING("VR64", ENCODING_RM) + ENCODING("VR256", ENCODING_RM) errs() << "Unhandled R/M register encoding " << s << "\n"; llvm_unreachable("Unhandled R/M register encoding"); } @@ -933,10 +1049,22 @@ ENCODING("SEGMENT_REG", ENCODING_REG) ENCODING("DEBUG_REG", ENCODING_REG) ENCODING("CONTROL_REG", ENCODING_REG) + ENCODING("VR256", ENCODING_REG) errs() << "Unhandled reg/opcode register encoding " << s << "\n"; llvm_unreachable("Unhandled reg/opcode register encoding"); } +OperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString + (const std::string &s, + bool hasOpSizePrefix) { + ENCODING("FR32", ENCODING_VVVV) + ENCODING("FR64", ENCODING_VVVV) + ENCODING("VR128", ENCODING_VVVV) + ENCODING("VR256", ENCODING_VVVV) + errs() << "Unhandled VEX.vvvv register encoding " << s << "\n"; + llvm_unreachable("Unhandled VEX.vvvv register encoding"); +} + OperandEncoding RecognizableInstr::memoryEncodingFromString (const std::string &s, bool hasOpSizePrefix) { @@ -951,6 +1079,7 @@ ENCODING("f64mem", ENCODING_RM) ENCODING("f32mem", ENCODING_RM) ENCODING("i128mem", ENCODING_RM) + ENCODING("i256mem", ENCODING_RM) ENCODING("f80mem", ENCODING_RM) ENCODING("lea32mem", ENCODING_RM) ENCODING("lea64_32mem", ENCODING_RM) Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.h?rev=127644&r1=127643&r2=127644&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/X86RecognizableInstr.h (original) +++ llvm/trunk/utils/TableGen/X86RecognizableInstr.h Mon Mar 14 20:23:15 2011 @@ -52,8 +52,14 @@ bool HasOpSizePrefix; /// The hasREX_WPrefix field from the record bool HasREX_WPrefix; + /// The hasVEXPrefix field from the record + bool HasVEXPrefix; /// The hasVEX_4VPrefix field from the record bool HasVEX_4VPrefix; + /// The hasVEX_WPrefix field from the record + bool HasVEX_WPrefix; + /// Inferred from the operands; indicates whether the L bit in the VEX prefix is set + bool HasVEX_LPrefix; /// The hasLockPrefix field from the record bool HasLockPrefix; /// The isCodeGenOnly filed from the record @@ -96,7 +102,7 @@ // error if it conflcits with any other FILTER_NORMAL // instruction }; - + /// filter - Determines whether the instruction should be decodable. Some /// instructions are pure intrinsics and use unencodable operands; many /// synthetic instructions are duplicates of other instructions; other @@ -106,6 +112,12 @@ /// /// @return - The degree of filtering to be applied (see filter_ret). filter_ret filter() const; + + /// hasFROperands - Returns true if any operand is a FR operand. + bool hasFROperands() const; + + /// has256BitOperands - Returns true if any operand is a 256-bit SSE operand. + bool has256BitOperands() const; /// typeFromString - Translates an operand type from the string provided in /// the LLVM tables to an OperandType for use in the operand specifier. @@ -155,6 +167,8 @@ bool hasOpSizePrefix); static OperandEncoding opcodeModifierEncodingFromString(const std::string &s, bool hasOpSizePrefix); + static OperandEncoding vvvvRegisterEncodingFromString(const std::string &s, + bool HasOpSizePrefix); /// handleOperand - Converts a single operand from the LLVM table format to /// the emitted table format, handling any duplicate operands it encounters From aggarwa4 at illinois.edu Mon Mar 14 20:27:13 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 15 Mar 2011 01:27:13 -0000 Subject: [llvm-commits] [poolalloc] r127645 - /poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Message-ID: <20110315012713.3D2572A6C12C@llvm.org> Author: aggarwa4 Date: Mon Mar 14 20:27:13 2011 New Revision: 127645 URL: http://llvm.org/viewvc/llvm-project?rev=127645&view=rev Log: A function to help identify malloc wrappers. Added: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Added: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp?rev=127645&view=auto ============================================================================== --- poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp (added) +++ poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Mon Mar 14 20:27:13 2011 @@ -0,0 +1,143 @@ +//===-- VarArgsFunc.cpp - Simplify calls to bitcasted const funcs --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#define DEBUG_TYPE "allocator-identify" + +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Debug.h" + +#include +#include +#include +#include + +using namespace llvm; + + +namespace { + static bool flowsFrom(Value *Dest,Value *Src) { + if(Dest == Src) + return true; + if(ReturnInst *Ret = dyn_cast(Dest)) { + return flowsFrom(Ret->getReturnValue(), Src); + } + if(PHINode *PN = dyn_cast(Dest)) { + bool ret = true; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + ret = ret && flowsFrom(PN->getIncomingValue(i), Src); + } + return ret; + } + if(BitCastInst *BI = dyn_cast(Dest)) { + return flowsFrom(BI->getOperand(0), Src); + } + if(isa(Dest)) + return true; + return false; + } + static bool isNotStored(Value *V) { + // check that V is not stroed to a location taht is accessible outside this fn + + for(Value::use_iterator ui = V->use_begin(), ue = V->use_end(); + ui != ue; ++ui) { + if(isa(ui)) + return false; + if(isa(ui)) + continue; + if(isa(ui)) + continue; + if(BitCastInst *BI = dyn_cast(ui)) + if(isNotStored(BI)) + continue; + else + return false; + if(PHINode *PN = dyn_cast(ui)) + if(isNotStored(PN)) + continue; + else + return false; + + //ui->dump(); + return false; + } + return true; + } + class AllocIdentify : public ModulePass { + protected: + std::set allocators; + public: + static char ID; + AllocIdentify() : ModulePass(&ID) {} + bool runOnModule(Module& M) { + + allocators.insert("malloc"); + allocators.insert("calloc"); + allocators.insert("realloc"); + allocators.insert("memset"); + + bool changed; + do { + changed = false; + std::set TempAllocators; + TempAllocators.insert( allocators.begin(), allocators.end()); + std::set::iterator it; + for(it = TempAllocators.begin(); it != TempAllocators.end(); ++it) { + Function* F = M.getFunction(*it); + if(!F) + continue; + for(Value::use_iterator ui = F->use_begin(), ue = F->use_end(); + ui != ue; ++ui) { + // iterate though all calls to malloc + if (CallInst* CI = dyn_cast(ui)) { + // The function that calls malloc could be a potential allocator + Function *WrapperF = CI->getParent()->getParent(); + if(WrapperF->doesNotReturn()) + continue; + if(!(WrapperF->getReturnType()->isPointerTy())) + continue; + bool isWrapper = true; + for (Function::iterator BBI = WrapperF->begin(), E = WrapperF->end(); BBI != E; ) { + BasicBlock &BB = *BBI++; + + // Only look at return blocks. + ReturnInst *Ret = dyn_cast(BB.getTerminator()); + if (Ret == 0) continue; + + //check for ALL return values + if(flowsFrom(Ret, CI)) { + continue; + } else { + isWrapper = false; + break; + } + // if true for all return add to list of allocators + } + if(isWrapper) + isWrapper = isWrapper && isNotStored(CI); + if(isWrapper) { + errs() << WrapperF->getNameStr() << "\n"; + changed = (allocators.find(WrapperF->getName()) == allocators.end()); + allocators.insert(WrapperF->getName()); + } + } + } + } + } while(changed); + return false; + } + }; +} + +char AllocIdentify::ID = 0; +static RegisterPass +X("alloc-identify", "Identify allocator wrapper functions"); From scallanan at apple.com Mon Mar 14 20:28:15 2011 From: scallanan at apple.com (Sean Callanan) Date: Tue, 15 Mar 2011 01:28:15 -0000 Subject: [llvm-commits] [llvm] r127646 - in /llvm/trunk/lib/Target/X86: X86InstrFormats.td X86InstrSSE.td Message-ID: <20110315012816.0D4BA2A6C12C@llvm.org> Author: spyffe Date: Mon Mar 14 20:28:15 2011 New Revision: 127646 URL: http://llvm.org/viewvc/llvm-project?rev=127646&view=rev Log: Enabled disassembler support for AVX instructions in the instruction tables and fixed a few bugs that were causing decode conflicts. Rudimentary tests are coming up in the next patch. Modified: llvm/trunk/lib/Target/X86/X86InstrFormats.td llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86InstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFormats.td?rev=127646&r1=127645&r2=127646&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFormats.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFormats.td Mon Mar 14 20:28:15 2011 @@ -319,7 +319,7 @@ Requires<[HasAVX]>; class VPSI o, Format F, dag outs, dag ins, string asm, list pattern> - : I, + : I, TB, Requires<[HasAVX]>; // SSE2 Instruction Templates: @@ -353,7 +353,7 @@ Requires<[HasAVX]>; class VPDI o, Format F, dag outs, dag ins, string asm, list pattern> - : I, + : I, TB, OpSize, Requires<[HasAVX]>; // SSE3 Instruction Templates: Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=127646&r1=127645&r2=127646&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon Mar 14 20:28:15 2011 @@ -135,7 +135,7 @@ // is used instead. Register-to-register movss/movsd is not modeled as an // INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable // in terms of a copy, and just mentioned, we don't use movss/movsd for copies. -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVSSrr : sse12_move_rr, XS, VEX_4V; def VMOVSDrr : sse12_move_rr; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src), "movss\t{$src, $dst|$dst, $src}", [(store FR32:$src, addr:$dst)]>, XS, VEX; @@ -251,7 +251,7 @@ [(set RC:$dst, (ld_frag addr:$src))], d>; } -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32, "movaps", SSEPackedSingle>, VEX; defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64, @@ -279,7 +279,7 @@ defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64, "movupd", SSEPackedDouble, 0>, TB, OpSize; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src), "movaps\t{$src, $dst|$dst, $src}", [(alignedstore (v4f32 VR128:$src), addr:$dst)]>, VEX; @@ -328,7 +328,7 @@ [(store (v2f64 VR128:$src), addr:$dst)]>; // Intrinsic forms of MOVUPS/D load and store -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { let canFoldAsLoad = 1, isReMaterializable = 1 in def VMOVUPSrm_Int : VPSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), @@ -382,7 +382,7 @@ SSEPackedDouble>, TB, OpSize; } -let isAsmParserOnly = 1, AddedComplexity = 20 in { +let isAsmParserOnly = 0, AddedComplexity = 20 in { defm VMOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp", "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V; defm VMOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp", @@ -395,7 +395,7 @@ "\t{$src2, $dst|$dst, $src2}">; } -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src), "movlps\t{$src, $dst|$dst, $src}", [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)), @@ -416,7 +416,7 @@ // v2f64 extract element 1 is always custom lowered to unpack high to low // and extract element 0 so the non-store version isn't too horrible. -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src), "movhps\t{$src, $dst|$dst, $src}", [(store (f64 (vector_extract @@ -441,7 +441,7 @@ (v2f64 (unpckh VR128:$src, (undef))), (iPTR 0))), addr:$dst)]>; -let isAsmParserOnly = 1, AddedComplexity = 20 in { +let isAsmParserOnly = 0, AddedComplexity = 20 in { def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}", @@ -516,7 +516,7 @@ !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>; } -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm VCVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32, "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX; defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32, @@ -591,7 +591,7 @@ [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))]>; } -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm Int_VCVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si, f32mem, load, "cvtss2si">, XS, VEX; defm Int_VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, @@ -622,7 +622,7 @@ f128mem, load, "cvtsd2si{q}">, XD, REX_W; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128, int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss", 0>, XS, VEX_4V; defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128, @@ -653,7 +653,7 @@ /// SSE 1 Only // Aliases for intrinsics -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si, f32mem, load, "cvttss2si">, XS, VEX; defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64, @@ -676,7 +676,7 @@ int_x86_sse2_cvttsd2si64, f128mem, load, "cvttsd2si{q}">, XD, REX_W; -let isAsmParserOnly = 1, Pattern = [] in { +let isAsmParserOnly = 0, Pattern = [] in { defm VCVTSS2SI : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load, "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS, VEX; defm VCVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load, @@ -702,7 +702,7 @@ /// SSE 2 Only // Convert scalar double to scalar single -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VCVTSD2SSrr : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src1, FR64:$src2), "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, @@ -723,7 +723,7 @@ [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD, Requires<[HasSSE2, OptForSize]>; -let isAsmParserOnly = 1 in +let isAsmParserOnly = 0 in defm Int_VCVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128, int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss", 0>, XS, VEX_4V; @@ -732,7 +732,7 @@ int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss">, XS; // Convert scalar single to scalar double -let isAsmParserOnly = 1 in { // SSE2 instructions with XS prefix +let isAsmParserOnly = 0 in { // SSE2 instructions with XS prefix def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src1, FR32:$src2), "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}", @@ -754,7 +754,7 @@ [(set FR64:$dst, (extloadf32 addr:$src))]>, XS, Requires<[HasSSE2, OptForSize]>; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}", @@ -788,7 +788,7 @@ Requires<[HasSSE2, OptForSpeed]>; // Convert doubleword to packed single/double fp -let isAsmParserOnly = 1 in { // SSE2 instructions without OpSize prefix +let isAsmParserOnly = 0 in { // SSE2 instructions without OpSize prefix def Int_VCVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "vcvtdq2ps\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>, @@ -810,7 +810,7 @@ TB, Requires<[HasSSE2]>; // FIXME: why the non-intrinsic version is described as SSE3? -let isAsmParserOnly = 1 in { // SSE2 instructions with XS prefix +let isAsmParserOnly = 0 in { // SSE2 instructions with XS prefix def Int_VCVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "vcvtdq2pd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>, @@ -833,7 +833,7 @@ // Convert packed single/double fp to doubleword -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX; def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), @@ -848,7 +848,7 @@ def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), "cvtps2dq\t{$src, $dst|$dst, $src}", []>; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def Int_VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "cvtps2dq\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>, @@ -867,7 +867,7 @@ [(set VR128:$dst, (int_x86_sse2_cvtps2dq (memop addr:$src)))]>; -let isAsmParserOnly = 1 in { // SSE2 packed instructions with XD prefix +let isAsmParserOnly = 0 in { // SSE2 packed instructions with XD prefix def Int_VCVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "vcvtpd2dq\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>, @@ -890,7 +890,7 @@ // Convert with truncation packed single/double fp to doubleword -let isAsmParserOnly = 1 in { // SSE2 packed instructions with XS prefix +let isAsmParserOnly = 0 in { // SSE2 packed instructions with XS prefix def VCVTTPS2DQrr : VSSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX; def VCVTTPS2DQrm : VSSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), @@ -910,7 +910,7 @@ (int_x86_sse2_cvttps2dq (memop addr:$src)))]>; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def Int_VCVTTPS2DQrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "vcvttps2dq\t{$src, $dst|$dst, $src}", [(set VR128:$dst, @@ -923,7 +923,7 @@ XS, VEX, Requires<[HasAVX]>; } -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def Int_VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "cvttpd2dq\t{$src, $dst|$dst, $src}", @@ -943,7 +943,7 @@ [(set VR128:$dst, (int_x86_sse2_cvttpd2dq (memop addr:$src)))]>; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { // The assembler can recognize rr 256-bit instructions by seeing a ymm // register, but the same isn't true when using memory operands instead. // Provide other assembly rr and rm forms to address this explicitly. @@ -966,7 +966,7 @@ } // Convert packed single to packed double -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { // SSE2 instructions without OpSize prefix def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, VEX; @@ -982,7 +982,7 @@ def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src), "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def Int_VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "vcvtps2pd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>, @@ -1004,7 +1004,7 @@ TB, Requires<[HasSSE2]>; // Convert packed double to packed single -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { // The assembler can recognize rr 256-bit instructions by seeing a ymm // register, but the same isn't true when using memory operands instead. // Provide other assembly rr and rm forms to address this explicitly. @@ -1031,7 +1031,7 @@ "cvtpd2ps\t{$src, $dst|$dst, $src}", []>; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def Int_VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "cvtpd2ps\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>; @@ -1089,26 +1089,27 @@ // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions multiclass sse12_cmp_scalar { - def rr : SIi8<0xC2, MRMSrcReg, - (outs RC:$dst), (ins RC:$src1, RC:$src, SSECC:$cc), - asm, []>; - let mayLoad = 1 in - def rm : SIi8<0xC2, MRMSrcMem, - (outs RC:$dst), (ins RC:$src1, x86memop:$src, SSECC:$cc), - asm, []>; - // Accept explicit immediate argument form instead of comparison code. let isAsmParserOnly = 1 in { - def rr_alt : SIi8<0xC2, MRMSrcReg, - (outs RC:$dst), (ins RC:$src1, RC:$src, i8imm:$src2), - asm_alt, []>; + def rr : SIi8<0xC2, MRMSrcReg, + (outs RC:$dst), (ins RC:$src1, RC:$src, SSECC:$cc), + asm, []>; let mayLoad = 1 in - def rm_alt : SIi8<0xC2, MRMSrcMem, - (outs RC:$dst), (ins RC:$src1, x86memop:$src, i8imm:$src2), - asm_alt, []>; + def rm : SIi8<0xC2, MRMSrcMem, + (outs RC:$dst), (ins RC:$src1, x86memop:$src, SSECC:$cc), + asm, []>; } + + // Accept explicit immediate argument form instead of comparison code. + def rr_alt : SIi8<0xC2, MRMSrcReg, + (outs RC:$dst), (ins RC:$src1, RC:$src, i8imm:$src2), + asm_alt, []>; + let mayLoad = 1 in + def rm_alt : SIi8<0xC2, MRMSrcMem, + (outs RC:$dst), (ins RC:$src1, x86memop:$src, i8imm:$src2), + asm_alt, []>; } -let neverHasSideEffects = 1, isAsmParserOnly = 1 in { +let neverHasSideEffects = 1, isAsmParserOnly = 0 in { defm VCMPSS : sse12_cmp_scalar, @@ -1141,7 +1142,7 @@ } // Aliases to match intrinsics which expect XMM operand(s). -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm Int_VCMPSS : sse12_cmp_scalar_int, XS, VEX_4V; @@ -1171,7 +1172,7 @@ } let Defs = [EFLAGS] in { - let isAsmParserOnly = 1 in { + let isAsmParserOnly = 0 in { defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32, "ucomiss", SSEPackedSingle>, VEX; defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64, @@ -1220,24 +1221,25 @@ multiclass sse12_cmp_packed { - def rri : PIi8<0xC2, MRMSrcReg, - (outs RC:$dst), (ins RC:$src1, RC:$src, SSECC:$cc), asm, - [(set RC:$dst, (Int RC:$src1, RC:$src, imm:$cc))], d>; - def rmi : PIi8<0xC2, MRMSrcMem, - (outs RC:$dst), (ins RC:$src1, f128mem:$src, SSECC:$cc), asm, - [(set RC:$dst, (Int RC:$src1, (memop addr:$src), imm:$cc))], d>; - // Accept explicit immediate argument form instead of comparison code. let isAsmParserOnly = 1 in { - def rri_alt : PIi8<0xC2, MRMSrcReg, - (outs RC:$dst), (ins RC:$src1, RC:$src, i8imm:$src2), - asm_alt, [], d>; - def rmi_alt : PIi8<0xC2, MRMSrcMem, - (outs RC:$dst), (ins RC:$src1, f128mem:$src, i8imm:$src2), - asm_alt, [], d>; + def rri : PIi8<0xC2, MRMSrcReg, + (outs RC:$dst), (ins RC:$src1, RC:$src, SSECC:$cc), asm, + [(set RC:$dst, (Int RC:$src1, RC:$src, imm:$cc))], d>; + def rmi : PIi8<0xC2, MRMSrcMem, + (outs RC:$dst), (ins RC:$src1, f128mem:$src, SSECC:$cc), asm, + [(set RC:$dst, (Int RC:$src1, (memop addr:$src), imm:$cc))], d>; } + + // Accept explicit immediate argument form instead of comparison code. + def rri_alt : PIi8<0xC2, MRMSrcReg, + (outs RC:$dst), (ins RC:$src1, RC:$src, i8imm:$src2), + asm_alt, [], d>; + def rmi_alt : PIi8<0xC2, MRMSrcMem, + (outs RC:$dst), (ins RC:$src1, f128mem:$src, i8imm:$src2), + asm_alt, [], d>; } -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm VCMPPS : sse12_cmp_packed; } -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm VSHUFPS : sse12_shuffle, VEX_4V; + memopv4f32, SSEPackedSingle>, TB, VEX_4V; defm VSHUFPSY : sse12_shuffle, VEX_4V; + memopv8f32, SSEPackedSingle>, TB, VEX_4V; defm VSHUFPD : sse12_shuffle, OpSize, VEX_4V; + memopv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V; defm VSHUFPDY : sse12_shuffle, OpSize, VEX_4V; + memopv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V; } let Constraints = "$src1 = $dst" in { @@ -1340,7 +1342,7 @@ } let AddedComplexity = 10 in { - let isAsmParserOnly = 1 in { + let isAsmParserOnly = 0 in { defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32, VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}", SSEPackedSingle>, VEX_4V; @@ -1404,7 +1406,7 @@ defm MOVMSKPD : sse12_extr_sign_mask, TB, OpSize; -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm VMOVMSKPS : sse12_extr_sign_mask, VEX; defm VMOVMSKPD : sse12_extr_sign_mask opc, string OpcodeStr, SDNode OpNode> { - let isAsmParserOnly = 1 in { + let isAsmParserOnly = 0 in { defm V#NAME#PS : sse12_fp_packed, VEX_4V; @@ -1514,7 +1516,7 @@ multiclass sse12_fp_packed_logical opc, string OpcodeStr, SDNode OpNode, int HasPat = 0, list> Pattern = []> { - let isAsmParserOnly = 1, Pattern = [] in { + let isAsmParserOnly = 0, Pattern = [] in { defm V#NAME#PS : sse12_fp_packed_logical_rm opc, string OpcodeStr> { defm PSY : sse12_fp_packed_logical_rm, VEX_4V; @@ -1667,7 +1669,7 @@ } // Binary Arithmetic instructions -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>, basic_sse12_fp_binop_s_int<0x58, "add", 0>, basic_sse12_fp_binop_p<0x58, "add", fadd, 0>, @@ -1899,7 +1901,7 @@ [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { // Square root. defm VSQRT : sse1_fp_unop_s_avx<0x51, "vsqrt", fsqrt, int_x86_sse_sqrt_ss>, sse2_fp_unop_s_avx<0x51, "vsqrt", fsqrt, int_x86_sse2_sqrt_sd>, @@ -1955,7 +1957,7 @@ // SSE 1 & 2 - Non-temporal stores //===----------------------------------------------------------------------===// -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVNTPSmr_Int : VPSI<0x2B, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src), "movntps\t{$src, $dst|$dst, $src}", @@ -2138,7 +2140,7 @@ // SSE 1 & 2 - Load/Store XCSR register //===----------------------------------------------------------------------===// -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src), "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX; def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst), @@ -2156,7 +2158,7 @@ let ExeDomain = SSEPackedInt in { // SSE integer instructions -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { let neverHasSideEffects = 1 in { def VMOVDQArr : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movdqa\t{$src, $dst|$dst, $src}", []>, VEX; @@ -2226,7 +2228,7 @@ } // Intrinsic forms of MOVDQU load and store -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { let canFoldAsLoad = 1 in def VMOVDQUrm_Int : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "vmovdqu\t{$src, $dst|$dst, $src}", @@ -2347,7 +2349,7 @@ // 128-bit Integer Arithmetic -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPADDB : PDI_binop_rm<0xFC, "vpaddb", add, v16i8, 1, 0 /*3addr*/>, VEX_4V; defm VPADDW : PDI_binop_rm<0xFD, "vpaddw", add, v8i16, 1, 0>, VEX_4V; defm VPADDD : PDI_binop_rm<0xFE, "vpaddd", add, v4i32, 1, 0>, VEX_4V; @@ -2437,7 +2439,7 @@ // SSE2 - Packed Integer Logical Instructions //===---------------------------------------------------------------------===// -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw", int_x86_sse2_psll_w, int_x86_sse2_pslli_w, 0>, VEX_4V; @@ -2584,7 +2586,7 @@ // SSE2 - Packed Integer Comparison Instructions //===---------------------------------------------------------------------===// -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPCMPEQB : PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_sse2_pcmpeq_b, 1, 0>, VEX_4V; defm VPCMPEQW : PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_sse2_pcmpeq_w, 1, @@ -2638,7 +2640,7 @@ // SSE2 - Packed Integer Pack Instructions //===---------------------------------------------------------------------===// -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128, 0, 0>, VEX_4V; defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128, @@ -2676,7 +2678,7 @@ } } // ExeDomain = SSEPackedInt -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { let AddedComplexity = 5 in defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, pshufd, bc_v4i32>, OpSize, VEX; @@ -2724,7 +2726,7 @@ addr:$src2))))]>; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPUNPCKLBW : sse2_unpack<0x60, "vpunpcklbw", v16i8, unpckl, bc_v16i8, 0>, VEX_4V; defm VPUNPCKLWD : sse2_unpack<0x61, "vpunpcklwd", v8i16, unpckl, bc_v8i16, @@ -2834,7 +2836,7 @@ } // Extract -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in def VPEXTRWri : Ii8<0xC5, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2), "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}", @@ -2847,7 +2849,7 @@ imm:$src2))]>; // Insert -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPINSRW : sse2_pinsrw<0>, OpSize, VEX_4V; def VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, GR64:$src2, i32i8imm:$src3), @@ -2866,7 +2868,7 @@ let ExeDomain = SSEPackedInt in { -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VPMOVMSKBrr : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src), "pmovmskb\t{$src, $dst|$dst, $src}", [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX; @@ -2885,7 +2887,7 @@ let ExeDomain = SSEPackedInt in { -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { let Uses = [EDI] in def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask), @@ -2914,7 +2916,7 @@ //===---------------------------------------------------------------------===// // Move Int Doubleword to Packed Double Int -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src), "movd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, @@ -2943,7 +2945,7 @@ // Move Int Doubleword to Single Scalar -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVDI2SSrr : VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src), "movd\t{$src, $dst|$dst, $src}", [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX; @@ -2962,7 +2964,7 @@ [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>; // Move Packed Doubleword Int to Packed Double Int -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVPDI2DIrr : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src), "movd\t{$src, $dst|$dst, $src}", [(set GR32:$dst, (vector_extract (v4i32 VR128:$src), @@ -2998,7 +3000,7 @@ [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>; // Move Scalar Single to Double Int -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVSS2DIrr : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src), "movd\t{$src, $dst|$dst, $src}", [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX; @@ -3014,7 +3016,7 @@ [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>; // movd / movq to XMM register zero-extends -let AddedComplexity = 15, isAsmParserOnly = 1 in { +let AddedComplexity = 15, isAsmParserOnly = 0 in { def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src), "movd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (v4i32 (X86vzmovl @@ -3038,7 +3040,7 @@ } let AddedComplexity = 20 in { -let isAsmParserOnly = 1 in +let isAsmParserOnly = 0 in def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src), "movd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, @@ -3064,7 +3066,7 @@ //===---------------------------------------------------------------------===// // Move Quadword Int to Packed Quadword Int -let isAsmParserOnly = 1 in +let isAsmParserOnly = 0 in def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src), "vmovq\t{$src, $dst|$dst, $src}", [(set VR128:$dst, @@ -3077,7 +3079,7 @@ Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix // Move Packed Quadword Int to Quadword Int -let isAsmParserOnly = 1 in +let isAsmParserOnly = 0 in def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src), "movq\t{$src, $dst|$dst, $src}", [(store (i64 (vector_extract (v2i64 VR128:$src), @@ -3091,7 +3093,7 @@ (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>; // Store / copy lower 64-bits of a XMM register. -let isAsmParserOnly = 1 in +let isAsmParserOnly = 0 in def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src), "movq\t{$src, $dst|$dst, $src}", [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX; @@ -3099,7 +3101,7 @@ "movq\t{$src, $dst|$dst, $src}", [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>; -let AddedComplexity = 20, isAsmParserOnly = 1 in +let AddedComplexity = 20, isAsmParserOnly = 0 in def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src), "vmovq\t{$src, $dst|$dst, $src}", [(set VR128:$dst, @@ -3124,7 +3126,7 @@ // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in // IA32 document. movq xmm1, xmm2 does clear the high bits. -let isAsmParserOnly = 1, AddedComplexity = 15 in +let isAsmParserOnly = 0, AddedComplexity = 15 in def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "vmovq\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>, @@ -3135,7 +3137,7 @@ [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>, XS, Requires<[HasSSE2]>; -let AddedComplexity = 20, isAsmParserOnly = 1 in +let AddedComplexity = 20, isAsmParserOnly = 0 in def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "vmovq\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (v2i64 (X86vzmovl @@ -3153,7 +3155,7 @@ } // Instructions to match in the assembler -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W; def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src), @@ -3167,7 +3169,7 @@ // xr = XMM register // xm = mem64 -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS; def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), @@ -3209,7 +3211,7 @@ //===---------------------------------------------------------------------===// // Convert Packed Double FP to Packed DW Integers -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { // The assembler can recognize rr 256-bit instructions by seeing a ymm // register, but the same isn't true when using memory operands instead. // Provide other assembly rr and rm forms to address this explicitly. @@ -3237,7 +3239,7 @@ "cvtpd2dq\t{$src, $dst|$dst, $src}", []>; // Convert Packed DW Integers to Packed Double FP -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { def VCVTDQ2PDrm : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX; def VCVTDQ2PDrr : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), @@ -3288,7 +3290,7 @@ !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { // FIXME: Merge above classes when we have patterns for the ymm version defm VMOVSHDUP : sse3_replicate_sfp<0x16, movshdup, "vmovshdup">, VEX; defm VMOVSLDUP : sse3_replicate_sfp<0x12, movsldup, "vmovsldup">, VEX; @@ -3319,7 +3321,7 @@ []>; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { // FIXME: Merge above classes when we have patterns for the ymm version defm VMOVDDUP : sse3_replicate_dfp<"vmovddup">, VEX; defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX; @@ -3327,7 +3329,7 @@ defm MOVDDUP : sse3_replicate_dfp<"movddup">; // Move Unaligned Integer -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "vlddqu\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX; @@ -3391,21 +3393,21 @@ [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>; } -let isAsmParserOnly = 1, Predicates = [HasAVX], +let isAsmParserOnly = 0, Predicates = [HasAVX], ExeDomain = SSEPackedDouble in { defm VADDSUBPS : sse3_addsub, XD, VEX_4V; + f128mem, 0>, TB, XD, VEX_4V; defm VADDSUBPD : sse3_addsub, OpSize, VEX_4V; + f128mem, 0>, TB, OpSize, VEX_4V; defm VADDSUBPSY : sse3_addsub, XD, VEX_4V; + f256mem, 0>, TB, XD, VEX_4V; defm VADDSUBPDY : sse3_addsub, OpSize, VEX_4V; + f256mem, 0>, TB, OpSize, VEX_4V; } let Constraints = "$src1 = $dst", Predicates = [HasSSE3], ExeDomain = SSEPackedDouble in { defm ADDSUBPS : sse3_addsub, XD; + f128mem>, TB, XD; defm ADDSUBPD : sse3_addsub, TB, OpSize; } @@ -3444,7 +3446,7 @@ [(set RC:$dst, (vt (IntId RC:$src1, (memop addr:$src2))))]>; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VHADDPS : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem, int_x86_sse3_hadd_ps, 0>, VEX_4V; defm VHADDPD : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem, @@ -3496,7 +3498,7 @@ (bitconvert (mem_frag128 addr:$src))))]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPABSB : SS3I_unop_rm_int<0x1C, "vpabsb", memopv16i8, int_x86_ssse3_pabs_b_128>, VEX; defm VPABSW : SS3I_unop_rm_int<0x1D, "vpabsw", memopv8i16, @@ -3538,7 +3540,7 @@ (bitconvert (memopv16i8 addr:$src2))))]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { let isCommutable = 0 in { defm VPHADDW : SS3I_binop_rm_int<0x01, "vphaddw", memopv8i16, int_x86_ssse3_phadd_w_128, 0>, VEX_4V; @@ -3630,7 +3632,7 @@ []>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V; let Constraints = "$src1 = $dst" in defm PALIGN : ssse3_palign<"palignr">; @@ -3985,7 +3987,7 @@ OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>, VEX; defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>, @@ -4051,7 +4053,7 @@ OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>, VEX; defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>, @@ -4092,7 +4094,7 @@ OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>, VEX; defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>, @@ -4134,7 +4136,7 @@ // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst) } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX; def VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst), (ins VR128:$src1, i32i8imm:$src2), @@ -4156,7 +4158,7 @@ // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst) } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX; defm PEXTRW : SS41I_extract16<0x15, "pextrw">; @@ -4178,7 +4180,7 @@ addr:$dst)]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX; defm PEXTRD : SS41I_extract32<0x16, "pextrd">; @@ -4199,7 +4201,7 @@ addr:$dst)]>, OpSize, REX_W; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W; defm PEXTRQ : SS41I_extract64<0x16, "pextrq">; @@ -4222,7 +4224,7 @@ addr:$dst)]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX; def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst), (ins VR128:$src1, i32i8imm:$src2), @@ -4262,7 +4264,7 @@ imm:$src3))]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V; let Constraints = "$src1 = $dst" in defm PINSRB : SS41I_insert8<0x20, "pinsrb">; @@ -4288,7 +4290,7 @@ imm:$src3)))]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V; let Constraints = "$src1 = $dst" in defm PINSRD : SS41I_insert32<0x22, "pinsrd">; @@ -4314,7 +4316,7 @@ imm:$src3)))]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W; let Constraints = "$src1 = $dst" in defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W; @@ -4347,7 +4349,7 @@ let Constraints = "$src1 = $dst" in defm INSERTPS : SS41I_insertf32<0x21, "insertps">; -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V; def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3), @@ -4517,7 +4519,7 @@ } // FP round - roundss, roundps, roundsd, roundpd -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { // Intrinsic form defm VROUND : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128, memopv4f32, memopv2f64, @@ -4552,7 +4554,7 @@ // ptest instruction we'll lower to this in X86ISelLowering primarily from // the intel intrinsic that corresponds to this. -let Defs = [EFLAGS], isAsmParserOnly = 1, Predicates = [HasAVX] in { +let Defs = [EFLAGS], isAsmParserOnly = 0, Predicates = [HasAVX] in { def VPTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), "vptest\t{$src2, $src1|$src1, $src2}", [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>, @@ -4595,7 +4597,7 @@ OpSize, VEX; } -let Defs = [EFLAGS], isAsmParserOnly = 1, Predicates = [HasAVX] in { +let Defs = [EFLAGS], isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VTESTPS : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>; defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>; defm VTESTPD : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>; @@ -4644,7 +4646,7 @@ (bitconvert (memopv8i16 addr:$src))))]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw", int_x86_sse41_phminposuw>, VEX; defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw", @@ -4670,7 +4672,7 @@ (bitconvert (memopv16i8 addr:$src2))))]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { let isCommutable = 0 in defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw, 0>, VEX_4V; @@ -4737,7 +4739,7 @@ OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPMULLD : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, 0>, VEX_4V; let Constraints = "$src1 = $dst" in defm PMULLD : SS48I_binop_rm<0x40, "pmulld", mul, v4i32>; @@ -4769,7 +4771,7 @@ OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { let isCommutable = 0 in { defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps, VR128, memopv16i8, i128mem, 0>, VEX_4V; @@ -4810,7 +4812,7 @@ } /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { multiclass SS41I_quaternary_int_avx opc, string OpcodeStr, RegisterClass RC, X86MemOperand x86memop, PatFrag mem_frag, Intrinsic IntId> { @@ -4870,7 +4872,7 @@ def : Pat<(X86pblendv VR128:$src1, VR128:$src2, XMM0), (PBLENDVBrr0 VR128:$src1, VR128:$src2)>; -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "vmovntdqa\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>, @@ -4904,7 +4906,7 @@ (bitconvert (memopv16i8 addr:$src2))))]>, OpSize; } -let isAsmParserOnly = 1, Predicates = [HasAVX] in +let isAsmParserOnly = 0, Predicates = [HasAVX] in defm VPCMPGTQ : SS42I_binop_rm_int<0x37, "vpcmpgtq", int_x86_sse42_pcmpgtq, 0>, VEX_4V; let Constraints = "$src1 = $dst" in @@ -4936,7 +4938,7 @@ defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>; } -let Defs = [XMM0, EFLAGS], isAsmParserOnly = 1, +let Defs = [XMM0, EFLAGS], isAsmParserOnly = 0, Predicates = [HasAVX] in { def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2, i8imm:$src3), @@ -4972,7 +4974,7 @@ defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>; } -let isAsmParserOnly = 1, Predicates = [HasAVX], +let isAsmParserOnly = 0, Predicates = [HasAVX], Defs = [XMM0, EFLAGS], Uses = [EAX, EDX] in { def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src3, i8imm:$src5), @@ -5007,7 +5009,7 @@ } } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPCMPISTRI : SS42AI_pcmpistri, VEX; defm VPCMPISTRIA : SS42AI_pcmpistri, @@ -5046,7 +5048,7 @@ } } -let isAsmParserOnly = 1, Predicates = [HasAVX] in { +let isAsmParserOnly = 0, Predicates = [HasAVX] in { defm VPCMPESTRI : SS42AI_pcmpestri, VEX; defm VPCMPESTRIA : SS42AI_pcmpestri, @@ -5165,7 +5167,7 @@ } // Perform One Round of an AES Encryption/Decryption Flow -let isAsmParserOnly = 1, Predicates = [HasAVX, HasAES] in { +let isAsmParserOnly = 0, Predicates = [HasAVX, HasAES] in { defm VAESENC : AESI_binop_rm_int<0xDC, "vaesenc", int_x86_aesni_aesenc, 0>, VEX_4V; defm VAESENCLAST : AESI_binop_rm_int<0xDD, "vaesenclast", @@ -5205,7 +5207,7 @@ (AESDECLASTrm VR128:$src1, addr:$src2)>; // Perform the AES InvMixColumn Transformation -let isAsmParserOnly = 1, Predicates = [HasAVX, HasAES] in { +let isAsmParserOnly = 0, Predicates = [HasAVX, HasAES] in { def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1), "vaesimc\t{$src1, $dst|$dst, $src1}", @@ -5233,7 +5235,7 @@ OpSize; // AES Round Key Generation Assist -let isAsmParserOnly = 1, Predicates = [HasAVX, HasAES] in { +let isAsmParserOnly = 0, Predicates = [HasAVX, HasAES] in { def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2), "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}", @@ -5269,7 +5271,7 @@ // Only the AVX version of CLMUL instructions are described here. // Carry-less Multiplication instructions -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { def VPCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i8imm:$src3), "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", @@ -5301,7 +5303,7 @@ // AVX Instructions //===----------------------------------------------------------------------===// -let isAsmParserOnly = 1 in { +let isAsmParserOnly = 0 in { // Load from memory and broadcast to all elements of the destination operand class avx_broadcast opc, string OpcodeStr, RegisterClass RC, From scallanan at apple.com Mon Mar 14 20:32:46 2011 From: scallanan at apple.com (Sean Callanan) Date: Tue, 15 Mar 2011 01:32:46 -0000 Subject: [llvm-commits] [llvm] r127647 - /llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt Message-ID: <20110315013246.4A4492A6C12C@llvm.org> Author: spyffe Date: Mon Mar 14 20:32:46 2011 New Revision: 127647 URL: http://llvm.org/viewvc/llvm-project?rev=127647&view=rev Log: Basic sanity checks to ensure that 2- and 3-byte VEX prefixes are working for triadic AVX instructions. This concludes the patch set to enable AVX support for the X86 disassebler. Modified: llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt Modified: llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt?rev=127647&r1=127646&r2=127647&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt Mon Mar 14 20:32:46 2011 @@ -66,3 +66,9 @@ # CHECK: movw $47416, -66(%rbp) 0x66 0xc7 0x45 0xbe 0x38 0xb9 + +# CHECK: vaddpd %ymm13, %ymm1, %ymm0 +0xc4 0xc1 0x75 0x58 0xc5 + +# CHECK: vaddps %ymm3, %ymm1, %ymm0 +0xc5 0xf4 0x58 0xc3 From bruno.cardoso at gmail.com Mon Mar 14 20:37:55 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Mon, 14 Mar 2011 22:37:55 -0300 Subject: [llvm-commits] [llvm] r127646 - in /llvm/trunk/lib/Target/X86: X86InstrFormats.td X86InstrSSE.td In-Reply-To: <20110315012816.0D4BA2A6C12C@llvm.org> References: <20110315012816.0D4BA2A6C12C@llvm.org> Message-ID: Hi Sean, On Mon, Mar 14, 2011 at 10:28 PM, Sean Callanan wrote: > Author: spyffe > Date: Mon Mar 14 20:28:15 2011 > New Revision: 127646 > > URL: http://llvm.org/viewvc/llvm-project?rev=127646&view=rev > Log: > Enabled disassembler support for AVX instructions > in the instruction tables and fixed a few bugs that > were causing decode conflicts. ?Rudimentary tests > are coming up in the next patch. > > Modified: > ? ?llvm/trunk/lib/Target/X86/X86InstrFormats.td > ? ?llvm/trunk/lib/Target/X86/X86InstrSSE.td > > Modified: llvm/trunk/lib/Target/X86/X86InstrFormats.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFormats.td?rev=127646&r1=127645&r2=127646&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrFormats.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrFormats.td Mon Mar 14 20:28:15 2011 > @@ -319,7 +319,7 @@ > ? ? ? ? Requires<[HasAVX]>; > ?class VPSI o, Format F, dag outs, dag ins, string asm, > ? ? ? ? ? ?list pattern> > - ? ? ?: I, > + ? ? ?: I, TB, > ? ? ? ? Requires<[HasAVX]>; > > ?// SSE2 Instruction Templates: > @@ -353,7 +353,7 @@ > ? ? ? ? Requires<[HasAVX]>; > ?class VPDI o, Format F, dag outs, dag ins, string asm, > ? ? ? ? ? ?list pattern> > - ? ? ?: I, > + ? ? ?: I, TB, > ? ? ? ? OpSize, Requires<[HasAVX]>; > > ?// SSE3 Instruction Templates: > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=127646&r1=127645&r2=127646&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon Mar 14 20:28:15 2011 > @@ -135,7 +135,7 @@ > ?// is used instead. Register-to-register movss/movsd is not modeled as an > ?// INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable > ?// in terms of a copy, and just mentioned, we don't use movss/movsd for copies. > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { Why not remove isAsmParserOnly completely instead of making it zero? > ? def VMOVSSrr : sse12_move_rr ? ? ? ? ? ? ? ? ? "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XS, VEX_4V; > ? def VMOVSDrr : sse12_move_rr @@ -218,7 +218,7 @@ > ? ? ? ? ? ? ? ? ? "movsd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? [(store FR64:$src, addr:$dst)]>; > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src), > ? ? ? ? ? ? ? ? ? "movss\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? [(store FR32:$src, addr:$dst)]>, XS, VEX; > @@ -251,7 +251,7 @@ > ? ? ? ? ? ? ? ? ? ?[(set RC:$dst, (ld_frag addr:$src))], d>; > ?} > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "movaps", SSEPackedSingle>, VEX; > ?defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64, > @@ -279,7 +279,7 @@ > ?defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "movupd", SSEPackedDouble, 0>, TB, OpSize; > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src), > ? ? ? ? ? ? ? ? ? ?"movaps\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ?[(alignedstore (v4f32 VR128:$src), addr:$dst)]>, VEX; > @@ -328,7 +328,7 @@ > ? ? ? ? ? ? ? ? ? ?[(store (v2f64 VR128:$src), addr:$dst)]>; > > ?// Intrinsic forms of MOVUPS/D load and store > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? let canFoldAsLoad = 1, isReMaterializable = 1 in > ? def VMOVUPSrm_Int : VPSI<0x10, MRMSrcMem, (outs VR128:$dst), > ? ? ? ? ? ? ?(ins f128mem:$src), > @@ -382,7 +382,7 @@ > ? ? ? ? ? ? ? SSEPackedDouble>, TB, OpSize; > ?} > > -let isAsmParserOnly = 1, AddedComplexity = 20 in { > +let isAsmParserOnly = 0, AddedComplexity = 20 in { > ? defm VMOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp", > ? ? ? ? ? ? ? ? ? ? ?"\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V; > ? defm VMOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp", > @@ -395,7 +395,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"\t{$src2, $dst|$dst, $src2}">; > ?} > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src), > ? ? ? ? ? ? ? ? ? ?"movlps\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ?[(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)), > @@ -416,7 +416,7 @@ > > ?// v2f64 extract element 1 is always custom lowered to unpack high to low > ?// and extract element 0 so the non-store version isn't too horrible. > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src), > ? ? ? ? ? ? ? ? ? ?"movhps\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ?[(store (f64 (vector_extract > @@ -441,7 +441,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(v2f64 (unpckh VR128:$src, (undef))), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(iPTR 0))), addr:$dst)]>; > > -let isAsmParserOnly = 1, AddedComplexity = 20 in { > +let isAsmParserOnly = 0, AddedComplexity = 20 in { > ? def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(ins VR128:$src1, VR128:$src2), > ? ? ? ? ? ? ? ? ? ? ? "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}", > @@ -516,7 +516,7 @@ > ? ? ? ? ? ? ? !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>; > ?} > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?defm VCVTTSS2SI ? : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX; > ?defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32, > @@ -591,7 +591,7 @@ > ? ? ? ? ? ? ? [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))]>; > ?} > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? defm Int_VCVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si, > ? ? ? ? ? ? ? ? ? ? ? ? f32mem, load, "cvtss2si">, XS, VEX; > ? defm Int_VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, > @@ -622,7 +622,7 @@ > ? ? ? ? ? ? ? ? ? f128mem, load, "cvtsd2si{q}">, XD, REX_W; > > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128, > ? ? ? ? ? ? int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss", 0>, XS, VEX_4V; > ? defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128, > @@ -653,7 +653,7 @@ > ?/// SSE 1 Only > > ?// Aliases for intrinsics > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f32mem, load, "cvttss2si">, XS, VEX; > ?defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64, > @@ -676,7 +676,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int_x86_sse2_cvttsd2si64, f128mem, load, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "cvttsd2si{q}">, XD, REX_W; > > -let isAsmParserOnly = 1, Pattern = [] in { > +let isAsmParserOnly = 0, Pattern = [] in { > ?defm VCVTSS2SI ? : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS, VEX; > ?defm VCVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load, > @@ -702,7 +702,7 @@ > ?/// SSE 2 Only > > ?// Convert scalar double to scalar single > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VCVTSD2SSrr ?: VSDI<0x5A, MRMSrcReg, (outs FR32:$dst), > ? ? ? ? ? ? ? ? ? ? ? ?(ins FR64:$src1, FR64:$src2), > ? ? ? ? ? ? ? ? ? ? ? "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, > @@ -723,7 +723,7 @@ > ? ? ? ? ? ? ? ? ? ? ? [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD, > ? ? ? ? ? ? ? ? ? Requires<[HasSSE2, OptForSize]>; > > -let isAsmParserOnly = 1 in > +let isAsmParserOnly = 0 in > ?defm Int_VCVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128, > ? ? ? ? ? ? ? ? ? ? ? int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss", 0>, > ? ? ? ? ? ? ? ? ? ? ? XS, VEX_4V; > @@ -732,7 +732,7 @@ > ? ? ? ? ? ? ? ? ? ? ? int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss">, XS; > > ?// Convert scalar single to scalar double > -let isAsmParserOnly = 1 in { // SSE2 instructions with XS prefix > +let isAsmParserOnly = 0 in { // SSE2 instructions with XS prefix > ?def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), > ? ? ? ? ? ? ? ? ? ? (ins FR32:$src1, FR32:$src2), > ? ? ? ? ? ? ? ? ? ? "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}", > @@ -754,7 +754,7 @@ > ? ? ? ? ? ? ? ? ? ?[(set FR64:$dst, (extloadf32 addr:$src))]>, XS, > ? ? ? ? ? ? ? ? ?Requires<[HasSSE2, OptForSize]>; > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg, > ? ? ? ? ? ? ? ? ? ? ? (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), > ? ? ? ? ? ? ? ? ? ? "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}", > @@ -788,7 +788,7 @@ > ? ? ? Requires<[HasSSE2, OptForSpeed]>; > > ?// Convert doubleword to packed single/double fp > -let isAsmParserOnly = 1 in { // SSE2 instructions without OpSize prefix > +let isAsmParserOnly = 0 in { // SSE2 instructions without OpSize prefix > ?def Int_VCVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"vcvtdq2ps\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>, > @@ -810,7 +810,7 @@ > ? ? ? ? ? ? ? ? ? ? ?TB, Requires<[HasSSE2]>; > > ?// FIXME: why the non-intrinsic version is described as SSE3? > -let isAsmParserOnly = 1 in { // SSE2 instructions with XS prefix > +let isAsmParserOnly = 0 in { // SSE2 instructions with XS prefix > ?def Int_VCVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"vcvtdq2pd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>, > @@ -833,7 +833,7 @@ > > > ?// Convert packed single/double fp to doubleword > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX; > ?def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), > @@ -848,7 +848,7 @@ > ?def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), > ? ? ? ? ? ? ? ? ? ? ?"cvtps2dq\t{$src, $dst|$dst, $src}", []>; > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def Int_VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ? "cvtps2dq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>, > @@ -867,7 +867,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, (int_x86_sse2_cvtps2dq > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (memop addr:$src)))]>; > > -let isAsmParserOnly = 1 in { // SSE2 packed instructions with XD prefix > +let isAsmParserOnly = 0 in { // SSE2 packed instructions with XD prefix > ?def Int_VCVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"vcvtpd2dq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>, > @@ -890,7 +890,7 @@ > > > ?// Convert with truncation packed single/double fp to doubleword > -let isAsmParserOnly = 1 in { // SSE2 packed instructions with XS prefix > +let isAsmParserOnly = 0 in { // SSE2 packed instructions with XS prefix > ?def VCVTTPS2DQrr : VSSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX; > ?def VCVTTPS2DQrm : VSSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), > @@ -910,7 +910,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? (int_x86_sse2_cvttps2dq (memop addr:$src)))]>; > > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def Int_VCVTTPS2DQrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ? "vcvttps2dq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, > @@ -923,7 +923,7 @@ > ? ? ? ? ? ? ? ? ? ? ? XS, VEX, Requires<[HasAVX]>; > ?} > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def Int_VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ? ? "cvttpd2dq\t{$src, $dst|$dst, $src}", > @@ -943,7 +943,7 @@ > ? ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, (int_x86_sse2_cvttpd2dq > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (memop addr:$src)))]>; > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?// The assembler can recognize rr 256-bit instructions by seeing a ymm > ?// register, but the same isn't true when using memory operands instead. > ?// Provide other assembly rr and rm forms to address this explicitly. > @@ -966,7 +966,7 @@ > ?} > > ?// Convert packed single to packed double > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? ? ? ? ? ? ? ? ? // SSE2 instructions without OpSize prefix > ?def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ?"vcvtps2pd\t{$src, $dst|$dst, $src}", []>, VEX; > @@ -982,7 +982,7 @@ > ?def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB; > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def Int_VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"vcvtps2pd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>, > @@ -1004,7 +1004,7 @@ > ? ? ? ? ? ? ? ? ? ? ?TB, Requires<[HasSSE2]>; > > ?// Convert packed double to packed single > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?// The assembler can recognize rr 256-bit instructions by seeing a ymm > ?// register, but the same isn't true when using memory operands instead. > ?// Provide other assembly rr and rm forms to address this explicitly. > @@ -1031,7 +1031,7 @@ > ? ? ? ? ? ? ? ? ? ? ?"cvtpd2ps\t{$src, $dst|$dst, $src}", []>; > > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def Int_VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ? ?"cvtpd2ps\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>; > @@ -1089,26 +1089,27 @@ > ?// sse12_cmp_scalar - sse 1 & 2 compare scalar instructions > ?multiclass sse12_cmp_scalar ? ? ? ? ? ? ? ? ? ? ? ? ? ? string asm, string asm_alt> { > - ?def rr : SIi8<0xC2, MRMSrcReg, > - ? ? ? ? ? ? ? ? ? ?(outs RC:$dst), (ins RC:$src1, RC:$src, SSECC:$cc), > - ? ? ? ? ? ? ? ? ? ?asm, []>; > - ?let mayLoad = 1 in > - ?def rm : SIi8<0xC2, MRMSrcMem, > - ? ? ? ? ? ? ? ? ? ?(outs RC:$dst), (ins RC:$src1, x86memop:$src, SSECC:$cc), > - ? ? ? ? ? ? ? ? ? ?asm, []>; > - ?// Accept explicit immediate argument form instead of comparison code. > ? let isAsmParserOnly = 1 in { > - ? ?def rr_alt : SIi8<0xC2, MRMSrcReg, > - ? ? ? ? ? ? ? ? ?(outs RC:$dst), (ins RC:$src1, RC:$src, i8imm:$src2), > - ? ? ? ? ? ? ? ? ?asm_alt, []>; > + ? ?def rr : SIi8<0xC2, MRMSrcReg, > + ? ? ? ? ? ? ? ? ?(outs RC:$dst), (ins RC:$src1, RC:$src, SSECC:$cc), > + ? ? ? ? ? ? ? ? ?asm, []>; > ? ? let mayLoad = 1 in > - ? ?def rm_alt : SIi8<0xC2, MRMSrcMem, > - ? ? ? ? ? ? ? ? ?(outs RC:$dst), (ins RC:$src1, x86memop:$src, i8imm:$src2), > - ? ? ? ? ? ? ? ? ?asm_alt, []>; > + ? ?def rm : SIi8<0xC2, MRMSrcMem, > + ? ? ? ? ? ? ? ? ?(outs RC:$dst), (ins RC:$src1, x86memop:$src, SSECC:$cc), > + ? ? ? ? ? ? ? ? ?asm, []>; > ? } > + > + ?// Accept explicit immediate argument form instead of comparison code. > + ?def rr_alt : SIi8<0xC2, MRMSrcReg, > + ? ? ? ? ? ? ? ?(outs RC:$dst), (ins RC:$src1, RC:$src, i8imm:$src2), > + ? ? ? ? ? ? ? ?asm_alt, []>; > + ?let mayLoad = 1 in > + ?def rm_alt : SIi8<0xC2, MRMSrcMem, > + ? ? ? ? ? ? ? ?(outs RC:$dst), (ins RC:$src1, x86memop:$src, i8imm:$src2), > + ? ? ? ? ? ? ? ?asm_alt, []>; > ?} > > -let neverHasSideEffects = 1, isAsmParserOnly = 1 in { > +let neverHasSideEffects = 1, isAsmParserOnly = 0 in { > ? defm VCMPSS ?: sse12_cmp_scalar ? ? ? ? ? ? ? ? ? "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}", > ? ? ? ? ? ? ? ? ? "cmpss\t{$src2, $src, $src1, $dst|$dst, $src1, $src, $src2}">, > @@ -1141,7 +1142,7 @@ > ?} > > ?// Aliases to match intrinsics which expect XMM operand(s). > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? defm Int_VCMPSS ?: sse12_cmp_scalar_int ? ? ? ? ? ? ? ? ? ? ? ?"cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}">, > ? ? ? ? ? ? ? ? ? ? ? ?XS, VEX_4V; > @@ -1171,7 +1172,7 @@ > ?} > > ?let Defs = [EFLAGS] in { > - ?let isAsmParserOnly = 1 in { > + ?let isAsmParserOnly = 0 in { > ? ? defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "ucomiss", SSEPackedSingle>, VEX; > ? ? defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64, > @@ -1220,24 +1221,25 @@ > ?multiclass sse12_cmp_packed ? ? ? ? ? ? ? ? ? ? ? ? ? ? Intrinsic Int, string asm, string asm_alt, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? Domain d> { > - ?def rri : PIi8<0xC2, MRMSrcReg, > - ? ? ? ? ? ? (outs RC:$dst), (ins RC:$src1, RC:$src, SSECC:$cc), asm, > - ? ? ? ? ? ? [(set RC:$dst, (Int RC:$src1, RC:$src, imm:$cc))], d>; > - ?def rmi : PIi8<0xC2, MRMSrcMem, > - ? ? ? ? ? ? (outs RC:$dst), (ins RC:$src1, f128mem:$src, SSECC:$cc), asm, > - ? ? ? ? ? ? [(set RC:$dst, (Int RC:$src1, (memop addr:$src), imm:$cc))], d>; > - ?// Accept explicit immediate argument form instead of comparison code. > ? let isAsmParserOnly = 1 in { > - ? ?def rri_alt : PIi8<0xC2, MRMSrcReg, > - ? ? ? ? ? ? ? (outs RC:$dst), (ins RC:$src1, RC:$src, i8imm:$src2), > - ? ? ? ? ? ? ? asm_alt, [], d>; > - ? ?def rmi_alt : PIi8<0xC2, MRMSrcMem, > - ? ? ? ? ? ? ? (outs RC:$dst), (ins RC:$src1, f128mem:$src, i8imm:$src2), > - ? ? ? ? ? ? ? asm_alt, [], d>; > + ? ?def rri : PIi8<0xC2, MRMSrcReg, > + ? ? ? ? ? ? ? (outs RC:$dst), (ins RC:$src1, RC:$src, SSECC:$cc), asm, > + ? ? ? ? ? ? ? [(set RC:$dst, (Int RC:$src1, RC:$src, imm:$cc))], d>; > + ? ?def rmi : PIi8<0xC2, MRMSrcMem, > + ? ? ? ? ? ? ? (outs RC:$dst), (ins RC:$src1, f128mem:$src, SSECC:$cc), asm, > + ? ? ? ? ? ? ? [(set RC:$dst, (Int RC:$src1, (memop addr:$src), imm:$cc))], d>; > ? } > + > + ?// Accept explicit immediate argument form instead of comparison code. > + ?def rri_alt : PIi8<0xC2, MRMSrcReg, > + ? ? ? ? ? ? (outs RC:$dst), (ins RC:$src1, RC:$src, i8imm:$src2), > + ? ? ? ? ? ? asm_alt, [], d>; > + ?def rmi_alt : PIi8<0xC2, MRMSrcMem, > + ? ? ? ? ? ? (outs RC:$dst), (ins RC:$src1, f128mem:$src, i8imm:$src2), > + ? ? ? ? ? ? asm_alt, [], d>; > ?} > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? defm VCMPPS : sse12_cmp_packed ? ? ? ? ? ? ? ? ?"cmp${cc}ps\t{$src, $src1, $dst|$dst, $src1, $src}", > ? ? ? ? ? ? ? ? ?"cmpps\t{$src2, $src, $src1, $dst|$dst, $src1, $src, $src2}", > @@ -1294,19 +1296,19 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? (vt (shufp:$src3 RC:$src1, RC:$src2)))], d>; > ?} > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? defm VSHUFPS ?: sse12_shuffle ? ? ? ? ? ? ?"shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", > - ? ? ? ? ? ? memopv4f32, SSEPackedSingle>, VEX_4V; > + ? ? ? ? ? ? memopv4f32, SSEPackedSingle>, TB, VEX_4V; > ? defm VSHUFPSY : sse12_shuffle ? ? ? ? ? ? ?"shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", > - ? ? ? ? ? ? memopv8f32, SSEPackedSingle>, VEX_4V; > + ? ? ? ? ? ? memopv8f32, SSEPackedSingle>, TB, VEX_4V; > ? defm VSHUFPD ?: sse12_shuffle ? ? ? ? ? ? ?"shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}", > - ? ? ? ? ? ? memopv2f64, SSEPackedDouble>, OpSize, VEX_4V; > + ? ? ? ? ? ? memopv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V; > ? defm VSHUFPDY : sse12_shuffle ? ? ? ? ? ? ?"shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}", > - ? ? ? ? ? ? memopv4f64, SSEPackedDouble>, OpSize, VEX_4V; > + ? ? ? ? ? ? memopv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V; > ?} > > ?let Constraints = "$src1 = $dst" in { > @@ -1340,7 +1342,7 @@ > ?} > > ?let AddedComplexity = 10 in { > - ?let isAsmParserOnly = 1 in { > + ?let isAsmParserOnly = 0 in { > ? ? defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32, > ? ? ? ? ? VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}", > ? ? ? ? ? ? ? ? ? ? ? ? ?SSEPackedSingle>, VEX_4V; > @@ -1404,7 +1406,7 @@ > ?defm MOVMSKPD : sse12_extr_sign_mask ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SSEPackedDouble>, TB, OpSize; > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? defm VMOVMSKPS : sse12_extr_sign_mask ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "movmskps", SSEPackedSingle>, VEX; > ? defm VMOVMSKPD : sse12_extr_sign_mask @@ -1482,7 +1484,7 @@ > ?/// > ?multiclass sse12_fp_alias_pack_logical opc, string OpcodeStr, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SDNode OpNode> { > - ?let isAsmParserOnly = 1 in { > + ?let isAsmParserOnly = 0 in { > ? ? defm V#NAME#PS : sse12_fp_packed ? ? ? ? ? ? ? ? FR32, f32, f128mem, memopfsf32, SSEPackedSingle, 0>, VEX_4V; > > @@ -1514,7 +1516,7 @@ > ?multiclass sse12_fp_packed_logical opc, string OpcodeStr, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SDNode OpNode, int HasPat = 0, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?list> Pattern = []> { > - ?let isAsmParserOnly = 1, Pattern = [] in { > + ?let isAsmParserOnly = 0, Pattern = [] in { > ? ? defm V#NAME#PS : sse12_fp_packed_logical_rm ? ? ? ? ?!strconcat(OpcodeStr, "ps"), f128mem, > ? ? ? ? ?!if(HasPat, Pattern[0], // rr > @@ -1561,7 +1563,7 @@ > > ?/// sse12_fp_packed_logical_y - AVX 256-bit SSE 1 & 2 logical ops forms > ?/// > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?multiclass sse12_fp_packed_logical_y opc, string OpcodeStr> { > ? ? defm PSY : sse12_fp_packed_logical_rm ? ? ? ? ? !strconcat(OpcodeStr, "ps"), f256mem, [], [], 0>, VEX_4V; > @@ -1667,7 +1669,7 @@ > ?} > > ?// Binary Arithmetic instructions > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>, > ? ? ? ? ? ? ? basic_sse12_fp_binop_s_int<0x58, "add", 0>, > ? ? ? ? ? ? ? basic_sse12_fp_binop_p<0x58, "add", fadd, 0>, > @@ -1899,7 +1901,7 @@ > ? ? ? ? ? ? ? ? ? ? [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? // Square root. > ? defm VSQRT ?: sse1_fp_unop_s_avx<0x51, "vsqrt", fsqrt, int_x86_sse_sqrt_ss>, > ? ? ? ? ? ? ? ? sse2_fp_unop_s_avx<0x51, "vsqrt", fsqrt, int_x86_sse2_sqrt_sd>, > @@ -1955,7 +1957,7 @@ > ?// SSE 1 & 2 - Non-temporal stores > ?//===----------------------------------------------------------------------===// > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? def VMOVNTPSmr_Int : VPSI<0x2B, MRMDestMem, (outs), > ? ? ? ? ? ? ? ? ? ? ? ? ?(ins i128mem:$dst, VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ? ?"movntps\t{$src, $dst|$dst, $src}", > @@ -2138,7 +2140,7 @@ > ?// SSE 1 & 2 - Load/Store XCSR register > ?//===----------------------------------------------------------------------===// > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src), > ? ? ? ? ? ? ? ? ? ? "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX; > ? def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst), > @@ -2156,7 +2158,7 @@ > > ?let ExeDomain = SSEPackedInt in { // SSE integer instructions > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ? let neverHasSideEffects = 1 in { > ? def VMOVDQArr ?: VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? "movdqa\t{$src, $dst|$dst, $src}", []>, VEX; > @@ -2226,7 +2228,7 @@ > ?} > > ?// Intrinsic forms of MOVDQU load and store > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?let canFoldAsLoad = 1 in > ?def VMOVDQUrm_Int : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"vmovdqu\t{$src, $dst|$dst, $src}", > @@ -2347,7 +2349,7 @@ > > ?// 128-bit Integer Arithmetic > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VPADDB ?: PDI_binop_rm<0xFC, "vpaddb", add, v16i8, 1, 0 /*3addr*/>, VEX_4V; > ?defm VPADDW ?: PDI_binop_rm<0xFD, "vpaddw", add, v8i16, 1, 0>, VEX_4V; > ?defm VPADDD ?: PDI_binop_rm<0xFE, "vpaddd", add, v4i32, 1, 0>, VEX_4V; > @@ -2437,7 +2439,7 @@ > ?// SSE2 - Packed Integer Logical Instructions > ?//===---------------------------------------------------------------------===// > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VPSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw", > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int_x86_sse2_psll_w, int_x86_sse2_pslli_w, 0>, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? VEX_4V; > @@ -2584,7 +2586,7 @@ > ?// SSE2 - Packed Integer Comparison Instructions > ?//===---------------------------------------------------------------------===// > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? defm VPCMPEQB ?: PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_sse2_pcmpeq_b, 1, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0>, VEX_4V; > ? defm VPCMPEQW ?: PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_sse2_pcmpeq_w, 1, > @@ -2638,7 +2640,7 @@ > ?// SSE2 - Packed Integer Pack Instructions > ?//===---------------------------------------------------------------------===// > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0, 0>, VEX_4V; > ?defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128, > @@ -2676,7 +2678,7 @@ > ?} > ?} // ExeDomain = SSEPackedInt > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? let AddedComplexity = 5 in > ? defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, pshufd, bc_v4i32>, OpSize, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?VEX; > @@ -2724,7 +2726,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?addr:$src2))))]>; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? defm VPUNPCKLBW ?: sse2_unpack<0x60, "vpunpcklbw", v16i8, unpckl, bc_v16i8, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0>, VEX_4V; > ? defm VPUNPCKLWD ?: sse2_unpack<0x61, "vpunpcklwd", v8i16, unpckl, bc_v8i16, > @@ -2834,7 +2836,7 @@ > ?} > > ?// Extract > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ?def VPEXTRWri : Ii8<0xC5, MRMSrcReg, > ? ? ? ? ? ? ? ? ? ? (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2), > ? ? ? ? ? ? ? ? ? ? "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}", > @@ -2847,7 +2849,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? imm:$src2))]>; > > ?// Insert > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? defm VPINSRW : sse2_pinsrw<0>, OpSize, VEX_4V; > ? def ?VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst), > ? ? ? ?(ins VR128:$src1, GR64:$src2, i32i8imm:$src3), > @@ -2866,7 +2868,7 @@ > > ?let ExeDomain = SSEPackedInt in { > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VPMOVMSKBrr ?: VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src), > ? ? ? ? ? ?"pmovmskb\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ?[(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX; > @@ -2885,7 +2887,7 @@ > > ?let ExeDomain = SSEPackedInt in { > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?let Uses = [EDI] in > ?def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs), > ? ? ? ? ? ?(ins VR128:$src, VR128:$mask), > @@ -2914,7 +2916,7 @@ > ?//===---------------------------------------------------------------------===// > > ?// Move Int Doubleword to Packed Double Int > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src), > ? ? ? ? ? ? ? ? ? ? ? "movd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, > @@ -2943,7 +2945,7 @@ > > > ?// Move Int Doubleword to Single Scalar > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVDI2SSrr ?: VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src), > ? ? ? ? ? ? ? ? ? ? ? "movd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX; > @@ -2962,7 +2964,7 @@ > ? ? ? ? ? ? ? ? ? ? ? [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>; > > ?// Move Packed Doubleword Int to Packed Double Int > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVPDI2DIrr ?: VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"movd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ?[(set GR32:$dst, (vector_extract (v4i32 VR128:$src), > @@ -2998,7 +3000,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>; > > ?// Move Scalar Single to Double Int > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVSS2DIrr ?: VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src), > ? ? ? ? ? ? ? ? ? ? ? "movd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX; > @@ -3014,7 +3016,7 @@ > ? ? ? ? ? ? ? ? ? ? ? [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>; > > ?// movd / movq to XMM register zero-extends > -let AddedComplexity = 15, isAsmParserOnly = 1 in { > +let AddedComplexity = 15, isAsmParserOnly = 0 in { > ?def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"movd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, (v4i32 (X86vzmovl > @@ -3038,7 +3040,7 @@ > ?} > > ?let AddedComplexity = 20 in { > -let isAsmParserOnly = 1 in > +let isAsmParserOnly = 0 in > ?def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"movd\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, > @@ -3064,7 +3066,7 @@ > ?//===---------------------------------------------------------------------===// > > ?// Move Quadword Int to Packed Quadword Int > -let isAsmParserOnly = 1 in > +let isAsmParserOnly = 0 in > ?def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src), > ? ? ? ? ? ? ? ? ? ? "vmovq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, > @@ -3077,7 +3079,7 @@ > ? ? ? ? ? ? ? ? ? ? Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix > > ?// Move Packed Quadword Int to Quadword Int > -let isAsmParserOnly = 1 in > +let isAsmParserOnly = 0 in > ?def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? "movq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? [(store (i64 (vector_extract (v2i64 VR128:$src), > @@ -3091,7 +3093,7 @@ > ? ? ? ? ? (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>; > > ?// Store / copy lower 64-bits of a XMM register. > -let isAsmParserOnly = 1 in > +let isAsmParserOnly = 0 in > ?def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src), > ? ? ? ? ? ? ? ? ? ? ?"movq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ?[(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX; > @@ -3099,7 +3101,7 @@ > ? ? ? ? ? ? ? ? ? ? ?"movq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ?[(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>; > > -let AddedComplexity = 20, isAsmParserOnly = 1 in > +let AddedComplexity = 20, isAsmParserOnly = 0 in > ?def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src), > ? ? ? ? ? ? ? ? ? ? ?"vmovq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, > @@ -3124,7 +3126,7 @@ > > ?// Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in > ?// IA32 document. movq xmm1, xmm2 does clear the high bits. > -let isAsmParserOnly = 1, AddedComplexity = 15 in > +let isAsmParserOnly = 0, AddedComplexity = 15 in > ?def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ? ? ? ? "vmovq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>, > @@ -3135,7 +3137,7 @@ > ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>, > ? ? ? ? ? ? ? ? ? ? ? XS, Requires<[HasSSE2]>; > > -let AddedComplexity = 20, isAsmParserOnly = 1 in > +let AddedComplexity = 20, isAsmParserOnly = 0 in > ?def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), > ? ? ? ? ? ? ? ? ? ? ? ? "vmovq\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? [(set VR128:$dst, (v2i64 (X86vzmovl > @@ -3153,7 +3155,7 @@ > ?} > > ?// Instructions to match in the assembler > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src), > ? ? ? ? ? ? ? ? ? ? ? "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W; > ?def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src), > @@ -3167,7 +3169,7 @@ > ?// xr = XMM register > ?// xm = mem64 > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ?def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > ? ? ? ? ? ? ? ? ?"vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS; > ?def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > @@ -3209,7 +3211,7 @@ > ?//===---------------------------------------------------------------------===// > > ?// Convert Packed Double FP to Packed DW Integers > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?// The assembler can recognize rr 256-bit instructions by seeing a ymm > ?// register, but the same isn't true when using memory operands instead. > ?// Provide other assembly rr and rm forms to address this explicitly. > @@ -3237,7 +3239,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ?"cvtpd2dq\t{$src, $dst|$dst, $src}", []>; > > ?// Convert Packed DW Integers to Packed Double FP > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?def VCVTDQ2PDrm ?: S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), > ? ? ? ? ? ? ? ? ? ? ?"vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX; > ?def VCVTDQ2PDrr ?: S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), > @@ -3288,7 +3290,7 @@ > ? ? ? ? ? ? ? !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? // FIXME: Merge above classes when we have patterns for the ymm version > ? defm VMOVSHDUP ?: sse3_replicate_sfp<0x16, movshdup, "vmovshdup">, VEX; > ? defm VMOVSLDUP ?: sse3_replicate_sfp<0x12, movsldup, "vmovsldup">, VEX; > @@ -3319,7 +3321,7 @@ > ? ? ? ? ? ? ? ? ? ? []>; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? // FIXME: Merge above classes when we have patterns for the ymm version > ? defm VMOVDDUP ?: sse3_replicate_dfp<"vmovddup">, VEX; > ? defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX; > @@ -3327,7 +3329,7 @@ > ?defm MOVDDUP : sse3_replicate_dfp<"movddup">; > > ?// Move Unaligned Integer > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), > ? ? ? ? ? ? ? ? ? ?"vlddqu\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX; > @@ -3391,21 +3393,21 @@ > ? ? ? ?[(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX], > +let isAsmParserOnly = 0, Predicates = [HasAVX], > ? ExeDomain = SSEPackedDouble in { > ? defm VADDSUBPS : sse3_addsub - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f128mem, 0>, XD, VEX_4V; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f128mem, 0>, TB, XD, VEX_4V; > ? defm VADDSUBPD : sse3_addsub - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f128mem, 0>, OpSize, VEX_4V; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f128mem, 0>, TB, OpSize, VEX_4V; > ? defm VADDSUBPSY : sse3_addsub - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f256mem, 0>, XD, VEX_4V; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f256mem, 0>, TB, XD, VEX_4V; > ? defm VADDSUBPDY : sse3_addsub - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f256mem, 0>, OpSize, VEX_4V; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f256mem, 0>, TB, OpSize, VEX_4V; > ?} > ?let Constraints = "$src1 = $dst", Predicates = [HasSSE3], > ? ? ExeDomain = SSEPackedDouble in { > ? defm ADDSUBPS : sse3_addsub - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?f128mem>, XD; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?f128mem>, TB, XD; > ? defm ADDSUBPD : sse3_addsub ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f128mem>, TB, OpSize; > ?} > @@ -3444,7 +3446,7 @@ > ? ? ? [(set RC:$dst, (vt (IntId RC:$src1, (memop addr:$src2))))]>; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? defm VHADDPS ?: S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem, > ? ? ? ? ? ? ? ? ? ? ? ? ? int_x86_sse3_hadd_ps, 0>, VEX_4V; > ? defm VHADDPD ?: S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem, > @@ -3496,7 +3498,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ?(bitconvert (mem_frag128 addr:$src))))]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? defm VPABSB ?: SS3I_unop_rm_int<0x1C, "vpabsb", memopv16i8, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int_x86_ssse3_pabs_b_128>, VEX; > ? defm VPABSW ?: SS3I_unop_rm_int<0x1D, "vpabsw", memopv8i16, > @@ -3538,7 +3540,7 @@ > ? ? ? ? ? (bitconvert (memopv16i8 addr:$src2))))]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?let isCommutable = 0 in { > ? defm VPHADDW ? ?: SS3I_binop_rm_int<0x01, "vphaddw", memopv8i16, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int_x86_ssse3_phadd_w_128, 0>, VEX_4V; > @@ -3630,7 +3632,7 @@ > ? ? ? []>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V; > ?let Constraints = "$src1 = $dst" in > ? defm PALIGN : ssse3_palign<"palignr">; > @@ -3985,7 +3987,7 @@ > ? ? ? ?OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?VEX; > ?defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>, > @@ -4051,7 +4053,7 @@ > ? ? ? ? ? OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?VEX; > ?defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>, > @@ -4092,7 +4094,7 @@ > ? ? ? ? ? ? ? ? ?OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?VEX; > ?defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>, > @@ -4134,7 +4136,7 @@ > ?// (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst) > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX; > ? def ?VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst), > ? ? ? ? ?(ins VR128:$src1, i32i8imm:$src2), > @@ -4156,7 +4158,7 @@ > ?// (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst) > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX; > > ?defm PEXTRW ? ? ?: SS41I_extract16<0x15, "pextrw">; > @@ -4178,7 +4180,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? addr:$dst)]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX; > > ?defm PEXTRD ? ? ?: SS41I_extract32<0x16, "pextrd">; > @@ -4199,7 +4201,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? addr:$dst)]>, OpSize, REX_W; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W; > > ?defm PEXTRQ ? ? ?: SS41I_extract64<0x16, "pextrq">; > @@ -4222,7 +4224,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? addr:$dst)]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX; > ? def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst), > ? ? ? ? ? ? ? ? ? (ins VR128:$src1, i32i8imm:$src2), > @@ -4262,7 +4264,7 @@ > ? ? ? ? ? ? ? ? ? ?imm:$src3))]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V; > ?let Constraints = "$src1 = $dst" in > ? defm PINSRB ?: SS41I_insert8<0x20, "pinsrb">; > @@ -4288,7 +4290,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? imm:$src3)))]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V; > ?let Constraints = "$src1 = $dst" in > ? defm PINSRD : SS41I_insert32<0x22, "pinsrd">; > @@ -4314,7 +4316,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? imm:$src3)))]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W; > ?let Constraints = "$src1 = $dst" in > ? defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W; > @@ -4347,7 +4349,7 @@ > > ?let Constraints = "$src1 = $dst" in > ? defm INSERTPS : SS41I_insertf32<0x21, "insertps">; > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V; > > ?def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3), > @@ -4517,7 +4519,7 @@ > ?} > > ?// FP round - roundss, roundps, roundsd, roundpd > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? // Intrinsic form > ? defm VROUND ?: sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? memopv4f32, memopv2f64, > @@ -4552,7 +4554,7 @@ > > ?// ptest instruction we'll lower to this in X86ISelLowering primarily from > ?// the intel intrinsic that corresponds to this. > -let Defs = [EFLAGS], isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let Defs = [EFLAGS], isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?def VPTESTrr ?: SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), > ? ? ? ? ? ? ? ? "vptest\t{$src2, $src1|$src1, $src2}", > ? ? ? ? ? ? ? ? [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>, > @@ -4595,7 +4597,7 @@ > ? ? ? ? ? ? OpSize, VEX; > ?} > > -let Defs = [EFLAGS], isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let Defs = [EFLAGS], isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VTESTPS ?: avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>; > ?defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>; > ?defm VTESTPD ?: avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>; > @@ -4644,7 +4646,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ?(bitconvert (memopv8i16 addr:$src))))]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ?defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw", > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int_x86_sse41_phminposuw>, VEX; > ?defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw", > @@ -4670,7 +4672,7 @@ > ? ? ? ? ? (bitconvert (memopv16i8 addr:$src2))))]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? let isCommutable = 0 in > ? defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0>, VEX_4V; > @@ -4737,7 +4739,7 @@ > ? ? ? ?OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPMULLD : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, 0>, VEX_4V; > ?let Constraints = "$src1 = $dst" in > ? defm PMULLD : SS48I_binop_rm<0x40, "pmulld", mul, v4i32>; > @@ -4769,7 +4771,7 @@ > ? ? ? ? OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ? let isCommutable = 0 in { > ? defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? VR128, memopv16i8, i128mem, 0>, VEX_4V; > @@ -4810,7 +4812,7 @@ > ?} > > ?/// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?multiclass SS41I_quaternary_int_avx opc, string OpcodeStr, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? RegisterClass RC, X86MemOperand x86memop, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PatFrag mem_frag, Intrinsic IntId> { > @@ -4870,7 +4872,7 @@ > ?def : Pat<(X86pblendv VR128:$src1, VR128:$src2, XMM0), > ? ? ? ? ? (PBLENDVBrr0 VR128:$src1, VR128:$src2)>; > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ?def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), > ? ? ? ? ? ? ? ? ? ? ? ?"vmovntdqa\t{$src, $dst|$dst, $src}", > ? ? ? ? ? ? ? ? ? ? ? ?[(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>, > @@ -4904,7 +4906,7 @@ > ? ? ? ? ? (bitconvert (memopv16i8 addr:$src2))))]>, OpSize; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in > +let isAsmParserOnly = 0, Predicates = [HasAVX] in > ? defm VPCMPGTQ : SS42I_binop_rm_int<0x37, "vpcmpgtq", int_x86_sse42_pcmpgtq, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0>, VEX_4V; > ?let Constraints = "$src1 = $dst" in > @@ -4936,7 +4938,7 @@ > ? defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>; > ?} > > -let Defs = [XMM0, EFLAGS], isAsmParserOnly = 1, > +let Defs = [XMM0, EFLAGS], isAsmParserOnly = 0, > ? ? Predicates = [HasAVX] in { > ? def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs), > ? ? ? (ins VR128:$src1, VR128:$src2, i8imm:$src3), > @@ -4972,7 +4974,7 @@ > ? defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>; > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX], > +let isAsmParserOnly = 0, Predicates = [HasAVX], > ? ? Defs = [XMM0, EFLAGS], Uses = [EAX, EDX] in { > ? def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs), > ? ? ? (ins VR128:$src1, VR128:$src3, i8imm:$src5), > @@ -5007,7 +5009,7 @@ > ? } > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VPCMPISTRI ?: SS42AI_pcmpistri, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? VEX; > ?defm VPCMPISTRIA : SS42AI_pcmpistri, > @@ -5046,7 +5048,7 @@ > ? } > ?} > > -let isAsmParserOnly = 1, Predicates = [HasAVX] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX] in { > ?defm VPCMPESTRI ?: SS42AI_pcmpestri, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? VEX; > ?defm VPCMPESTRIA : SS42AI_pcmpestri, > @@ -5165,7 +5167,7 @@ > ?} > > ?// Perform One Round of an AES Encryption/Decryption Flow > -let isAsmParserOnly = 1, Predicates = [HasAVX, HasAES] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX, HasAES] in { > ? defm VAESENC ? ? ? ? ?: AESI_binop_rm_int<0xDC, "vaesenc", > ? ? ? ? ? ? ? ? ? ? ? ? ?int_x86_aesni_aesenc, 0>, VEX_4V; > ? defm VAESENCLAST ? ? ?: AESI_binop_rm_int<0xDD, "vaesenclast", > @@ -5205,7 +5207,7 @@ > ? ? ? ? ? (AESDECLASTrm VR128:$src1, addr:$src2)>; > > ?// Perform the AES InvMixColumn Transformation > -let isAsmParserOnly = 1, Predicates = [HasAVX, HasAES] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX, HasAES] in { > ? def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst), > ? ? ? (ins VR128:$src1), > ? ? ? "vaesimc\t{$src1, $dst|$dst, $src1}", > @@ -5233,7 +5235,7 @@ > ? OpSize; > > ?// AES Round Key Generation Assist > -let isAsmParserOnly = 1, Predicates = [HasAVX, HasAES] in { > +let isAsmParserOnly = 0, Predicates = [HasAVX, HasAES] in { > ? def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst), > ? ? ? (ins VR128:$src1, i8imm:$src2), > ? ? ? "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}", > @@ -5269,7 +5271,7 @@ > ?// Only the AVX version of CLMUL instructions are described here. > > ?// Carry-less Multiplication instructions > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > ?def VPCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst), > ? ? ? ? ? ?(ins VR128:$src1, VR128:$src2, i8imm:$src3), > ? ? ? ? ? ?"vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}", > @@ -5301,7 +5303,7 @@ > ?// AVX Instructions > ?//===----------------------------------------------------------------------===// > > -let isAsmParserOnly = 1 in { > +let isAsmParserOnly = 0 in { > > ?// Load from memory and broadcast to all elements of the destination operand > ?class avx_broadcast opc, string OpcodeStr, RegisterClass RC, > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -- Bruno Cardoso Lopes http://www.brunocardoso.cc From isanbard at gmail.com Mon Mar 14 20:49:08 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 15 Mar 2011 01:49:08 -0000 Subject: [llvm-commits] [llvm] r127648 - /llvm/trunk/test/CodeGen/ARM/shuffle.ll Message-ID: <20110315014908.B0B6B2A6C12C@llvm.org> Author: void Date: Mon Mar 14 20:49:08 2011 New Revision: 127648 URL: http://llvm.org/viewvc/llvm-project?rev=127648&view=rev Log: Testcase for r127630. Added: llvm/trunk/test/CodeGen/ARM/shuffle.ll Added: llvm/trunk/test/CodeGen/ARM/shuffle.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/shuffle.ll?rev=127648&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/shuffle.ll (added) +++ llvm/trunk/test/CodeGen/ARM/shuffle.ll Mon Mar 14 20:49:08 2011 @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -relocation-model=pic -disable-fp-elim | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" +target triple = "thumbv7-apple-darwin" + +define <8 x i8> @shuf(<8 x i8> %a) nounwind readnone optsize ssp { +entry: +; CHECK: vtbl + %shuffle = shufflevector <8 x i8> %a, <8 x i8> undef, <8 x i32> + ret <8 x i8> %shuffle +} + +define <8 x i8> @shuf2(<8 x i8> %a, <8 x i8> %b) nounwind readnone optsize ssp { +entry: +; CHECK: vtbl + %shuffle = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> + ret <8 x i8> %shuffle +} From evan.cheng at apple.com Mon Mar 14 21:22:11 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 15 Mar 2011 02:22:11 -0000 Subject: [llvm-commits] [llvm] r127649 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAG.cpp test/CodeGen/X86/machine-cse.ll Message-ID: <20110315022211.457232A6C12C@llvm.org> Author: evancheng Date: Mon Mar 14 21:22:10 2011 New Revision: 127649 URL: http://llvm.org/viewvc/llvm-project?rev=127649&view=rev Log: sext(undef) = 0, because the top bits will all be the same. zext(undef) = 0, because the top bits will be zero. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/test/CodeGen/X86/machine-cse.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=127649&r1=127648&r2=127649&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Mar 14 21:22:10 2011 @@ -2483,7 +2483,8 @@ if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND) return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0)); else if (OpOpcode == ISD::UNDEF) - return getUNDEF(VT); + // sext(undef) = 0, because the top bits will all be the same. + return getConstant(0, VT); break; case ISD::ZERO_EXTEND: assert(VT.isInteger() && Operand.getValueType().isInteger() && @@ -2498,6 +2499,9 @@ if (OpOpcode == ISD::ZERO_EXTEND) // (zext (zext x)) -> (zext x) return getNode(ISD::ZERO_EXTEND, DL, VT, Operand.getNode()->getOperand(0)); + else if (OpOpcode == ISD::UNDEF) + // zext(undef) = 0, because the top bits will be zero. + return getConstant(0, VT); break; case ISD::ANY_EXTEND: assert(VT.isInteger() && Operand.getValueType().isInteger() && Modified: llvm/trunk/test/CodeGen/X86/machine-cse.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/machine-cse.ll?rev=127649&r1=127648&r2=127649&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/machine-cse.ll (original) +++ llvm/trunk/test/CodeGen/X86/machine-cse.ll Mon Mar 14 21:22:10 2011 @@ -6,11 +6,11 @@ %struct.s2 = type { i32, i8*, i8*, [256 x %struct.s1*], [8 x i32], i64, i8*, i32, i64, i64, i32, %struct.s3*, %struct.s3*, [49 x i64] } %struct.s3 = type { %struct.s3*, %struct.s3*, i32, i32, i32 } -define fastcc i8* @t(i64 %size) nounwind { +define fastcc i8* @t(i32 %base) nounwind { entry: ; CHECK: t: ; CHECK: leaq (%rax,%rax,4) - %0 = zext i32 undef to i64 + %0 = zext i32 %base to i64 %1 = getelementptr inbounds %struct.s2* null, i64 %0 br i1 undef, label %bb1, label %bb2 From eli.friedman at gmail.com Mon Mar 14 21:23:35 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Tue, 15 Mar 2011 02:23:35 -0000 Subject: [llvm-commits] [llvm] r127650 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/UnreachableEliminate.ll Message-ID: <20110315022335.E84602A6C12C@llvm.org> Author: efriedma Date: Mon Mar 14 21:23:35 2011 New Revision: 127650 URL: http://llvm.org/viewvc/llvm-project?rev=127650&view=rev Log: PR9450: Make switch optimization in SimplifyCFG not dependent on the ordering of pointers in an std::map. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=127650&r1=127649&r2=127650&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Mar 14 21:23:35 2011 @@ -2211,17 +2211,28 @@ // If the default value is unreachable, figure out the most popular // destination and make it the default. if (SI->getSuccessor(0) == BB) { - std::map Popularity; - for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) - Popularity[SI->getSuccessor(i)]++; - + std::map > Popularity; + for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) { + std::pair& entry = + Popularity[SI->getSuccessor(i)]; + if (entry.first == 0) { + entry.first = 1; + entry.second = i; + } else { + entry.first++; + } + } + // Find the most popular block. unsigned MaxPop = 0; + unsigned MaxIndex = 0; BasicBlock *MaxBlock = 0; - for (std::map::iterator + for (std::map >::iterator I = Popularity.begin(), E = Popularity.end(); I != E; ++I) { - if (I->second > MaxPop) { - MaxPop = I->second; + if (I->second.first > MaxPop || + (I->second.first == MaxPop && MaxIndex > I->second.second)) { + MaxPop = I->second.first; + MaxIndex = I->second.second; MaxBlock = I->first; } } Modified: llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll?rev=127650&r1=127649&r2=127650&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll Mon Mar 14 21:23:35 2011 @@ -1,33 +1,73 @@ -; RUN: opt < %s -simplifycfg -S | not grep unreachable +; RUN: opt < %s -simplifycfg -S | FileCheck %s define void @test1(i1 %C, i1* %BP) { +; CHECK: @test1 +; CHECK: entry: +; CHECK-NEXT: ret void +entry: br i1 %C, label %T, label %F -T: ; preds = %0 +T: store i1 %C, i1* %BP unreachable -F: ; preds = %0 +F: ret void } define void @test2() { +; CHECK: @test2 +; CHECK: entry: +; CHECK-NEXT: call void @test2() +; CHECK-NEXT: ret void +entry: invoke void @test2( ) to label %N unwind label %U -U: ; preds = %0 +U: unreachable -N: ; preds = %0 +N: ret void } define i32 @test3(i32 %v) { +; CHECK: @test3 +; CHECK: entry: +; CHECK-NEXT: [[CMP:%[A-Za-z0-9]+]] = icmp eq i32 %v, 2 +; CHECK-NEXT: select i1 [[CMP]], i32 2, i32 1 +; CHECK-NEXT: ret +entry: switch i32 %v, label %default [ i32 1, label %U i32 2, label %T ] -default: ; preds = %0 +default: ret i32 1 -U: ; preds = %0 +U: unreachable -T: ; preds = %0 +T: ret i32 2 } +; PR9450 +define i32 @test4(i32 %v) { +; CHECK: entry: +; CHECK-NEXT: switch i32 %v, label %T [ +; CHECK-NEXT: i32 3, label %V +; CHECK-NEXT: i32 2, label %U +; CHECK-NEXT: ] + +entry: + br label %SWITCH +V: + ret i32 7 +SWITCH: + switch i32 %v, label %default [ + i32 1, label %T + i32 2, label %U + i32 3, label %V + ] +default: + unreachable +U: + ret i32 1 +T: + ret i32 2 +} From evan.cheng at apple.com Mon Mar 14 21:36:09 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 14 Mar 2011 19:36:09 -0700 Subject: [llvm-commits] [llvm] r127518 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-pred.ll In-Reply-To: References: <20110312010929.82F192A6C12C@llvm.org> Message-ID: On Mar 11, 2011, at 7:39 PM, Jim Grosbach wrote: > > On Mar 11, 2011, at 5:09 PM, Eric Christopher wrote: > >> Author: echristo >> Date: Fri Mar 11 19:09:29 2011 >> New Revision: 127518 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127518&view=rev >> Log: >> Sometimes isPredicable lies to us and tells us we don't need the operands. >> Go ahead and add them on when we might want to use them and let >> later passes remove them. >> > > I agree this will fix the crash, but have to confess it kinda makes me a bit squirmy. If the instruction isn't predicable, it shouldn't have the operands. Is there no way we can tell the backend directly that some NEON instructions really aren't predicable? Note: I have not looked deeply into how predication+NEON is handled, so that could easily be anywhere from "trivial" to "holy crap hard" in complexity to do. I'm purely talking from the perspective of what I'd like to see at a high level. As you described it: the compiler shouldn't lie to itself. I believe the solution should to to change isPredicable to something like hasPredicateOperand. And then add TargetInstrInfo::isPredicable() to a target hook. The ARM version should return false when it's NEON and Thumb2. The only place that should check for isPredicable() instead of hasPredicateOperand() would be the if-converter. Can one of you file a bug for this clean up? Thanks, Evan > >> Fixes rdar://9118569 >> >> Added: >> llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll >> Modified: >> llvm/trunk/lib/Target/ARM/ARMFastISel.cpp >> >> Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=127518&r1=127517&r2=127518&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Fri Mar 11 19:09:29 2011 >> @@ -123,14 +123,15 @@ >> const TargetRegisterClass *RC, >> unsigned Op0, bool Op0IsKill, >> const ConstantFP *FPImm); >> - virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode, >> - const TargetRegisterClass *RC, >> - uint64_t Imm); >> virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode, >> const TargetRegisterClass *RC, >> unsigned Op0, bool Op0IsKill, >> unsigned Op1, bool Op1IsKill, >> uint64_t Imm); >> + virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode, >> + const TargetRegisterClass *RC, >> + uint64_t Imm); >> + >> virtual unsigned FastEmitInst_extractsubreg(MVT RetVT, >> unsigned Op0, bool Op0IsKill, >> uint32_t Idx); >> @@ -193,6 +194,7 @@ >> >> // OptionalDef handling routines. >> private: >> + bool isARMNEONPred(const MachineInstr *MI); >> bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR); >> const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB); >> void AddLoadStoreOperands(EVT VT, Address &Addr, >> @@ -221,6 +223,21 @@ >> return true; >> } >> >> +bool ARMFastISel::isARMNEONPred(const MachineInstr *MI) { >> + const TargetInstrDesc &TID = MI->getDesc(); >> + >> + // If we're a thumb2 or not NEON function we were handled via isPredicable. >> + if ((TID.TSFlags & ARMII::DomainMask) != ARMII::DomainNEON || >> + AFI->isThumb2Function()) >> + return false; >> + >> + for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) >> + if (TID.OpInfo[i].isPredicate()) >> + return true; >> + >> + return false; >> +} >> + >> // If the machine is predicable go ahead and add the predicate operands, if >> // it needs default CC operands add those. >> // TODO: If we want to support thumb1 then we'll need to deal with optional >> @@ -230,10 +247,12 @@ >> ARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) { >> MachineInstr *MI = &*MIB; >> >> - // Do we use a predicate? >> - if (TII.isPredicable(MI)) >> + // Do we use a predicate? or... >> + // Are we NEON in ARM mode and have a predicate operand? If so, I know >> + // we're not predicable but add it anyways. >> + if (TII.isPredicable(MI) || isARMNEONPred(MI)) >> AddDefaultPred(MIB); >> - >> + >> // Do we optionally set a predicate? Preds is size > 0 iff the predicate >> // defines CPSR. All other OptionalDefines in ARM are the CCR register. >> bool CPSR = false; >> >> Added: llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll?rev=127518&view=auto >> ============================================================================== >> --- llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll (added) >> +++ llvm/trunk/test/CodeGen/ARM/fast-isel-pred.ll Fri Mar 11 19:09:29 2011 >> @@ -0,0 +1,60 @@ >> +; ModuleID = 'test.c' >> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64-n32" >> +target triple = "armv7-apple-darwin" >> + > On the completely nitpicky side, is the test really Darwin specific? Either way, the datalayout and triple lines aren't really necessary. Just passing -march/-mtriple and -mcpu to llc in the RUN line is more consistent with the rest of the tests. > > This was code-gen OK before, but failed when trying to assemble due to an invalid instruction (predicate on a non-predicable instruction), right? If so, this test won't catch that as it doesn't try to assemble the assembly file. Adding a CHECK-NOT for the particular instruction that was bogus and a CHECK for what it actually should be would be good. > > > >> +define i32 @main() nounwind ssp { >> +entry: >> + %retval = alloca i32, align 4 >> + %X = alloca <4 x i32>, align 16 >> + %Y = alloca <4 x float>, align 16 >> + store i32 0, i32* %retval >> + %tmp = load <4 x i32>* %X, align 16 >> + call void @__aa(<4 x i32> %tmp, i8* null, i32 3, <4 x float>* %Y) >> + %0 = load i32* %retval >> + ret i32 %0 >> +} >> + >> +define internal void @__aa(<4 x i32> %v, i8* %p, i32 %offset, <4 x float>* %constants) nounwind inlinehint ssp { >> +entry: >> + %__a.addr.i = alloca <4 x i32>, align 16 >> + %v.addr = alloca <4 x i32>, align 16 >> + %p.addr = alloca i8*, align 4 >> + %offset.addr = alloca i32, align 4 >> + %constants.addr = alloca <4 x float>*, align 4 >> + store <4 x i32> %v, <4 x i32>* %v.addr, align 16 >> + store i8* %p, i8** %p.addr, align 4 >> + store i32 %offset, i32* %offset.addr, align 4 >> + store <4 x float>* %constants, <4 x float>** %constants.addr, align 4 >> + %tmp = load <4 x i32>* %v.addr, align 16 >> + store <4 x i32> %tmp, <4 x i32>* %__a.addr.i, align 16 >> + %tmp.i = load <4 x i32>* %__a.addr.i, align 16 >> + %0 = bitcast <4 x i32> %tmp.i to <16 x i8> >> + %1 = bitcast <16 x i8> %0 to <4 x i32> >> + %vcvt.i = sitofp <4 x i32> %1 to <4 x float> >> + %tmp1 = load i8** %p.addr, align 4 >> + %tmp2 = load i32* %offset.addr, align 4 >> + %tmp3 = load <4 x float>** %constants.addr, align 4 >> + call void @__bb(<4 x float> %vcvt.i, i8* %tmp1, i32 %tmp2, <4 x float>* %tmp3) >> + ret void >> +} >> + >> +define internal void @__bb(<4 x float> %v, i8* %p, i32 %offset, <4 x float>* %constants) nounwind inlinehint ssp { >> +entry: >> + %v.addr = alloca <4 x float>, align 16 >> + %p.addr = alloca i8*, align 4 >> + %offset.addr = alloca i32, align 4 >> + %constants.addr = alloca <4 x float>*, align 4 >> + %data = alloca i64, align 4 >> + store <4 x float> %v, <4 x float>* %v.addr, align 16 >> + store i8* %p, i8** %p.addr, align 4 >> + store i32 %offset, i32* %offset.addr, align 4 >> + store <4 x float>* %constants, <4 x float>** %constants.addr, align 4 >> + %tmp = load i64* %data, align 4 >> + %tmp1 = load i8** %p.addr, align 4 >> + %tmp2 = load i32* %offset.addr, align 4 >> + %add.ptr = getelementptr i8* %tmp1, i32 %tmp2 >> + %0 = bitcast i8* %add.ptr to i64* >> + %arrayidx = getelementptr inbounds i64* %0, i32 0 >> + store i64 %tmp, i64* %arrayidx >> + ret void >> +} >> > > > > Not a huge deal, but seems a bit largish for this sort of test. Does it reduce down at all? I would, perhaps naively, expect that a conditional followed by the vcvt (sitofp <4 x i32> %1 to <4 x float>) would do the trick. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From ajclinto at gmail.com Mon Mar 14 22:43:13 2011 From: ajclinto at gmail.com (Andrew Clinton) Date: Mon, 14 Mar 2011 23:43:13 -0400 Subject: [llvm-commits] LCSSA avoiding creation of unused PHI nodes Message-ID: This is a patch to avoid the creation of unused PHI nodes in the LCSSA pass. Anyone willing to review/commit? Andrew -------------- next part -------------- A non-text attachment was scrubbed... Name: lcssa_unused_phis.diff Type: text/x-patch Size: 1661 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110314/39463240/attachment.bin From zwarich at apple.com Mon Mar 14 22:50:13 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 14 Mar 2011 20:50:13 -0700 Subject: [llvm-commits] LCSSA avoiding creation of unused PHI nodes In-Reply-To: References: Message-ID: <56862D77-CAFB-4F21-993F-AEEE4017D9E2@apple.com> I would add a test for this. Also, AvailablePHIs is a bit of a vague name. Maybe AddedPHIs would be better? Other than that, it looks good. Cameron From aggarwa4 at illinois.edu Mon Mar 14 22:48:09 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 15 Mar 2011 03:48:09 -0000 Subject: [llvm-commits] [poolalloc] r127658 - /poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Message-ID: <20110315034809.724562A6C12C@llvm.org> Author: aggarwa4 Date: Mon Mar 14 22:48:09 2011 New Revision: 127658 URL: http://llvm.org/viewvc/llvm-project?rev=127658&view=rev Log: Updated header. Thanks Will! Modified: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Modified: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp?rev=127658&r1=127657&r2=127658&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp (original) +++ poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Mon Mar 14 22:48:09 2011 @@ -1,4 +1,4 @@ -//===-- VarArgsFunc.cpp - Simplify calls to bitcasted const funcs --------===// +//===-- AllocatorIdentification.cpp - Identify wrappers to allocators -----===// // // The LLVM Compiler Infrastructure // From ajclinto at gmail.com Mon Mar 14 23:18:03 2011 From: ajclinto at gmail.com (Andrew Clinton) Date: Tue, 15 Mar 2011 00:18:03 -0400 Subject: [llvm-commits] LCSSA avoiding creation of unused PHI nodes In-Reply-To: <56862D77-CAFB-4F21-993F-AEEE4017D9E2@apple.com> References: <56862D77-CAFB-4F21-993F-AEEE4017D9E2@apple.com> Message-ID: Thanks for the review - here is the update. Could you also review/commit the updated loop-simplify patch that I send to the llvm-commits list? On Mon, Mar 14, 2011 at 11:50 PM, Cameron Zwarich wrote: > I would add a test for this. Also, AvailablePHIs is a bit of a vague name. Maybe AddedPHIs would be better? Other than that, it looks good. > > Cameron -------------- next part -------------- A non-text attachment was scrubbed... Name: lcssa_unused_phis.diff Type: text/x-patch Size: 2578 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110315/b17d17e4/attachment.bin From zwarich at apple.com Mon Mar 14 23:24:14 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 14 Mar 2011 21:24:14 -0700 Subject: [llvm-commits] LCSSA avoiding creation of unused PHI nodes In-Reply-To: References: <56862D77-CAFB-4F21-993F-AEEE4017D9E2@apple.com> Message-ID: Sorry to be a pain, but do you want to use the new FileCheck style of test here? I will try to take a look at the LoopSimplify patch later today or tomorrow. There was something I wanted to test with it. It is unfortunate that block layout is so brittle right now, but that's the way it is for the time being. Cameron On Mar 14, 2011, at 9:18 PM, Andrew Clinton wrote: > Thanks for the review - here is the update. > > Could you also review/commit the updated loop-simplify patch that I > send to the llvm-commits list? > > On Mon, Mar 14, 2011 at 11:50 PM, Cameron Zwarich wrote: >> I would add a test for this. Also, AvailablePHIs is a bit of a vague name. Maybe AddedPHIs would be better? Other than that, it looks good. >> >> Cameron > From evan.cheng at apple.com Tue Mar 15 00:09:26 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 15 Mar 2011 05:09:26 -0000 Subject: [llvm-commits] [llvm] r127667 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrDesc.h utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/CodeGenInstruction.cpp utils/TableGen/CodeGenInstruction.h utils/TableGen/InstrInfoEmitter.cpp Message-ID: <20110315050926.4F38A2A6C12C@llvm.org> Author: evancheng Date: Tue Mar 15 00:09:26 2011 New Revision: 127667 URL: http://llvm.org/viewvc/llvm-project?rev=127667&view=rev Log: - Add "Bitcast" target instruction property for instructions which perform nothing more than a bitcast. - Teach tablegen to automatically infer "Bitcast" property. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/include/llvm/Target/TargetInstrDesc.h llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/CodeGenInstruction.cpp llvm/trunk/utils/TableGen/CodeGenInstruction.h llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=127667&r1=127666&r2=127667&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Tue Mar 15 00:09:26 2011 @@ -200,6 +200,7 @@ bit isIndirectBranch = 0; // Is this instruction an indirect branch? bit isCompare = 0; // Is this instruction a comparison instruction? bit isMoveImm = 0; // Is this instruction a move immediate instruction? + bit isBitcast = 0; // Is this instruction a bitcast instruction? bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=127667&r1=127666&r2=127667&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Tue Mar 15 00:09:26 2011 @@ -105,6 +105,7 @@ IndirectBranch, Compare, MoveImm, + Bitcast, DelaySlot, FoldableAsLoad, MayLoad, @@ -358,6 +359,12 @@ bool isMoveImmediate() const { return Flags & (1 << TID::MoveImm); } + + /// isBitcast - Return true if this instruction is a bitcast instruction. + /// + bool isBitcast() const { + return Flags & (1 << TID::Bitcast); + } /// isNotDuplicable - Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=127667&r1=127666&r2=127667&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Tue Mar 15 00:09:26 2011 @@ -2288,13 +2288,14 @@ const CodeGenDAGPatterns &CDP; bool &mayStore; bool &mayLoad; + bool &IsBitcast; bool &HasSideEffects; bool &IsVariadic; public: InstAnalyzer(const CodeGenDAGPatterns &cdp, - bool &maystore, bool &mayload, bool &hse, bool &isv) - : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse), - IsVariadic(isv) { + bool &maystore, bool &mayload, bool &isbc, bool &hse, bool &isv) + : CDP(cdp), mayStore(maystore), mayLoad(mayload), IsBitcast(isbc), + HasSideEffects(hse), IsVariadic(isv) { } /// Analyze - Analyze the specified instruction, returning true if the @@ -2313,6 +2314,29 @@ } private: + bool IsNodeBitcast(const TreePatternNode *N) const { + if (HasSideEffects || mayLoad || mayStore || IsVariadic) + return false; + + if (N->getNumChildren() != 2) + return false; + + const TreePatternNode *N0 = N->getChild(0); + if (!N0->isLeaf() || !dynamic_cast(N0->getLeafValue())) + return false; + + const TreePatternNode *N1 = N->getChild(1); + if (N1->isLeaf()) + return false; + if (N1->getNumChildren() != 1 || !N1->getChild(0)->isLeaf()) + return false; + + const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N1->getOperator()); + if (OpInfo.getNumResults() != 1 || OpInfo.getNumOperands() != 1) + return false; + return OpInfo.getEnumName() == "ISD::BITCAST"; + } + void AnalyzeNode(const TreePatternNode *N) { if (N->isLeaf()) { if (DefInit *DI = dynamic_cast(N->getLeafValue())) { @@ -2333,8 +2357,10 @@ AnalyzeNode(N->getChild(i)); // Ignore set nodes, which are not SDNodes. - if (N->getOperator()->getName() == "set") + if (N->getOperator()->getName() == "set") { + IsBitcast = IsNodeBitcast(N); return; + } // Get information about the SDNode for the operator. const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator()); @@ -2363,12 +2389,13 @@ static void InferFromPattern(const CodeGenInstruction &Inst, bool &MayStore, bool &MayLoad, + bool &IsBitcast, bool &HasSideEffects, bool &IsVariadic, const CodeGenDAGPatterns &CDP) { - MayStore = MayLoad = HasSideEffects = IsVariadic = false; + MayStore = MayLoad = IsBitcast = HasSideEffects = IsVariadic = false; bool HadPattern = - InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects, IsVariadic) + InstAnalyzer(CDP, MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic) .Analyze(Inst.TheDef); // InstAnalyzer only correctly analyzes mayStore/mayLoad so far. @@ -2714,11 +2741,12 @@ CodeGenInstruction &InstInfo = const_cast(*Instructions[i]); // Determine properties of the instruction from its pattern. - bool MayStore, MayLoad, HasSideEffects, IsVariadic; - InferFromPattern(InstInfo, MayStore, MayLoad, HasSideEffects, IsVariadic, - *this); + bool MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic; + InferFromPattern(InstInfo, MayStore, MayLoad, IsBitcast, + HasSideEffects, IsVariadic, *this); InstInfo.mayStore = MayStore; InstInfo.mayLoad = MayLoad; + InstInfo.isBitcast = IsBitcast; InstInfo.hasSideEffects = HasSideEffects; InstInfo.Operands.isVariadic = IsVariadic; } Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=127667&r1=127666&r2=127667&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Tue Mar 15 00:09:26 2011 @@ -288,6 +288,7 @@ isIndirectBranch = R->getValueAsBit("isIndirectBranch"); isCompare = R->getValueAsBit("isCompare"); isMoveImm = R->getValueAsBit("isMoveImm"); + isBitcast = R->getValueAsBit("isBitcast"); isBarrier = R->getValueAsBit("isBarrier"); isCall = R->getValueAsBit("isCall"); canFoldAsLoad = R->getValueAsBit("canFoldAsLoad"); Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=127667&r1=127666&r2=127667&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Tue Mar 15 00:09:26 2011 @@ -215,6 +215,7 @@ bool isIndirectBranch; bool isCompare; bool isMoveImm; + bool isBitcast; bool isBarrier; bool isCall; bool canFoldAsLoad; Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=127667&r1=127666&r2=127667&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Tue Mar 15 00:09:26 2011 @@ -272,6 +272,7 @@ if (Inst.isIndirectBranch) OS << "|(1< References: <56862D77-CAFB-4F21-993F-AEEE4017D9E2@apple.com> Message-ID: No problem. Here is the updated patch. On Tue, Mar 15, 2011 at 12:24 AM, Cameron Zwarich wrote: > Sorry to be a pain, but do you want to use the new FileCheck style of test here? > > I will try to take a look at the LoopSimplify patch later today or tomorrow. There was something I wanted to test with it. It is unfortunate that block layout is so brittle right now, but that's the way it is for the time being. > > Cameron > > On Mar 14, 2011, at 9:18 PM, Andrew Clinton wrote: > >> Thanks for the review - here is the update. >> >> Could you also review/commit the updated loop-simplify patch that I >> send to the llvm-commits list? >> >> On Mon, Mar 14, 2011 at 11:50 PM, Cameron Zwarich wrote: >>> I would add a test for this. Also, AvailablePHIs is a bit of a vague name. Maybe AddedPHIs would be better? Other than that, it looks good. >>> >>> Cameron >> > > -------------- next part -------------- A non-text attachment was scrubbed... Name: lcssa_unused_phis.diff Type: text/x-patch Size: 2591 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110315/a9b16644/attachment.bin From evan.cheng at apple.com Tue Mar 15 00:13:13 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 15 Mar 2011 05:13:13 -0000 Subject: [llvm-commits] [llvm] r127668 - in /llvm/trunk: lib/CodeGen/PeepholeOptimizer.cpp test/CodeGen/ARM/peephole-bitcast.ll Message-ID: <20110315051313.9B9072A6C12C@llvm.org> Author: evancheng Date: Tue Mar 15 00:13:13 2011 New Revision: 127668 URL: http://llvm.org/viewvc/llvm-project?rev=127668&view=rev Log: Add a peephole optimization to optimize pairs of bitcasts. e.g. v2 = bitcast v1 ... v3 = bitcast v2 ... = v3 => v2 = bitcast v1 ... = v1 if v1 and v3 are of in the same register class. bitcast between i32 and fp (and others) are often not nops since they are in different register classes. These bitcast instructions are often left because they are in different basic blocks and cannot be eliminated by dag combine. rdar://9104514 Added: llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll Modified: llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp Modified: llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp?rev=127668&r1=127667&r2=127668&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp (original) +++ llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp Tue Mar 15 00:13:13 2011 @@ -30,6 +30,15 @@ // If the "sub" instruction all ready sets (or could be modified to set) the // same flag that the "cmp" instruction sets and that "bz" uses, then we can // eliminate the "cmp" instruction. +// +// - Optimize Bitcast pairs: +// +// v1 = bitcast v0 +// v2 = bitcast v1 +// = v2 +// => +// v1 = bitcast v0 +// = v0 // //===----------------------------------------------------------------------===// @@ -57,7 +66,8 @@ cl::desc("Disable the peephole optimizer")); STATISTIC(NumReuse, "Number of extension results reused"); -STATISTIC(NumEliminated, "Number of compares eliminated"); +STATISTIC(NumBitcasts, "Number of bitcasts eliminated"); +STATISTIC(NumCmps, "Number of compares eliminated"); STATISTIC(NumImmFold, "Number of move immediate foled"); namespace { @@ -85,6 +95,7 @@ } private: + bool OptimizeBitcastInstr(MachineInstr *MI, MachineBasicBlock *MBB); bool OptimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB); bool OptimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB, SmallPtrSet &LocalMIs); @@ -243,12 +254,85 @@ return Changed; } +/// OptimizeBitcastInstr - If the instruction is a bitcast instruction A that +/// cannot be optimized away during isel (e.g. ARM::VMOVSR, which bitcast +/// a value cross register classes), and the source is defined by another +/// bitcast instruction B. And if the register class of source of B matches +/// the register class of instruction A, then it is legal to replace all uses +/// of the def of A with source of B. e.g. +/// %vreg0 = VMOVSR %vreg1 +/// %vreg3 = VMOVRS %vreg0 +/// Replace all uses of vreg3 with vreg1. + +bool PeepholeOptimizer::OptimizeBitcastInstr(MachineInstr *MI, + MachineBasicBlock *MBB) { + unsigned NumDefs = MI->getDesc().getNumDefs(); + unsigned NumSrcs = MI->getDesc().getNumOperands() - NumDefs; + if (NumDefs != 1) + return false; + + unsigned Def = 0; + unsigned Src = 0; + for (unsigned i = 0, e = NumDefs + NumSrcs; i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (MO.isDef()) + Def = Reg; + else if (Src) + // Multiple sources? + return false; + else + Src = Reg; + } + + assert(Def && Src && "Malformed bitcast instruction!"); + + MachineInstr *DefMI = MRI->getVRegDef(Src); + if (!DefMI || !DefMI->getDesc().isBitcast()) + return false; + + unsigned SrcDef = 0; + unsigned SrcSrc = 0; + NumDefs = DefMI->getDesc().getNumDefs(); + NumSrcs = DefMI->getDesc().getNumOperands() - NumDefs; + if (NumDefs != 1) + return false; + for (unsigned i = 0, e = NumDefs + NumSrcs; i != e; ++i) { + const MachineOperand &MO = DefMI->getOperand(i); + if (!MO.isReg() || MO.isDef()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (MO.isDef()) + SrcDef = Reg; + else if (SrcSrc) + // Multiple sources? + return false; + else + SrcSrc = Reg; + } + + if (MRI->getRegClass(SrcSrc) != MRI->getRegClass(Def)) + return false; + + MRI->replaceRegWith(Def, SrcSrc); + MRI->clearKillFlags(SrcSrc); + MI->eraseFromParent(); + ++NumBitcasts; + return true; +} + /// OptimizeCmpInstr - If the instruction is a compare and the previous /// instruction it's comparing against all ready sets (or could be modified to /// set) the same flag as the compare, then we can remove the comparison and use /// the flag from the previous instruction. bool PeepholeOptimizer::OptimizeCmpInstr(MachineInstr *MI, - MachineBasicBlock *MBB){ + MachineBasicBlock *MBB) { // If this instruction is a comparison against zero and isn't comparing a // physical register, we can try to optimize it. unsigned SrcReg; @@ -259,7 +343,7 @@ // Attempt to optimize the comparison instruction. if (TII->OptimizeCompareInstr(MI, SrcReg, CmpMask, CmpValue, MRI)) { - ++NumEliminated; + ++NumCmps; return true; } @@ -345,7 +429,16 @@ continue; } - if (MI->getDesc().isCompare()) { + const TargetInstrDesc &TID = MI->getDesc(); + + if (TID.isBitcast()) { + if (OptimizeBitcastInstr(MI, MBB)) { + // MI is deleted. + Changed = true; + MII = First ? I->begin() : llvm::next(PMII); + continue; + } + } else if (TID.isCompare()) { if (OptimizeCmpInstr(MI, MBB)) { // MI is deleted. Changed = true; Added: llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll?rev=127668&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll (added) +++ llvm/trunk/test/CodeGen/ARM/peephole-bitcast.ll Tue Mar 15 00:13:13 2011 @@ -0,0 +1,23 @@ +; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s + +; vmov s0, r0 + vmov r0, s0 should have been optimized away. +; rdar://9104514 + +define void @t(float %x) nounwind ssp { +entry: +; CHECK: t: +; CHECK-NOT: vmov +; CHECK: bl + %0 = bitcast float %x to i32 + %cmp = icmp ult i32 %0, 2139095039 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + tail call void @doSomething(float %x) nounwind + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +declare void @doSomething(float) From bob.wilson at apple.com Tue Mar 15 01:04:10 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 14 Mar 2011 23:04:10 -0700 Subject: [llvm-commits] [llvm] r127630 - in /llvm/trunk: lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h test/CodeGen/ARM/vext.ll In-Reply-To: <20110314230238.AC3CF2A6C12C@llvm.org> References: <20110314230238.AC3CF2A6C12C@llvm.org> Message-ID: <4BE24910-ABB6-435B-98EA-8917490B2751@apple.com> On Mar 14, 2011, at 4:02 PM, Bill Wendling wrote: > Author: void > Date: Mon Mar 14 18:02:38 2011 > New Revision: 127630 > > URL: http://llvm.org/viewvc/llvm-project?rev=127630&view=rev > Log: > Generate a VTBL instruction instead of a series of loads and stores when we > can. You need to update ARMTargetLowering::isShuffleMaskLegal to show that all v8i8 shuffles are legal. Other comments below.... > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127630&r1=127629&r2=127630&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Mar 14 18:02:38 2011 > @@ -852,6 +852,10 @@ > case ARMISD::VZIP: return "ARMISD::VZIP"; > case ARMISD::VUZP: return "ARMISD::VUZP"; > case ARMISD::VTRN: return "ARMISD::VTRN"; > + case ARMISD::VTBL1: return "ARMISD::VTBL1"; > + case ARMISD::VTBL2: return "ARMISD::VTBL2"; > + case ARMISD::VTBL3: return "ARMISD::VTBL3"; > + case ARMISD::VTBL4: return "ARMISD::VTBL4"; Since you're only using VTBL1 and VTBL2, there's no need for the 3 & 4 versions. > case ARMISD::VMULLs: return "ARMISD::VMULLs"; > case ARMISD::VMULLu: return "ARMISD::VMULLu"; > case ARMISD::BUILD_VECTOR: return "ARMISD::BUILD_VECTOR"; > @@ -4055,6 +4059,29 @@ > } > } > > +static SDValue LowerVECTOR_SHUFFLEv8i8(SDValue Op, > + SmallVectorImpl &ShuffleMask, > + SelectionDAG &DAG) { > + // Check to see if we can use the VTBL instruction. > + SDValue V1 = Op.getOperand(0); > + SDValue V2 = Op.getOperand(1); > + DebugLoc DL = Op.getDebugLoc(); > + > + SmallVector VTBLMask; > + for (SmallVectorImpl::iterator > + I = ShuffleMask.begin(), E = ShuffleMask.end(); I != E; ++I) > + VTBLMask.push_back(DAG.getConstant(*I, MVT::i32)); > + > + if (V2.getNode()->getOpcode() == ISD::UNDEF) > + return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1, > + DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, > + &VTBLMask[0], 8)); > + else There's no need for that "else". > + return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2, > + DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, > + &VTBLMask[0], 8)); > +} > + > static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { > SDValue V1 = Op.getOperand(0); > SDValue V2 = Op.getOperand(1); > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=127630&r1=127629&r2=127630&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Mon Mar 14 18:02:38 2011 > @@ -153,6 +153,10 @@ > VZIP, // zip (interleave) > VUZP, // unzip (deinterleave) > VTRN, // transpose > + VTBL1, // 1-register shuffle with mask > + VTBL2, // 2-register shuffle with mask > + VTBL3, // 3-register shuffle with mask > + VTBL4, // 4-register shuffle with mask See comment above about VTBL3 and VTBL4. > > // Vector multiply long: > VMULLs, // ...signed > > Modified: llvm/trunk/test/CodeGen/ARM/vext.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vext.ll?rev=127630&r1=127629&r2=127630&view=diff > ============================================================================== > --- llvm/trunk/test/CodeGen/ARM/vext.ll (original) > +++ llvm/trunk/test/CodeGen/ARM/vext.ll Mon Mar 14 18:02:38 2011 > @@ -121,15 +121,3 @@ > %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <4 x i32> > ret <4 x i16> %tmp2 > } > - > -; The actual shuffle code only handles some cases, make sure we check > -; this rather than blindly emitting a VECTOR_SHUFFLE (infinite > -; lowering loop can result otherwise). > -define <8 x i8> @test_illegal(<16 x i8>* %A, <16 x i8>* %B) nounwind { > -;CHECK: test_illegal: > -;CHECK: vst1.8 > - %tmp1 = load <16 x i8>* %A > - %tmp2 = load <16 x i8>* %B > - %tmp3 = shufflevector <16 x i8> %tmp1, <16 x i8> %tmp2, <8 x i32> > - ret <8 x i8> %tmp3 > -} Instead of removing this testcase, can you change it to test an illegal v8i16 shuffle? From nicholas at mxc.ca Tue Mar 15 02:31:33 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 15 Mar 2011 07:31:33 -0000 Subject: [llvm-commits] [llvm] r127673 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Message-ID: <20110315073133.23F762A6C12D@llvm.org> Author: nicholas Date: Tue Mar 15 02:31:32 2011 New Revision: 127673 URL: http://llvm.org/viewvc/llvm-project?rev=127673&view=rev Log: Add C++ global operator {new,new[],delete,delete[]}(unsigned {int,long}) to the memory builtins as equivalent to malloc/free. This is different from any attribute we have. For example, you can delete the allocators when their result is unused, but you can't collapse two calls to the same function, even if no global/memory state has changed in between. The noalias return states that the result does not alias any other pointer, but instcombine optimizes malloc() as though the result is non-null for the purpose of eliminating unused pointers. Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=127673&r1=127672&r2=127673&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Tue Mar 15 02:31:32 2011 @@ -35,7 +35,11 @@ return false; Function *Callee = CI->getCalledFunction(); - if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "malloc") + if (Callee == 0 || !Callee->isDeclaration()) + return false; + if (Callee->getName() != "malloc" && + Callee->getName() != "_Znwj" && Callee->getName() != "_Znwm" && + Callee->getName() != "_Znaj" && Callee->getName() != "_Znam") return false; // Check malloc prototype. @@ -189,7 +193,12 @@ if (!CI) return 0; Function *Callee = CI->getCalledFunction(); - if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "free") + if (Callee == 0 || !Callee->isDeclaration()) + return 0; + + if (Callee->getName() != "free" && + Callee->getName() != "_Zdlj" && Callee->getName() != "_Zdlm" && + Callee->getName() != "_Zdaj" && Callee->getName() != "_Zdam") return 0; // Check free prototype. From zwarich at apple.com Tue Mar 15 02:41:25 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 15 Mar 2011 07:41:25 -0000 Subject: [llvm-commits] [llvm] r127674 - in /llvm/trunk: lib/Transforms/Utils/LCSSA.cpp test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll test/Transforms/LCSSA/unused-phis.ll Message-ID: <20110315074125.9B3542A6C12D@llvm.org> Author: zwarich Date: Tue Mar 15 02:41:25 2011 New Revision: 127674 URL: http://llvm.org/viewvc/llvm-project?rev=127674&view=rev Log: Do not add PHIs with no users when creating LCSSA form. Patch by Andrew Clinton. Added: llvm/trunk/test/Transforms/LCSSA/unused-phis.ll Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp llvm/trunk/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=127674&r1=127673&r2=127674&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Tue Mar 15 02:41:25 2011 @@ -207,6 +207,8 @@ DomTreeNode *DomNode = DT->getNode(DomBB); + SmallVector AddedPHIs; + SSAUpdater SSAUpdate; SSAUpdate.Initialize(Inst->getType(), Inst->getName()); @@ -236,6 +238,8 @@ &PN->getOperandUse( PN->getOperandNumForIncomingValue(PN->getNumIncomingValues()-1))); } + + AddedPHIs.push_back(PN); // Remember that this phi makes the value alive in this block. SSAUpdate.AddAvailableValue(ExitBB, PN); @@ -262,6 +266,12 @@ // Otherwise, do full PHI insertion. SSAUpdate.RewriteUse(*UsesToRewrite[i]); } + + // Remove PHI nodes that did not have any uses rewritten. + for (unsigned i = 0, e = AddedPHIs.size(); i != e; ++i) { + if (!AddedPHIs[i]->hasNUsesOrMore(1)) + AddedPHIs[i]->eraseFromParent(); + } return true; } Modified: llvm/trunk/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll?rev=127674&r1=127673&r2=127674&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll (original) +++ llvm/trunk/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll Tue Mar 15 02:41:25 2011 @@ -1,7 +1,5 @@ ; RUN: opt < %s -loop-simplify -lcssa -S | \ ; RUN: grep {%%SJE.0.0.lcssa = phi .struct.SetJmpMapEntry} -; RUN: opt < %s -loop-simplify -lcssa -S | \ -; RUN: grep {%%SJE.0.0.lcssa1 = phi .struct.SetJmpMapEntry} %struct.SetJmpMapEntry = type { i8*, i32, %struct.SetJmpMapEntry* } Added: llvm/trunk/test/Transforms/LCSSA/unused-phis.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LCSSA/unused-phis.ll?rev=127674&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LCSSA/unused-phis.ll (added) +++ llvm/trunk/test/Transforms/LCSSA/unused-phis.ll Tue Mar 15 02:41:25 2011 @@ -0,0 +1,38 @@ +; RUN: opt < %s -lcssa -S | FileCheck %s +; CHECK: exit1: +; CHECK: .lcssa = +; CHECK: exit2: +; CHECK: .lcssa2 = +; CHECK: exit3: +; CHECK-NOT: .lcssa1 = + +; Test to ensure that when there are multiple exit blocks, PHI nodes are +; only inserted by LCSSA when there is a use dominated by a given exit +; block. + +declare void @printf(i32 %i) + +define i32 @unused_phis() nounwind { +entry: + br label %loop + +loop: + %i = phi i32 [0, %entry], [1, %then2] + br i1 undef, label %exit1, label %then1 + +then1: + br i1 undef, label %exit2, label %then2 + +then2: + br i1 undef, label %exit3, label %loop + +exit1: + call void @printf(i32 %i) + ret i32 %i + +exit2: + ret i32 %i + +exit3: + ret i32 0 +} From baldrick at free.fr Tue Mar 15 03:41:24 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 15 Mar 2011 08:41:24 -0000 Subject: [llvm-commits] [llvm] r127675 - /llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp Message-ID: <20110315084124.8052B2A6C12C@llvm.org> Author: baldrick Date: Tue Mar 15 03:41:24 2011 New Revision: 127675 URL: http://llvm.org/viewvc/llvm-project?rev=127675&view=rev Log: Avoid a compiler warning about reg possibly being used uninitialized when building with assertions disabled. Modified: llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp Modified: llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp?rev=127675&r1=127674&r2=127675&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXISelLowering.cpp Tue Mar 15 03:41:24 2011 @@ -212,11 +212,9 @@ else if (Outs[0].VT == MVT::f32) { reg = PTX::F0; } - else if (Outs[0].VT == MVT::f64) { - reg = PTX::FD0; - } else { - assert(false && "Can return only basic types"); + assert(Outs[0].VT == MVT::f64 && "Can return only basic types"); + reg = PTX::FD0; } MachineFunction &MF = DAG.getMachineFunction(); From baldrick at free.fr Tue Mar 15 03:54:51 2011 From: baldrick at free.fr (Duncan Sands) Date: Tue, 15 Mar 2011 08:54:51 -0000 Subject: [llvm-commits] [llvm] r127676 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20110315085451.D38982A6C12C@llvm.org> Author: baldrick Date: Tue Mar 15 03:54:51 2011 New Revision: 127676 URL: http://llvm.org/viewvc/llvm-project?rev=127676&view=rev Log: Silence compiler warning about case values not being in the enumerated type MCFixupKind. This is the same technique that is used elsewhere in MC. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=127676&r1=127675&r2=127676&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Tue Mar 15 03:54:51 2011 @@ -826,7 +826,7 @@ // relocation entry in the the low 16 bits of r_address field. unsigned ThumbBit = 0; unsigned MovtBit = 0; - switch (Fixup.getKind()) { + switch ((unsigned)Fixup.getKind()) { default: break; case ARM::fixup_arm_movt_hi16: case ARM::fixup_arm_movt_hi16_pcrel: From fvbommel at gmail.com Tue Mar 15 04:46:57 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Tue, 15 Mar 2011 10:46:57 +0100 Subject: [llvm-commits] [llvm] r127674 - in /llvm/trunk: lib/Transforms/Utils/LCSSA.cpp test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll test/Transforms/LCSSA/unused-phis.ll In-Reply-To: <20110315074125.9B3542A6C12D@llvm.org> References: <20110315074125.9B3542A6C12D@llvm.org> Message-ID: On Tue, Mar 15, 2011 at 8:41 AM, Cameron Zwarich wrote: > + ?// Remove PHI nodes that did not have any uses rewritten. > + ?for (unsigned i = 0, e = AddedPHIs.size(); i != e; ++i) { > + ? ?if (!AddedPHIs[i]->hasNUsesOrMore(1)) I think use_empty() would be better than !hasNUsesOrMore(1)... > + ? ? ?AddedPHIs[i]->eraseFromParent(); > + ?} From justin.holewinski at gmail.com Tue Mar 15 08:24:15 2011 From: justin.holewinski at gmail.com (Justin Holewinski) Date: Tue, 15 Mar 2011 13:24:15 -0000 Subject: [llvm-commits] [llvm] r127677 - in /llvm/trunk: include/llvm/IntrinsicsPTX.td lib/Target/PTX/PTX.td lib/Target/PTX/PTXInstrInfo.td lib/Target/PTX/PTXIntrinsicInstrInfo.td lib/Target/PTX/PTXSubtarget.cpp lib/Target/PTX/PTXSubtarget.h test/CodeGen/PTX/intrinsic.ll test/CodeGen/PTX/options.ll Message-ID: <20110315132416.1234D2A6C12C@llvm.org> Author: jholewinski Date: Tue Mar 15 08:24:15 2011 New Revision: 127677 URL: http://llvm.org/viewvc/llvm-project?rev=127677&view=rev Log: PTX: Set PTX 2.0 as the minimum supported version - Remove PTX 1.4 code generation - Change type of intrinsics to .v4.i32 instead of .v4.i16 - Add and/or/xor integer instructions Modified: llvm/trunk/include/llvm/IntrinsicsPTX.td llvm/trunk/lib/Target/PTX/PTX.td llvm/trunk/lib/Target/PTX/PTXInstrInfo.td llvm/trunk/lib/Target/PTX/PTXIntrinsicInstrInfo.td llvm/trunk/lib/Target/PTX/PTXSubtarget.cpp llvm/trunk/lib/Target/PTX/PTXSubtarget.h llvm/trunk/test/CodeGen/PTX/intrinsic.ll llvm/trunk/test/CodeGen/PTX/options.ll Modified: llvm/trunk/include/llvm/IntrinsicsPTX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsPTX.td?rev=127677&r1=127676&r2=127677&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsPTX.td (original) +++ llvm/trunk/include/llvm/IntrinsicsPTX.td Tue Mar 15 08:24:15 2011 @@ -12,14 +12,17 @@ //===----------------------------------------------------------------------===// let TargetPrefix = "ptx" in { - // FIXME Since PTX 2.0, special registers are redefined as v4i32 type - multiclass PTXReadSpecialRegisterIntrinsic_v4i16 { - def _r64 : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>; - def _v4i16 : Intrinsic<[llvm_v4i16_ty], [], [IntrNoMem]>; - def _x : Intrinsic<[llvm_i16_ty], [], [IntrNoMem]>; - def _y : Intrinsic<[llvm_i16_ty], [], [IntrNoMem]>; - def _z : Intrinsic<[llvm_i16_ty], [], [IntrNoMem]>; - def _w : Intrinsic<[llvm_i16_ty], [], [IntrNoMem]>; + multiclass PTXReadSpecialRegisterIntrinsic_v4i32 { +// FIXME: Do we need the 128-bit integer type version? +// def _r64 : Intrinsic<[llvm_i128_ty], [], [IntrNoMem]>; + +// FIXME: Enable this once v4i32 support is enabled in back-end. +// def _v4i16 : Intrinsic<[llvm_v4i32_ty], [], [IntrNoMem]>; + + def _x : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; + def _y : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; + def _z : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; + def _w : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; } class PTXReadSpecialRegisterIntrinsic_r32 @@ -29,15 +32,15 @@ : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>; } -defm int_ptx_read_tid : PTXReadSpecialRegisterIntrinsic_v4i16; -defm int_ptx_read_ntid : PTXReadSpecialRegisterIntrinsic_v4i16; +defm int_ptx_read_tid : PTXReadSpecialRegisterIntrinsic_v4i32; +defm int_ptx_read_ntid : PTXReadSpecialRegisterIntrinsic_v4i32; def int_ptx_read_laneid : PTXReadSpecialRegisterIntrinsic_r32; def int_ptx_read_warpid : PTXReadSpecialRegisterIntrinsic_r32; def int_ptx_read_nwarpid : PTXReadSpecialRegisterIntrinsic_r32; -defm int_ptx_read_ctaid : PTXReadSpecialRegisterIntrinsic_v4i16; -defm int_ptx_read_nctaid : PTXReadSpecialRegisterIntrinsic_v4i16; +defm int_ptx_read_ctaid : PTXReadSpecialRegisterIntrinsic_v4i32; +defm int_ptx_read_nctaid : PTXReadSpecialRegisterIntrinsic_v4i32; def int_ptx_read_smid : PTXReadSpecialRegisterIntrinsic_r32; def int_ptx_read_nsmid : PTXReadSpecialRegisterIntrinsic_r32; Modified: llvm/trunk/lib/Target/PTX/PTX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTX.td?rev=127677&r1=127676&r2=127677&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTX.td (original) +++ llvm/trunk/lib/Target/PTX/PTX.td Tue Mar 15 08:24:15 2011 @@ -29,17 +29,18 @@ //===- PTX Version --------------------------------------------------------===// -def FeaturePTX14 : SubtargetFeature<"ptx14", "PTXVersion", "PTX_VERSION_1_4", - "Use PTX Language Version 1.4">; - def FeaturePTX20 : SubtargetFeature<"ptx20", "PTXVersion", "PTX_VERSION_2_0", "Use PTX Language Version 2.0", - [FeaturePTX14]>; + []>; def FeaturePTX21 : SubtargetFeature<"ptx21", "PTXVersion", "PTX_VERSION_2_1", "Use PTX Language Version 2.1", [FeaturePTX20]>; +def FeaturePTX22 : SubtargetFeature<"ptx22", "PTXVersion", "PTX_VERSION_2_2", + "Use PTX Language Version 2.2", + [FeaturePTX21]>; + //===- PTX Shader Model ---------------------------------------------------===// def FeatureSM10 : SubtargetFeature<"sm10", "PTXShaderModel", "PTX_SM_1_0", Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.td?rev=127677&r1=127676&r2=127677&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.td Tue Mar 15 08:24:15 2011 @@ -32,10 +32,11 @@ def DoesNotSupportSM20 : Predicate<"!getSubtarget().supportsSM20()">; // PTX Version Support -def SupportsPTX20 : Predicate<"getSubtarget().supportsPTX20()">; -def DoesNotSupportPTX20 : Predicate<"!getSubtarget().supportsPTX20()">; def SupportsPTX21 : Predicate<"getSubtarget().supportsPTX21()">; def DoesNotSupportPTX21 : Predicate<"!getSubtarget().supportsPTX21()">; +def SupportsPTX22 : Predicate<"getSubtarget().supportsPTX22()">; +def DoesNotSupportPTX22 : Predicate<"!getSubtarget().supportsPTX22()">; + //===----------------------------------------------------------------------===// // Instruction Pattern Stuff @@ -253,6 +254,33 @@ [(set RRegu64:$d, (opnode RRegu64:$a, imm:$b))]>; } +multiclass PTX_LOGIC { + def rr16 : InstPTX<(outs RRegu16:$d), + (ins RRegu16:$a, RRegu16:$b), + !strconcat(opcstr, ".b16\t$d, $a, $b"), + [(set RRegu16:$d, (opnode RRegu16:$a, RRegu16:$b))]>; + def ri16 : InstPTX<(outs RRegu16:$d), + (ins RRegu16:$a, i16imm:$b), + !strconcat(opcstr, ".b16\t$d, $a, $b"), + [(set RRegu16:$d, (opnode RRegu16:$a, imm:$b))]>; + def rr32 : InstPTX<(outs RRegu32:$d), + (ins RRegu32:$a, RRegu32:$b), + !strconcat(opcstr, ".b32\t$d, $a, $b"), + [(set RRegu32:$d, (opnode RRegu32:$a, RRegu32:$b))]>; + def ri32 : InstPTX<(outs RRegu32:$d), + (ins RRegu32:$a, i32imm:$b), + !strconcat(opcstr, ".b32\t$d, $a, $b"), + [(set RRegu32:$d, (opnode RRegu32:$a, imm:$b))]>; + def rr64 : InstPTX<(outs RRegu64:$d), + (ins RRegu64:$a, RRegu64:$b), + !strconcat(opcstr, ".b64\t$d, $a, $b"), + [(set RRegu64:$d, (opnode RRegu64:$a, RRegu64:$b))]>; + def ri64 : InstPTX<(outs RRegu64:$d), + (ins RRegu64:$a, i64imm:$b), + !strconcat(opcstr, ".b64\t$d, $a, $b"), + [(set RRegu64:$d, (opnode RRegu64:$a, imm:$b))]>; +} + // no %type directive, non-communtable multiclass INT3ntnc { def rr : InstPTX<(outs RRegu32:$d), @@ -359,6 +387,7 @@ defm ADD : INT3<"add", add>; defm SUB : INT3<"sub", sub>; +defm MUL : INT3<"mul.lo", mul>; // FIXME: Allow 32x32 -> 64 multiplies ///===- Floating-Point Arithmetic Instructions ----------------------------===// @@ -462,6 +491,10 @@ defm SRL : INT3ntnc<"shr.u32", PTXsrl>; defm SRA : INT3ntnc<"shr.s32", PTXsra>; +defm AND : PTX_LOGIC<"and", and>; +defm OR : PTX_LOGIC<"or", or>; +defm XOR : PTX_LOGIC<"xor", xor>; + ///===- Data Movement and Conversion Instructions -------------------------===// let neverHasSideEffects = 1 in { Modified: llvm/trunk/lib/Target/PTX/PTXIntrinsicInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXIntrinsicInstrInfo.td?rev=127677&r1=127676&r2=127677&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXIntrinsicInstrInfo.td (original) +++ llvm/trunk/lib/Target/PTX/PTXIntrinsicInstrInfo.td Tue Mar 15 08:24:15 2011 @@ -23,40 +23,35 @@ !strconcat("mov.u32\t$d, %", regname), [(set RRegu32:$d, (intop))]>; -class PTX_READ_SPECIAL_SUB_REGISTER - : InstPTX<(outs RRegu16:$d), (ins), - !strconcat("mov.u16\t$d, %", regname), - [(set RRegu16:$d, (intop))]>; - // TODO Add read vector-version of special registers -def PTX_READ_TID_R64 : PTX_READ_SPECIAL_REGISTER_R64<"tid", int_ptx_read_tid_r64>; -def PTX_READ_TID_X : PTX_READ_SPECIAL_SUB_REGISTER<"tid.x", int_ptx_read_tid_x>; -def PTX_READ_TID_Y : PTX_READ_SPECIAL_SUB_REGISTER<"tid.y", int_ptx_read_tid_y>; -def PTX_READ_TID_Z : PTX_READ_SPECIAL_SUB_REGISTER<"tid.z", int_ptx_read_tid_z>; -def PTX_READ_TID_W : PTX_READ_SPECIAL_SUB_REGISTER<"tid.w", int_ptx_read_tid_w>; - -def PTX_READ_NTID_R64 : PTX_READ_SPECIAL_REGISTER_R64<"ntid", int_ptx_read_ntid_r64>; -def PTX_READ_NTID_X : PTX_READ_SPECIAL_SUB_REGISTER<"ntid.x", int_ptx_read_ntid_x>; -def PTX_READ_NTID_Y : PTX_READ_SPECIAL_SUB_REGISTER<"ntid.y", int_ptx_read_ntid_y>; -def PTX_READ_NTID_Z : PTX_READ_SPECIAL_SUB_REGISTER<"ntid.z", int_ptx_read_ntid_z>; -def PTX_READ_NTID_W : PTX_READ_SPECIAL_SUB_REGISTER<"ntid.w", int_ptx_read_ntid_w>; +//def PTX_READ_TID_R64 : PTX_READ_SPECIAL_REGISTER_R64<"tid", int_ptx_read_tid_r64>; +def PTX_READ_TID_X : PTX_READ_SPECIAL_REGISTER_R32<"tid.x", int_ptx_read_tid_x>; +def PTX_READ_TID_Y : PTX_READ_SPECIAL_REGISTER_R32<"tid.y", int_ptx_read_tid_y>; +def PTX_READ_TID_Z : PTX_READ_SPECIAL_REGISTER_R32<"tid.z", int_ptx_read_tid_z>; +def PTX_READ_TID_W : PTX_READ_SPECIAL_REGISTER_R32<"tid.w", int_ptx_read_tid_w>; + +//def PTX_READ_NTID_R64 : PTX_READ_SPECIAL_REGISTER_R64<"ntid", int_ptx_read_ntid_r64>; +def PTX_READ_NTID_X : PTX_READ_SPECIAL_REGISTER_R32<"ntid.x", int_ptx_read_ntid_x>; +def PTX_READ_NTID_Y : PTX_READ_SPECIAL_REGISTER_R32<"ntid.y", int_ptx_read_ntid_y>; +def PTX_READ_NTID_Z : PTX_READ_SPECIAL_REGISTER_R32<"ntid.z", int_ptx_read_ntid_z>; +def PTX_READ_NTID_W : PTX_READ_SPECIAL_REGISTER_R32<"ntid.w", int_ptx_read_ntid_w>; def PTX_READ_LANEID : PTX_READ_SPECIAL_REGISTER_R32<"laneid", int_ptx_read_laneid>; def PTX_READ_WARPID : PTX_READ_SPECIAL_REGISTER_R32<"warpid", int_ptx_read_warpid>; def PTX_READ_NWARPID : PTX_READ_SPECIAL_REGISTER_R32<"nwarpid", int_ptx_read_nwarpid>; -def PTX_READ_CTAID_R64 : PTX_READ_SPECIAL_REGISTER_R64<"ctaid", int_ptx_read_ctaid_r64>; -def PTX_READ_CTAID_X : PTX_READ_SPECIAL_SUB_REGISTER<"ctaid.x", int_ptx_read_ctaid_x>; -def PTX_READ_CTAID_Y : PTX_READ_SPECIAL_SUB_REGISTER<"ctaid.y", int_ptx_read_ctaid_y>; -def PTX_READ_CTAID_Z : PTX_READ_SPECIAL_SUB_REGISTER<"ctaid.z", int_ptx_read_ctaid_z>; -def PTX_READ_CTAID_W : PTX_READ_SPECIAL_SUB_REGISTER<"ctaid.w", int_ptx_read_ctaid_w>; - -def PTX_READ_NCTAID_R64 : PTX_READ_SPECIAL_REGISTER_R64<"nctaid", int_ptx_read_nctaid_r64>; -def PTX_READ_NCTAID_X : PTX_READ_SPECIAL_SUB_REGISTER<"nctaid.x", int_ptx_read_nctaid_x>; -def PTX_READ_NCTAID_Y : PTX_READ_SPECIAL_SUB_REGISTER<"nctaid.y", int_ptx_read_nctaid_y>; -def PTX_READ_NCTAID_Z : PTX_READ_SPECIAL_SUB_REGISTER<"nctaid.z", int_ptx_read_nctaid_z>; -def PTX_READ_NCTAID_W : PTX_READ_SPECIAL_SUB_REGISTER<"nctaid.w", int_ptx_read_nctaid_w>; +//def PTX_READ_CTAID_R64 : PTX_READ_SPECIAL_REGISTER_R64<"ctaid", int_ptx_read_ctaid_r64>; +def PTX_READ_CTAID_X : PTX_READ_SPECIAL_REGISTER_R32<"ctaid.x", int_ptx_read_ctaid_x>; +def PTX_READ_CTAID_Y : PTX_READ_SPECIAL_REGISTER_R32<"ctaid.y", int_ptx_read_ctaid_y>; +def PTX_READ_CTAID_Z : PTX_READ_SPECIAL_REGISTER_R32<"ctaid.z", int_ptx_read_ctaid_z>; +def PTX_READ_CTAID_W : PTX_READ_SPECIAL_REGISTER_R32<"ctaid.w", int_ptx_read_ctaid_w>; + +//def PTX_READ_NCTAID_R64 : PTX_READ_SPECIAL_REGISTER_R64<"nctaid", int_ptx_read_nctaid_r64>; +def PTX_READ_NCTAID_X : PTX_READ_SPECIAL_REGISTER_R32<"nctaid.x", int_ptx_read_nctaid_x>; +def PTX_READ_NCTAID_Y : PTX_READ_SPECIAL_REGISTER_R32<"nctaid.y", int_ptx_read_nctaid_y>; +def PTX_READ_NCTAID_Z : PTX_READ_SPECIAL_REGISTER_R32<"nctaid.z", int_ptx_read_nctaid_z>; +def PTX_READ_NCTAID_W : PTX_READ_SPECIAL_REGISTER_R32<"nctaid.w", int_ptx_read_nctaid_w>; def PTX_READ_SMID : PTX_READ_SPECIAL_REGISTER_R32<"smid", int_ptx_read_smid>; def PTX_READ_NSMID : PTX_READ_SPECIAL_REGISTER_R32<"nsmid", int_ptx_read_nsmid>; Modified: llvm/trunk/lib/Target/PTX/PTXSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXSubtarget.cpp?rev=127677&r1=127676&r2=127677&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXSubtarget.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXSubtarget.cpp Tue Mar 15 08:24:15 2011 @@ -18,7 +18,7 @@ PTXSubtarget::PTXSubtarget(const std::string &TT, const std::string &FS) : PTXShaderModel(PTX_SM_1_0), - PTXVersion(PTX_VERSION_1_4), + PTXVersion(PTX_VERSION_2_0), SupportsDouble(false), Use64BitAddresses(false) { std::string TARGET = "generic"; @@ -37,9 +37,9 @@ std::string PTXSubtarget::getPTXVersionString() const { switch(PTXVersion) { default: llvm_unreachable("Unknown PTX version"); - case PTX_VERSION_1_4: return "1.4"; case PTX_VERSION_2_0: return "2.0"; case PTX_VERSION_2_1: return "2.1"; + case PTX_VERSION_2_2: return "2.2"; } } Modified: llvm/trunk/lib/Target/PTX/PTXSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXSubtarget.h?rev=127677&r1=127676&r2=127677&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXSubtarget.h (original) +++ llvm/trunk/lib/Target/PTX/PTXSubtarget.h Tue Mar 15 08:24:15 2011 @@ -19,16 +19,25 @@ namespace llvm { class PTXSubtarget : public TargetSubtarget { private: + + /** + * Enumeration of Shader Models supported by the back-end. + */ enum PTXShaderModelEnum { - PTX_SM_1_0, - PTX_SM_1_3, - PTX_SM_2_0 + PTX_SM_1_0, /*< Shader Model 1.0 */ + PTX_SM_1_3, /*< Shader Model 1.3 */ + PTX_SM_2_0 /*< Shader Model 2.0 */ }; + /** + * Enumeration of PTX versions supported by the back-end. + * + * Currently, PTX 2.0 is the minimum supported version. + */ enum PTXVersionEnum { - PTX_VERSION_1_4, - PTX_VERSION_2_0, - PTX_VERSION_2_1 + PTX_VERSION_2_0, /*< PTX Version 2.0 */ + PTX_VERSION_2_1, /*< PTX Version 2.1 */ + PTX_VERSION_2_2 /*< PTX Version 2.2 */ }; /// Shader Model supported on the target GPU. @@ -58,10 +67,10 @@ bool supportsSM20() const { return PTXShaderModel >= PTX_SM_2_0; } - bool supportsPTX20() const { return PTXVersion >= PTX_VERSION_2_0; } - bool supportsPTX21() const { return PTXVersion >= PTX_VERSION_2_1; } + bool supportsPTX22() const { return PTXVersion >= PTX_VERSION_2_2; } + std::string ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); }; // class PTXSubtarget Modified: llvm/trunk/test/CodeGen/PTX/intrinsic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/intrinsic.ll?rev=127677&r1=127676&r2=127677&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/intrinsic.ll (original) +++ llvm/trunk/test/CodeGen/PTX/intrinsic.ll Tue Mar 15 08:24:15 2011 @@ -1,59 +1,59 @@ ; RUN: llc < %s -march=ptx -mattr=+ptx20,+sm20 | FileCheck %s -define ptx_device i16 @test_tid_x() { -; CHECK: mov.u16 rh0, %tid.x; +define ptx_device i32 @test_tid_x() { +; CHECK: mov.u32 r0, %tid.x; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.tid.x() - ret i16 %x + %x = call i32 @llvm.ptx.read.tid.x() + ret i32 %x } -define ptx_device i16 @test_tid_y() { -; CHECK: mov.u16 rh0, %tid.y; +define ptx_device i32 @test_tid_y() { +; CHECK: mov.u32 r0, %tid.y; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.tid.y() - ret i16 %x + %x = call i32 @llvm.ptx.read.tid.y() + ret i32 %x } -define ptx_device i16 @test_tid_z() { -; CHECK: mov.u16 rh0, %tid.z; +define ptx_device i32 @test_tid_z() { +; CHECK: mov.u32 r0, %tid.z; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.tid.z() - ret i16 %x + %x = call i32 @llvm.ptx.read.tid.z() + ret i32 %x } -define ptx_device i16 @test_tid_w() { -; CHECK: mov.u16 rh0, %tid.w; +define ptx_device i32 @test_tid_w() { +; CHECK: mov.u32 r0, %tid.w; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.tid.w() - ret i16 %x + %x = call i32 @llvm.ptx.read.tid.w() + ret i32 %x } -define ptx_device i16 @test_ntid_x() { -; CHECK: mov.u16 rh0, %ntid.x; +define ptx_device i32 @test_ntid_x() { +; CHECK: mov.u32 r0, %ntid.x; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.ntid.x() - ret i16 %x + %x = call i32 @llvm.ptx.read.ntid.x() + ret i32 %x } -define ptx_device i16 @test_ntid_y() { -; CHECK: mov.u16 rh0, %ntid.y; +define ptx_device i32 @test_ntid_y() { +; CHECK: mov.u32 r0, %ntid.y; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.ntid.y() - ret i16 %x + %x = call i32 @llvm.ptx.read.ntid.y() + ret i32 %x } -define ptx_device i16 @test_ntid_z() { -; CHECK: mov.u16 rh0, %ntid.z; +define ptx_device i32 @test_ntid_z() { +; CHECK: mov.u32 r0, %ntid.z; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.ntid.z() - ret i16 %x + %x = call i32 @llvm.ptx.read.ntid.z() + ret i32 %x } -define ptx_device i16 @test_ntid_w() { -; CHECK: mov.u16 rh0, %ntid.w; +define ptx_device i32 @test_ntid_w() { +; CHECK: mov.u32 r0, %ntid.w; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.ntid.w() - ret i16 %x + %x = call i32 @llvm.ptx.read.ntid.w() + ret i32 %x } define ptx_device i32 @test_laneid() { @@ -77,60 +77,60 @@ ret i32 %x } -define ptx_device i16 @test_ctaid_x() { -; CHECK: mov.u16 rh0, %ctaid.x; +define ptx_device i32 @test_ctaid_x() { +; CHECK: mov.u32 r0, %ctaid.x; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.ctaid.x() - ret i16 %x + %x = call i32 @llvm.ptx.read.ctaid.x() + ret i32 %x } -define ptx_device i16 @test_ctaid_y() { -; CHECK: mov.u16 rh0, %ctaid.y; +define ptx_device i32 @test_ctaid_y() { +; CHECK: mov.u32 r0, %ctaid.y; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.ctaid.y() - ret i16 %x + %x = call i32 @llvm.ptx.read.ctaid.y() + ret i32 %x } -define ptx_device i16 @test_ctaid_z() { -; CHECK: mov.u16 rh0, %ctaid.z; +define ptx_device i32 @test_ctaid_z() { +; CHECK: mov.u32 r0, %ctaid.z; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.ctaid.z() - ret i16 %x + %x = call i32 @llvm.ptx.read.ctaid.z() + ret i32 %x } -define ptx_device i16 @test_ctaid_w() { -; CHECK: mov.u16 rh0, %ctaid.w; +define ptx_device i32 @test_ctaid_w() { +; CHECK: mov.u32 r0, %ctaid.w; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.ctaid.w() - ret i16 %x + %x = call i32 @llvm.ptx.read.ctaid.w() + ret i32 %x } -define ptx_device i16 @test_nctaid_x() { -; CHECK: mov.u16 rh0, %nctaid.x; +define ptx_device i32 @test_nctaid_x() { +; CHECK: mov.u32 r0, %nctaid.x; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.nctaid.x() - ret i16 %x + %x = call i32 @llvm.ptx.read.nctaid.x() + ret i32 %x } -define ptx_device i16 @test_nctaid_y() { -; CHECK: mov.u16 rh0, %nctaid.y; +define ptx_device i32 @test_nctaid_y() { +; CHECK: mov.u32 r0, %nctaid.y; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.nctaid.y() - ret i16 %x + %x = call i32 @llvm.ptx.read.nctaid.y() + ret i32 %x } -define ptx_device i16 @test_nctaid_z() { -; CHECK: mov.u16 rh0, %nctaid.z; +define ptx_device i32 @test_nctaid_z() { +; CHECK: mov.u32 r0, %nctaid.z; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.nctaid.z() - ret i16 %x + %x = call i32 @llvm.ptx.read.nctaid.z() + ret i32 %x } -define ptx_device i16 @test_nctaid_w() { -; CHECK: mov.u16 rh0, %nctaid.w; +define ptx_device i32 @test_nctaid_w() { +; CHECK: mov.u32 r0, %nctaid.w; ; CHECK-NEXT: ret; - %x = call i16 @llvm.ptx.read.nctaid.w() - ret i16 %x + %x = call i32 @llvm.ptx.read.nctaid.w() + ret i32 %x } define ptx_device i32 @test_smid() { @@ -238,27 +238,27 @@ ret void } -declare i16 @llvm.ptx.read.tid.x() -declare i16 @llvm.ptx.read.tid.y() -declare i16 @llvm.ptx.read.tid.z() -declare i16 @llvm.ptx.read.tid.w() -declare i16 @llvm.ptx.read.ntid.x() -declare i16 @llvm.ptx.read.ntid.y() -declare i16 @llvm.ptx.read.ntid.z() -declare i16 @llvm.ptx.read.ntid.w() +declare i32 @llvm.ptx.read.tid.x() +declare i32 @llvm.ptx.read.tid.y() +declare i32 @llvm.ptx.read.tid.z() +declare i32 @llvm.ptx.read.tid.w() +declare i32 @llvm.ptx.read.ntid.x() +declare i32 @llvm.ptx.read.ntid.y() +declare i32 @llvm.ptx.read.ntid.z() +declare i32 @llvm.ptx.read.ntid.w() declare i32 @llvm.ptx.read.laneid() declare i32 @llvm.ptx.read.warpid() declare i32 @llvm.ptx.read.nwarpid() -declare i16 @llvm.ptx.read.ctaid.x() -declare i16 @llvm.ptx.read.ctaid.y() -declare i16 @llvm.ptx.read.ctaid.z() -declare i16 @llvm.ptx.read.ctaid.w() -declare i16 @llvm.ptx.read.nctaid.x() -declare i16 @llvm.ptx.read.nctaid.y() -declare i16 @llvm.ptx.read.nctaid.z() -declare i16 @llvm.ptx.read.nctaid.w() +declare i32 @llvm.ptx.read.ctaid.x() +declare i32 @llvm.ptx.read.ctaid.y() +declare i32 @llvm.ptx.read.ctaid.z() +declare i32 @llvm.ptx.read.ctaid.w() +declare i32 @llvm.ptx.read.nctaid.x() +declare i32 @llvm.ptx.read.nctaid.y() +declare i32 @llvm.ptx.read.nctaid.z() +declare i32 @llvm.ptx.read.nctaid.w() declare i32 @llvm.ptx.read.smid() declare i32 @llvm.ptx.read.nsmid() Modified: llvm/trunk/test/CodeGen/PTX/options.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PTX/options.ll?rev=127677&r1=127676&r2=127677&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PTX/options.ll (original) +++ llvm/trunk/test/CodeGen/PTX/options.ll Tue Mar 15 08:24:15 2011 @@ -1,8 +1,9 @@ -; RUN: llc < %s -march=ptx -mattr=ptx14 | grep ".version 1.4" ; RUN: llc < %s -march=ptx -mattr=ptx20 | grep ".version 2.0" ; RUN: llc < %s -march=ptx -mattr=ptx21 | grep ".version 2.1" -; RUN: llc < %s -march=ptx -mattr=sm20 | grep ".target sm_20" +; RUN: llc < %s -march=ptx -mattr=ptx22 | grep ".version 2.2" +; RUN: llc < %s -march=ptx -mattr=sm10 | grep ".target sm_10" ; RUN: llc < %s -march=ptx -mattr=sm13 | grep ".target sm_13" +; RUN: llc < %s -march=ptx -mattr=sm20 | grep ".target sm_20" define ptx_device void @t1() { ret void From richard at xmos.com Tue Mar 15 08:45:47 2011 From: richard at xmos.com (Richard Osborne) Date: Tue, 15 Mar 2011 13:45:47 -0000 Subject: [llvm-commits] [llvm] r127678 - in /llvm/trunk: include/llvm/IntrinsicsXCore.td lib/Target/XCore/XCoreInstrInfo.td test/CodeGen/XCore/ps-intrinsics.ll test/CodeGen/XCore/sr-intrinsics.ll Message-ID: <20110315134547.5EA472A6C12C@llvm.org> Author: friedgold Date: Tue Mar 15 08:45:47 2011 New Revision: 127678 URL: http://llvm.org/viewvc/llvm-project?rev=127678&view=rev Log: Add XCore intrinsics for getps, setps, setsr and clrsr. Added: llvm/trunk/test/CodeGen/XCore/ps-intrinsics.ll llvm/trunk/test/CodeGen/XCore/sr-intrinsics.ll Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsXCore.td?rev=127678&r1=127677&r2=127678&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsXCore.td (original) +++ llvm/trunk/include/llvm/IntrinsicsXCore.td Tue Mar 15 08:45:47 2011 @@ -9,8 +9,13 @@ //===----------------------------------------------------------------------===// let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". + // Miscellaneous instructions. def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>; def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>; + def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>; + def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>; + def int_xcore_setsr : Intrinsic<[],[llvm_i32_ty]>; + def int_xcore_clrsr : Intrinsic<[],[llvm_i32_ty]>; // Resource instructions. def int_xcore_getr : Intrinsic<[llvm_anyptr_ty],[llvm_i32_ty]>; Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=127678&r1=127677&r2=127678&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Tue Mar 15 08:45:47 2011 @@ -308,6 +308,16 @@ !strconcat(OpcStr, " $b"), [(OpNode immU16:$b)]>; } +multiclass FU6_LU6_int { + def _u6: _FU6< + (outs), (ins i32imm:$b), + !strconcat(OpcStr, " $b"), + [(Int immU6:$b)]>; + def _lu6: _FLU6< + (outs), (ins i32imm:$b), + !strconcat(OpcStr, " $b"), + [(Int immU16:$b)]>; +} multiclass FU6_LU6_np { def _u6: _FU6< @@ -638,8 +648,8 @@ } } -// TODO extdp, kentsp, krestsp, blat, setsr -// clrsr, getsr, kalli +// TODO extdp, kentsp, krestsp, blat +// getsr, kalli let isBranch = 1, isTerminator = 1, isBarrier = 1 in { def BRBU_u6 : _FU6< (outs), @@ -678,6 +688,10 @@ "ldaw r11, cp[$a]", [(set R11, ADDRcpii:$a)]>; +defm SETSR : FU6_LU6_int<"setsr", int_xcore_setsr>; + +defm CLRSR : FU6_LU6_int<"clrsr", int_xcore_clrsr>; + // U10 // TODO ldwcpl, blacp @@ -818,7 +832,7 @@ // Two operand long // TODO setclk, setrdy, setpsc, endin, peek, -// getd, testlcl, tinitlr, getps, setps +// getd, testlcl, tinitlr def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), "bitrev $dst, $src", [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>; @@ -839,6 +853,14 @@ "settw res[$r], $val", [(int_xcore_settw GRRegs:$r, GRRegs:$val)]>; +def GETPS_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), + "get $dst, ps[$src]", + [(set GRRegs:$dst, (int_xcore_getps GRRegs:$src))]>; + +def SETPS_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), + "set ps[$src1], $src2", + [(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>; + // One operand short // TODO edu, eeu, waitet, waitef, tstart, msync, mjoin, clrtp // setdp, setcp, setev, kcall Added: llvm/trunk/test/CodeGen/XCore/ps-intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/ps-intrinsics.ll?rev=127678&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/ps-intrinsics.ll (added) +++ llvm/trunk/test/CodeGen/XCore/ps-intrinsics.ll Tue Mar 15 08:45:47 2011 @@ -0,0 +1,18 @@ +; RUN: llc < %s -march=xcore | FileCheck %s +declare i32 @llvm.xcore.getps(i32) +declare void @llvm.xcore.setps(i32, i32) + +define i32 @getps(i32 %reg) nounwind { +; CHECK: getps: +; CHECK: get r0, ps[r0] + %result = call i32 @llvm.xcore.getps(i32 %reg) + ret i32 %result +} + + +define void @setps(i32 %reg, i32 %value) nounwind { +; CHECK: setps: +; CHECK: set ps[r0], r1 + call void @llvm.xcore.setps(i32 %reg, i32 %value) + ret void +} Added: llvm/trunk/test/CodeGen/XCore/sr-intrinsics.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/sr-intrinsics.ll?rev=127678&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/sr-intrinsics.ll (added) +++ llvm/trunk/test/CodeGen/XCore/sr-intrinsics.ll Tue Mar 15 08:45:47 2011 @@ -0,0 +1,18 @@ +; RUN: llc < %s -march=xcore | FileCheck %s +declare void @llvm.xcore.setsr(i32) +declare void @llvm.xcore.clrsr(i32) + +define void @setsr() nounwind { +; CHECK: setsr: +; CHECK: setsr 128 + call void @llvm.xcore.setsr(i32 128) + ret void +} + + +define void @clrsr() nounwind { +; CHECK: clrsr: +; CHECK: clrsr 128 + call void @llvm.xcore.clrsr(i32 128) + ret void +} From ofv at wanadoo.es Tue Mar 15 09:53:53 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Tue, 15 Mar 2011 14:53:53 -0000 Subject: [llvm-commits] [llvm] r127679 - /llvm/trunk/cmake/modules/LLVMConfig.cmake Message-ID: <20110315145353.AA0522A6C12C@llvm.org> Author: ofv Date: Tue Mar 15 09:53:53 2011 New Revision: 127679 URL: http://llvm.org/viewvc/llvm-project?rev=127679&view=rev Log: is_llvm_target_library: recognize libraries without the LLVM prefix. Without this cmake fails at configuration when some target pass "native" on LLVM_LINK_COMPONENTS and that is expanded to "X86". Modified: llvm/trunk/cmake/modules/LLVMConfig.cmake Modified: llvm/trunk/cmake/modules/LLVMConfig.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMConfig.cmake?rev=127679&r1=127678&r2=127679&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMConfig.cmake (original) +++ llvm/trunk/cmake/modules/LLVMConfig.cmake Tue Mar 15 09:53:53 2011 @@ -23,7 +23,8 @@ string(TOUPPER "${library}" capitalized_lib) string(TOUPPER "${LLVM_ALL_TARGETS}" targets) foreach(t ${targets}) - if( capitalized_lib STREQUAL "LLVM${t}" OR + if( capitalized_lib STREQUAL t OR + capitalized_lib STREQUAL "LLVM${t}" OR capitalized_lib STREQUAL "LLVM${t}CODEGEN" OR capitalized_lib STREQUAL "LLVM${t}ASMPARSER" OR capitalized_lib STREQUAL "LLVM${t}ASMPRINTER" OR From richard at xmos.com Tue Mar 15 10:10:11 2011 From: richard at xmos.com (Richard Osborne) Date: Tue, 15 Mar 2011 15:10:11 -0000 Subject: [llvm-commits] [llvm] r127680 - in /llvm/trunk: lib/Target/XCore/XCoreRegisterInfo.cpp lib/Target/XCore/XCoreRegisterInfo.h test/CodeGen/XCore/scavenging.ll Message-ID: <20110315151011.3DD4F2A6C12C@llvm.org> Author: friedgold Date: Tue Mar 15 10:10:11 2011 New Revision: 127680 URL: http://llvm.org/viewvc/llvm-project?rev=127680&view=rev Log: On the XCore the scavenging slot should be closest to the SP. Added: llvm/trunk/test/CodeGen/XCore/scavenging.ll Modified: llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.h Modified: llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp?rev=127680&r1=127679&r2=127680&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp Tue Mar 15 10:10:11 2011 @@ -104,6 +104,11 @@ return TFI->hasFP(MF); } +bool +XCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { + return false; +} + // This function eliminates ADJCALLSTACKDOWN, // ADJCALLSTACKUP pseudo instructions void XCoreRegisterInfo:: Modified: llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.h?rev=127680&r1=127679&r2=127680&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.h (original) +++ llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.h Tue Mar 15 10:10:11 2011 @@ -48,6 +48,8 @@ bool requiresRegisterScavenging(const MachineFunction &MF) const; + bool useFPForScavengingIndex(const MachineFunction &MF) const; + void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; Added: llvm/trunk/test/CodeGen/XCore/scavenging.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/scavenging.ll?rev=127680&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/scavenging.ll (added) +++ llvm/trunk/test/CodeGen/XCore/scavenging.ll Tue Mar 15 10:10:11 2011 @@ -0,0 +1,52 @@ +; RUN: llc < %s -march=xcore + at size = global i32 0 ; [#uses=1] + at g0 = external global i32 ; [#uses=2] + at g1 = external global i32 ; [#uses=2] + at g2 = external global i32 ; [#uses=2] + at g3 = external global i32 ; [#uses=2] + at g4 = external global i32 ; [#uses=2] + at g5 = external global i32 ; [#uses=2] + at g6 = external global i32 ; [#uses=2] + at g7 = external global i32 ; [#uses=2] + at g8 = external global i32 ; [#uses=2] + at g9 = external global i32 ; [#uses=2] + at g10 = external global i32 ; [#uses=2] + at g11 = external global i32 ; [#uses=2] + +define void @f() nounwind { +entry: + %x = alloca [100 x i32], align 4 ; <[100 x i32]*> [#uses=2] + %0 = load i32* @size, align 4 ; [#uses=1] + %1 = alloca i32, i32 %0, align 4 ; [#uses=1] + %2 = volatile load i32* @g0, align 4 ; [#uses=1] + %3 = volatile load i32* @g1, align 4 ; [#uses=1] + %4 = volatile load i32* @g2, align 4 ; [#uses=1] + %5 = volatile load i32* @g3, align 4 ; [#uses=1] + %6 = volatile load i32* @g4, align 4 ; [#uses=1] + %7 = volatile load i32* @g5, align 4 ; [#uses=1] + %8 = volatile load i32* @g6, align 4 ; [#uses=1] + %9 = volatile load i32* @g7, align 4 ; [#uses=1] + %10 = volatile load i32* @g8, align 4 ; [#uses=1] + %11 = volatile load i32* @g9, align 4 ; [#uses=1] + %12 = volatile load i32* @g10, align 4 ; [#uses=1] + %13 = volatile load i32* @g11, align 4 ; [#uses=2] + %14 = getelementptr [100 x i32]* %x, i32 0, i32 50 ; [#uses=1] + store i32 %13, i32* %14, align 4 + volatile store i32 %13, i32* @g11, align 4 + volatile store i32 %12, i32* @g10, align 4 + volatile store i32 %11, i32* @g9, align 4 + volatile store i32 %10, i32* @g8, align 4 + volatile store i32 %9, i32* @g7, align 4 + volatile store i32 %8, i32* @g6, align 4 + volatile store i32 %7, i32* @g5, align 4 + volatile store i32 %6, i32* @g4, align 4 + volatile store i32 %5, i32* @g3, align 4 + volatile store i32 %4, i32* @g2, align 4 + volatile store i32 %3, i32* @g1, align 4 + volatile store i32 %2, i32* @g0, align 4 + %x1 = getelementptr [100 x i32]* %x, i32 0, i32 0 ; [#uses=1] + call void @g(i32* %x1, i32* %1) nounwind + ret void +} + +declare void @g(i32*, i32*) From richard at xmos.com Tue Mar 15 10:55:30 2011 From: richard at xmos.com (Richard Osborne) Date: Tue, 15 Mar 2011 15:55:30 -0000 Subject: [llvm-commits] [llvm] r127681 - /llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp Message-ID: <20110315155530.E1F3E2A6C12C@llvm.org> Author: friedgold Date: Tue Mar 15 10:55:30 2011 New Revision: 127681 URL: http://llvm.org/viewvc/llvm-project?rev=127681&view=rev Log: Don't indent cases in a switch, no functionality change. Modified: llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp?rev=127681&r1=127680&r2=127681&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp Tue Mar 15 10:55:30 2011 @@ -157,58 +157,58 @@ EVT NVT = N->getValueType(0); if (NVT == MVT::i32) { switch (N->getOpcode()) { - default: break; - case ISD::Constant: { - uint64_t Val = cast(N)->getZExtValue(); - if (immMskBitp(N)) { - // Transformation function: get the size of a mask - // Look for the first non-zero bit - SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(Val)); - return CurDAG->getMachineNode(XCore::MKMSK_rus, dl, - MVT::i32, MskSize); - } - else if (!isUInt<16>(Val)) { - SDValue CPIdx = - CurDAG->getTargetConstantPool(ConstantInt::get( - Type::getInt32Ty(*CurDAG->getContext()), Val), - TLI.getPointerTy()); - return CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32, - MVT::Other, CPIdx, - CurDAG->getEntryNode()); - } - break; + default: break; + case ISD::Constant: { + uint64_t Val = cast(N)->getZExtValue(); + if (immMskBitp(N)) { + // Transformation function: get the size of a mask + // Look for the first non-zero bit + SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(Val)); + return CurDAG->getMachineNode(XCore::MKMSK_rus, dl, + MVT::i32, MskSize); + } + else if (!isUInt<16>(Val)) { + SDValue CPIdx = + CurDAG->getTargetConstantPool(ConstantInt::get( + Type::getInt32Ty(*CurDAG->getContext()), Val), + TLI.getPointerTy()); + return CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32, + MVT::Other, CPIdx, + CurDAG->getEntryNode()); } - case XCoreISD::LADD: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2) }; - return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32, - Ops, 3); - } - case XCoreISD::LSUB: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2) }; - return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32, - Ops, 3); - } - case XCoreISD::MACCU: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2), N->getOperand(3) }; - return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32, - Ops, 4); - } - case XCoreISD::MACCS: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2), N->getOperand(3) }; - return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32, - Ops, 4); - } - case XCoreISD::LMUL: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2), N->getOperand(3) }; - return CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32, - Ops, 4); - } - // Other cases are autogenerated. + break; + } + case XCoreISD::LADD: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2) }; + return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32, + Ops, 3); + } + case XCoreISD::LSUB: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2) }; + return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32, + Ops, 3); + } + case XCoreISD::MACCU: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2), N->getOperand(3) }; + return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32, + Ops, 4); + } + case XCoreISD::MACCS: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2), N->getOperand(3) }; + return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32, + Ops, 4); + } + case XCoreISD::LMUL: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2), N->getOperand(3) }; + return CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32, + Ops, 4); + } + // Other cases are autogenerated. } } return SelectCode(N); From dpatel at apple.com Tue Mar 15 11:02:34 2011 From: dpatel at apple.com (Devang Patel) Date: Tue, 15 Mar 2011 09:02:34 -0700 Subject: [llvm-commits] Debug Relocation Patch In-Reply-To: <4D7E7064.5060101@gmail.com> References: <4D7E5C2E.1000803@gmail.com> <4D7E7064.5060101@gmail.com> Message-ID: <1C562675-DA94-4070-B953-B6C9B3CF1E36@apple.com> On Mar 14, 2011, at 12:45 PM, Rafael Avila de Espindola wrote: > evang, for testing on linux I normally use a current version of the gdb testsuite. I assume that for darwin it is better to use an older one. Which testsuite do you normally use? Daniel recently put it in svn @llvm.org, so it is convenient for everyone. http://llvm.org/viewvc/llvm-project/clang-tests/trunk/gdb-1472-testsuite/ - Devang From Renato.Golin at arm.com Tue Mar 15 12:13:04 2011 From: Renato.Golin at arm.com (Renato Golin) Date: Tue, 15 Mar 2011 17:13:04 +0000 Subject: [llvm-commits] Debug Relocation Patch In-Reply-To: <4D7E7064.5060101@gmail.com> References: , <4D7E5C2E.1000803@gmail.com> <4D7E7064.5060101@gmail.com> Message-ID: <4D7F9E20.70203@arm.com> On 14/03/11 19:45, Rafael Avila de Espindola wrote: > We might need a virtual method or similar. Devang, for testing on linux > I normally use a current version of the gdb testsuite. I assume that for > darwin it is better to use an older one. Which testsuite do you normally > use? Hi all, I've just compiled LLVM on an old Mac box (9.1.0, 2007) and compiled the same example in the test case and everything (symbols, stepping, debugging experience) was ok. All tests, including my new one, pass. I don't know how to dump mach-o objects nor how to check for the relocation sections, though. Somebody with more experience in Mach-o should take a look. cheers, --renato -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. From rafael.espindola at gmail.com Tue Mar 15 12:32:42 2011 From: rafael.espindola at gmail.com (Rafael Avila de Espindola) Date: Tue, 15 Mar 2011 13:32:42 -0400 Subject: [llvm-commits] Debug Relocation Patch In-Reply-To: <1C562675-DA94-4070-B953-B6C9B3CF1E36@apple.com> References: <4D7E5C2E.1000803@gmail.com> <4D7E7064.5060101@gmail.com> <1C562675-DA94-4070-B953-B6C9B3CF1E36@apple.com> Message-ID: <4D7FA2BA.2090400@gmail.com> On 11-03-15 12:02 PM, Devang Patel wrote: > > On Mar 14, 2011, at 12:45 PM, Rafael Avila de Espindola wrote: > >> evang, for testing on linux I normally use a current version of the >> gdb testsuite. I assume that for darwin it is better to use an >> older one. Which testsuite do you normally use? > > > Daniel recently put it in svn @llvm.org, so it is convenient for > everyone. > > http://llvm.org/viewvc/llvm-project/clang-tests/trunk/gdb-1472-testsuite/ That is really cool. Will be handy when trying to enable .cfi_* :-) > - Devang Cheers, Rafael From kd at kendyck.com Tue Mar 15 12:47:26 2011 From: kd at kendyck.com (Ken Dyck) Date: Tue, 15 Mar 2011 13:47:26 -0400 Subject: [llvm-commits] [PATCH] TargetLowering::isLoadWidthReducible() Message-ID: The DSP that my back end targets has multiple address spaces. From most of the address spaces, it is possible to load a 'small' integer with a single instruction. But one address space can only load a 'large' integer in a single instruction. For that last address space, I would like to custom lower 'small' loads to 'large' ones, then truncate the result. But when I do, DAGCombiner detects the truncate of a load, which it assumes can be reduced to a 'small' load, effectively undoing the lowering operation. The attached patch adds a hook to TargetLowering, isLoadWidthReducible(), that allows back ends to stop the DAG combiner before it reduces the size of a load in ReduceLoadWidth(). Would there be any interest in applying it? -Ken -------------- next part -------------- A non-text attachment was scrubbed... Name: isLoadWidthReducible.patch Type: text/x-patch Size: 1356 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110315/f713ff10/attachment.bin From echristo at apple.com Tue Mar 15 13:01:56 2011 From: echristo at apple.com (Eric Christopher) Date: Tue, 15 Mar 2011 11:01:56 -0700 Subject: [llvm-commits] [llvm] r127518 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-pred.ll In-Reply-To: References: <20110312010929.82F192A6C12C@llvm.org> Message-ID: <2871EAAE-06B5-4184-95B6-A865E256CC4A@apple.com> On Mar 14, 2011, at 7:36 PM, Evan Cheng wrote: > Can one of you file a bug for this clean up? Done. -eric From clattner at apple.com Tue Mar 15 13:43:54 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 15 Mar 2011 11:43:54 -0700 Subject: [llvm-commits] Support for explicit argument form of X86 string instructions In-Reply-To: <20110306232445.GA3958@britannica.bec.de> References: <20110306232445.GA3958@britannica.bec.de> Message-ID: On Mar 6, 2011, at 3:24 PM, Joerg Sonnenberger wrote: > Hi all, > the attached patch implements the various explicit argument forms of the > X86 string instructions. They are used for documentation purposes, but > the use of segment overrides make them hard to specify with the normal > InstAlias syntax. This covers the ins, outs, movs, lods and stos family > of instructions. For lods and stos, both the implicit and explicit size > version is recognized. Hi Joerg, Some questions, comments: Please do not accept (%dx) for ins and outs. I know that we accept them for in/out, but this is just because of compatibility with specific broken patterns in existing code, it isn't something that should spread to other places. This eliminates the need for isPortDxOp. +bool X86ATTAsmParser::isDstOp(X86Operand &Op) { Please add a doxygen comment explaining what pattern this matches. Also, I think this can just be a static function, it doesn't need to be a method on X86ATTAsmParser. Likewise for the other predicates. Instead of handling "lods" and "stos" in ParseInstruction, can't you just ignore these two cases and let the suffix search code in MatchAndEmitInstruction handle them? -Chris From evan.cheng at apple.com Tue Mar 15 13:41:53 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 15 Mar 2011 18:41:53 -0000 Subject: [llvm-commits] [llvm] r127683 - in /llvm/trunk: lib/Target/ARM/ARMLoadStoreOptimizer.cpp test/CodeGen/ARM/2011-03-15-LdStMultipleBug.ll Message-ID: <20110315184153.125802A6C12C@llvm.org> Author: evancheng Date: Tue Mar 15 13:41:52 2011 New Revision: 127683 URL: http://llvm.org/viewvc/llvm-project?rev=127683&view=rev Log: Do not form thumb2 ldrd / strd if the offset is by multiple of 4. rdar://9133587 Added: llvm/trunk/test/CodeGen/ARM/2011-03-15-LdStMultipleBug.ll Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=127683&r1=127682&r2=127683&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Mar 15 13:41:52 2011 @@ -1530,15 +1530,9 @@ // Then make sure the immediate offset fits. int OffImm = getMemoryOpOffset(Op0); if (isT2) { - if (OffImm < 0) { - if (OffImm < -255) - // Can't fall back to t2LDRi8 / t2STRi8. - return false; - } else { - int Limit = (1 << 8) * Scale; - if (OffImm >= Limit || (OffImm & (Scale-1))) - return false; - } + int Limit = (1 << 8) * Scale; + if (OffImm >= Limit || (OffImm <= -Limit) || (OffImm & (Scale-1))) + return false; Offset = OffImm; } else { ARM_AM::AddrOpc AddSub = ARM_AM::add; Added: llvm/trunk/test/CodeGen/ARM/2011-03-15-LdStMultipleBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2011-03-15-LdStMultipleBug.ll?rev=127683&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2011-03-15-LdStMultipleBug.ll (added) +++ llvm/trunk/test/CodeGen/ARM/2011-03-15-LdStMultipleBug.ll Tue Mar 15 13:41:52 2011 @@ -0,0 +1,55 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -relocation-model=pic -disable-fp-elim -mcpu=cortex-a8 | FileCheck %s + +; Do not form Thumb2 ldrd / strd if the offset is not multiple of 4. +; rdar://9133587 + +%struct.Outer = type { i32, [2 x %"struct.Outer::Inner"] } +%"struct.Outer::Inner" = type { i32, i32, i8, i8 } + + at oStruct = external global %struct.Outer, align 4 + +define void @main() nounwind { +; CHECK: main: +; CHECK-NOT: ldrd +; CHECK: mul +for.body.lr.ph: + br label %for.body + +for.body: ; preds = %_Z14printIsNotZeroi.exit17.for.body_crit_edge, %for.body.lr.ph + %tmp3 = phi i1 [ false, %for.body.lr.ph ], [ %phitmp27, %_Z14printIsNotZeroi.exit17.for.body_crit_edge ] + %i.022 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %_Z14printIsNotZeroi.exit17.for.body_crit_edge ] + %x = getelementptr %struct.Outer* @oStruct, i32 0, i32 1, i32 %i.022, i32 0 + %y = getelementptr %struct.Outer* @oStruct, i32 0, i32 1, i32 %i.022, i32 1 + %inc = add i32 %i.022, 1 + br i1 %tmp3, label %_Z14printIsNotZeroi.exit, label %if.then.i + +if.then.i: ; preds = %for.body + unreachable + +_Z14printIsNotZeroi.exit: ; preds = %for.body + %tmp8 = load i32* %x, align 4, !tbaa !0 + %tmp11 = load i32* %y, align 4, !tbaa !0 + %mul = mul nsw i32 %tmp11, %tmp8 + %tobool.i14 = icmp eq i32 %mul, 0 + br i1 %tobool.i14, label %_Z14printIsNotZeroi.exit17, label %if.then.i16 + +if.then.i16: ; preds = %_Z14printIsNotZeroi.exit + unreachable + +_Z14printIsNotZeroi.exit17: ; preds = %_Z14printIsNotZeroi.exit + br i1 undef, label %_Z14printIsNotZeroi.exit17.for.body_crit_edge, label %for.end + +_Z14printIsNotZeroi.exit17.for.body_crit_edge: ; preds = %_Z14printIsNotZeroi.exit17 + %b.phi.trans.insert = getelementptr %struct.Outer* @oStruct, i32 0, i32 1, i32 %inc, i32 3 + %tmp3.pre = load i8* %b.phi.trans.insert, align 1, !tbaa !3 + %phitmp27 = icmp eq i8 undef, 0 + br label %for.body + +for.end: ; preds = %_Z14printIsNotZeroi.exit17 + ret void +} + +!0 = metadata !{metadata !"int", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} +!3 = metadata !{metadata !"bool", metadata !1} From zwarich at apple.com Tue Mar 15 13:42:33 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Tue, 15 Mar 2011 18:42:33 -0000 Subject: [llvm-commits] [llvm] r127684 - /llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Message-ID: <20110315184233.732F22A6C12C@llvm.org> Author: zwarich Date: Tue Mar 15 13:42:33 2011 New Revision: 127684 URL: http://llvm.org/viewvc/llvm-project?rev=127684&view=rev Log: Clean up something noticed by Fritz. Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=127684&r1=127683&r2=127684&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Tue Mar 15 13:42:33 2011 @@ -269,7 +269,7 @@ // Remove PHI nodes that did not have any uses rewritten. for (unsigned i = 0, e = AddedPHIs.size(); i != e; ++i) { - if (!AddedPHIs[i]->hasNUsesOrMore(1)) + if (AddedPHIs[i]->use_empty()) AddedPHIs[i]->eraseFromParent(); } From joerg at britannica.bec.de Tue Mar 15 14:04:54 2011 From: joerg at britannica.bec.de (Joerg Sonnenberger) Date: Tue, 15 Mar 2011 20:04:54 +0100 Subject: [llvm-commits] Support for explicit argument form of X86 string instructions In-Reply-To: References: <20110306232445.GA3958@britannica.bec.de> Message-ID: <20110315190454.GA30805@britannica.bec.de> On Tue, Mar 15, 2011 at 11:43:54AM -0700, Chris Lattner wrote: > Please do not accept (%dx) for ins and outs. I know that we accept > them for in/out, but this is just because of compatibility with specific > broken patterns in existing code, it isn't something that should spread > to other places. This eliminates the need for isPortDxOp. OK. > +bool X86ATTAsmParser::isDstOp(X86Operand &Op) { > > Please add a doxygen comment explaining what pattern this matches. OK. > Also, I think this can just be a static function, it doesn't need to > be a method on X86ATTAsmParser. Likewise for the other predicates. It does want to know if it is 32bit or 64bit mode. That's the only reason why it is in X86ATTAsmParser. Passing down the variable feels like a greater cludge. > Instead of handling "lods" and "stos" in ParseInstruction, can't you > just ignore these two cases and let the suffix search code in > MatchAndEmitInstruction handle them? MatchAndEmitInstruction and doesn't the register anymore, so it can't do that matching, I think. The actual instructions can't be used without suffix. Joerg From clattner at apple.com Tue Mar 15 15:03:10 2011 From: clattner at apple.com (Chris Lattner) Date: Tue, 15 Mar 2011 13:03:10 -0700 Subject: [llvm-commits] Support for explicit argument form of X86 string instructions In-Reply-To: <20110315190454.GA30805@britannica.bec.de> References: <20110306232445.GA3958@britannica.bec.de> <20110315190454.GA30805@britannica.bec.de> Message-ID: On Mar 15, 2011, at 12:04 PM, Joerg Sonnenberger wrote: >> >> Also, I think this can just be a static function, it doesn't need to >> be a method on X86ATTAsmParser. Likewise for the other predicates. > > It does want to know if it is 32bit or 64bit mode. That's the only > reason why it is in X86ATTAsmParser. Passing down the variable feels > like a greater cludge. Ah ok! >> Instead of handling "lods" and "stos" in ParseInstruction, can't you >> just ignore these two cases and let the suffix search code in >> MatchAndEmitInstruction handle them? > > MatchAndEmitInstruction and doesn't the register anymore, so it can't do > that matching, I think. The actual instructions can't be used without > suffix. I'm not sure what you mean, -Chris From grosbach at apple.com Tue Mar 15 15:25:54 2011 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 15 Mar 2011 20:25:54 -0000 Subject: [llvm-commits] [llvm] r127691 - /llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Message-ID: <20110315202554.BF1762A6C12C@llvm.org> Author: grosbach Date: Tue Mar 15 15:25:54 2011 New Revision: 127691 URL: http://llvm.org/viewvc/llvm-project?rev=127691&view=rev Log: Trailing whitespae. Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=127691&r1=127690&r2=127691&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Tue Mar 15 15:25:54 2011 @@ -35,7 +35,7 @@ using namespace llvm; -#ifdef __APPLE__ +#ifdef __APPLE__ // Apple gcc defaults to -fuse-cxa-atexit (i.e. calls __cxa_atexit instead // of atexit). It passes the address of linker generated symbol __dso_handle // to the function. @@ -75,7 +75,7 @@ #endif #if HAVE_EHTABLE_SUPPORT - + // libgcc defines the __register_frame function to dynamically register new // dwarf frames for exception handling. This functionality is not portable // across compilers and is only provided by GCC. We use the __register_frame @@ -113,10 +113,10 @@ void *unused1; void *unused2; void *unused3; - + /// frame - Pointer to the exception table. void *frame; - + /// encoding - The encoding of the object? union { struct { @@ -124,15 +124,15 @@ unsigned long from_array : 1; unsigned long mixed_encoding : 1; unsigned long encoding : 8; - unsigned long count : 21; + unsigned long count : 21; } b; size_t i; } encoding; - + /// fde_end - libgcc defines this field only if some macro is defined. We /// include this field even if it may not there, to make libgcc happy. char *fde_end; - + /// next - At least we know it's a chained list! struct LibgccObject *next; }; @@ -153,7 +153,7 @@ /// unseenObjects - LibgccObjects not parsed yet by the unwinding runtime. /// struct LibgccObject* unseenObjects; - + unsigned unused[2]; }; @@ -165,32 +165,32 @@ LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); assert(LOI && "This should be preallocated by the runtime"); - + // Allocate a new LibgccObject to represent this frame. Deallocation of this // object may be impossible: since darwin code in libgcc was written after // the ability to dynamically register frames, things may crash if we // deallocate it. struct LibgccObject* ob = (struct LibgccObject*) malloc(sizeof(struct LibgccObject)); - + // Do like libgcc for the values of the field. ob->unused1 = (void *)-1; ob->unused2 = 0; ob->unused3 = 0; ob->frame = FrameBegin; - ob->encoding.i = 0; + ob->encoding.i = 0; ob->encoding.b.encoding = llvm::dwarf::DW_EH_PE_omit; - + // Put the info on both places, as libgcc uses the first or the second // field. Note that we rely on having two pointers here. If fde_end was a // char, things would get complicated. ob->fde_end = (char*)LOI->unseenObjects; ob->next = LOI->unseenObjects; - + // Update the key's unseenObjects list. LOI->unseenObjects = ob; - - // Finally update the "key". Apparently, libgcc requires it. + + // Finally update the "key". Apparently, libgcc requires it. _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, LOI); @@ -312,18 +312,18 @@ if (TM.addPassesToEmitMachineCode(PM, *JCE, OptLevel)) { report_fatal_error("Target does not support machine code emission!"); } - + // Register routine for informing unwinding runtime about new EH frames #if HAVE_EHTABLE_SUPPORT #if USE_KEYMGR struct LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); - + // The key is created on demand, and libgcc creates it the first time an // exception occurs. Since we need the key to register frames, we create // it now. if (!LOI) - LOI = (LibgccObjectInfo*)calloc(sizeof(struct LibgccObjectInfo), 1); + LOI = (LibgccObjectInfo*)calloc(sizeof(struct LibgccObjectInfo), 1); _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, LOI); InstallExceptionTableRegister(DarwinRegisterFrame); // Not sure about how to deregister on Darwin. @@ -332,7 +332,7 @@ InstallExceptionTableDeregister(__deregister_frame); #endif // __APPLE__ #endif // HAVE_EHTABLE_SUPPORT - + // Initialize passes. PM.doInitialization(); } @@ -365,11 +365,11 @@ if (TM.addPassesToEmitMachineCode(PM, *JCE, CodeGenOpt::Default)) { report_fatal_error("Target does not support machine code emission!"); } - + // Initialize passes. PM.doInitialization(); } - + ExecutionEngine::addModule(M); } @@ -377,29 +377,29 @@ /// since the PassManager it contains references a released Module. bool JIT::removeModule(Module *M) { bool result = ExecutionEngine::removeModule(M); - + MutexGuard locked(lock); - + if (jitstate->getModule() == M) { delete jitstate; jitstate = 0; } - + if (!jitstate && !Modules.empty()) { jitstate = new JITState(Modules[0]); FunctionPassManager &PM = jitstate->getPM(locked); PM.add(new TargetData(*TM.getTargetData())); - + // Turn the machine code intermediate representation into bytes in memory // that may be executed. if (TM.addPassesToEmitMachineCode(PM, *JCE, CodeGenOpt::Default)) { report_fatal_error("Target does not support machine code emission!"); } - + // Initialize passes. PM.doInitialization(); - } + } return result; } @@ -433,7 +433,7 @@ // Call the function. GenericValue rv; - rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), + rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), (char **)GVTOP(ArgValues[1]), (const char **)GVTOP(ArgValues[2]))); return rv; @@ -446,7 +446,7 @@ // Call the function. GenericValue rv; - rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), + rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), (char **)GVTOP(ArgValues[1]))); return rv; } @@ -480,7 +480,7 @@ rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)()); else if (BitWidth <= 64) rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)()); - else + else llvm_unreachable("Integer types > 64 bits not supported"); return rv; } @@ -542,7 +542,7 @@ case Type::PointerTyID: void *ArgPtr = GVTOP(AV); if (sizeof(void*) == 4) - C = ConstantInt::get(Type::getInt32Ty(F->getContext()), + C = ConstantInt::get(Type::getInt32Ty(F->getContext()), (int)(intptr_t)ArgPtr); else C = ConstantInt::get(Type::getInt64Ty(F->getContext()), @@ -649,7 +649,7 @@ "Externally-defined function should not be in pending list."); jitTheFunction(PF, locked); - + // Now that the function has been jitted, ask the JITEmitter to rewrite // the stub with real address of the function. updateFunctionStub(PF); @@ -703,7 +703,7 @@ void JIT::addPointerToBasicBlock(const BasicBlock *BB, void *Addr) { MutexGuard locked(lock); - + BasicBlockAddressMapTy::iterator I = getBasicBlockAddressMap(locked).find(BB); if (I == getBasicBlockAddressMap(locked).end()) { @@ -724,7 +724,7 @@ // resolve basic block address MutexGuard locked(lock); - + BasicBlockAddressMapTy::iterator I = getBasicBlockAddressMap(locked).find(BB); if (I != getBasicBlockAddressMap(locked).end()) { From joerg at britannica.bec.de Tue Mar 15 15:44:50 2011 From: joerg at britannica.bec.de (Joerg Sonnenberger) Date: Tue, 15 Mar 2011 21:44:50 +0100 Subject: [llvm-commits] Support for explicit argument form of X86 string instructions In-Reply-To: References: <20110306232445.GA3958@britannica.bec.de> <20110315190454.GA30805@britannica.bec.de> Message-ID: <20110315204450.GA29298@britannica.bec.de> On Tue, Mar 15, 2011 at 01:03:10PM -0700, Chris Lattner wrote: > >> Instead of handling "lods" and "stos" in ParseInstruction, can't you > >> just ignore these two cases and let the suffix search code in > >> MatchAndEmitInstruction handle them? > > > > MatchAndEmitInstruction and doesn't the register anymore, so it can't do > > that matching, I think. The actual instructions can't be used without > > suffix. > > I'm not sure what you mean, lods without arguments is ambigious and MatchAndEmitInstruction doesn't see the optional arguments. Joerg From isanbard at gmail.com Tue Mar 15 15:47:26 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 15 Mar 2011 20:47:26 -0000 Subject: [llvm-commits] [llvm] r127694 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h test/CodeGen/ARM/vext.ll Message-ID: <20110315204726.937702A6C12C@llvm.org> Author: void Date: Tue Mar 15 15:47:26 2011 New Revision: 127694 URL: http://llvm.org/viewvc/llvm-project?rev=127694&view=rev Log: Some minor cleanups based on feedback. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/test/CodeGen/ARM/vext.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127694&r1=127693&r2=127694&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Mar 15 15:47:26 2011 @@ -854,8 +854,6 @@ case ARMISD::VTRN: return "ARMISD::VTRN"; case ARMISD::VTBL1: return "ARMISD::VTBL1"; case ARMISD::VTBL2: return "ARMISD::VTBL2"; - case ARMISD::VTBL3: return "ARMISD::VTBL3"; - case ARMISD::VTBL4: return "ARMISD::VTBL4"; case ARMISD::VMULLs: return "ARMISD::VMULLs"; case ARMISD::VMULLu: return "ARMISD::VMULLu"; case ARMISD::BUILD_VECTOR: return "ARMISD::BUILD_VECTOR"; @@ -4076,10 +4074,10 @@ return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1, DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, &VTBLMask[0], 8)); - else - return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2, - DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, - &VTBLMask[0], 8)); + + return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2, + DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, + &VTBLMask[0], 8)); } static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=127694&r1=127693&r2=127694&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Tue Mar 15 15:47:26 2011 @@ -155,8 +155,6 @@ VTRN, // transpose VTBL1, // 1-register shuffle with mask VTBL2, // 2-register shuffle with mask - VTBL3, // 3-register shuffle with mask - VTBL4, // 4-register shuffle with mask // Vector multiply long: VMULLs, // ...signed Modified: llvm/trunk/test/CodeGen/ARM/vext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vext.ll?rev=127694&r1=127693&r2=127694&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/vext.ll (original) +++ llvm/trunk/test/CodeGen/ARM/vext.ll Tue Mar 15 15:47:26 2011 @@ -121,3 +121,15 @@ %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <4 x i32> ret <4 x i16> %tmp2 } + +; The actual shuffle code only handles some cases, make sure we check +; this rather than blindly emitting a VECTOR_SHUFFLE (infinite +; lowering loop can result otherwise). +define <8 x i16> @test_illegal(<8 x i16>* %A, <8 x i16>* %B) nounwind { +;CHECK: test_illegal: +;CHECK: vst1.16 + %tmp1 = load <8 x i16>* %A + %tmp2 = load <8 x i16>* %B + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> + ret <8 x i16> %tmp3 +} From bob.wilson at apple.com Tue Mar 15 16:02:25 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 15 Mar 2011 14:02:25 -0700 Subject: [llvm-commits] [llvm] r127694 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h test/CodeGen/ARM/vext.ll In-Reply-To: <20110315204726.937702A6C12C@llvm.org> References: <20110315204726.937702A6C12C@llvm.org> Message-ID: <2B0E56D9-7076-4AE2-B003-B6A367616B30@apple.com> Thanks, Bill. You're still going to update ARMTargetLowering::isShuffleMaskLegal, right? On Mar 15, 2011, at 1:47 PM, Bill Wendling wrote: > Author: void > Date: Tue Mar 15 15:47:26 2011 > New Revision: 127694 > > URL: http://llvm.org/viewvc/llvm-project?rev=127694&view=rev > Log: > Some minor cleanups based on feedback. > > Modified: > llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > llvm/trunk/lib/Target/ARM/ARMISelLowering.h > llvm/trunk/test/CodeGen/ARM/vext.ll > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127694&r1=127693&r2=127694&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Mar 15 15:47:26 2011 > @@ -854,8 +854,6 @@ > case ARMISD::VTRN: return "ARMISD::VTRN"; > case ARMISD::VTBL1: return "ARMISD::VTBL1"; > case ARMISD::VTBL2: return "ARMISD::VTBL2"; > - case ARMISD::VTBL3: return "ARMISD::VTBL3"; > - case ARMISD::VTBL4: return "ARMISD::VTBL4"; > case ARMISD::VMULLs: return "ARMISD::VMULLs"; > case ARMISD::VMULLu: return "ARMISD::VMULLu"; > case ARMISD::BUILD_VECTOR: return "ARMISD::BUILD_VECTOR"; > @@ -4076,10 +4074,10 @@ > return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1, > DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, > &VTBLMask[0], 8)); > - else > - return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2, > - DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, > - &VTBLMask[0], 8)); > + > + return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2, > + DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, > + &VTBLMask[0], 8)); > } > > static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=127694&r1=127693&r2=127694&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Tue Mar 15 15:47:26 2011 > @@ -155,8 +155,6 @@ > VTRN, // transpose > VTBL1, // 1-register shuffle with mask > VTBL2, // 2-register shuffle with mask > - VTBL3, // 3-register shuffle with mask > - VTBL4, // 4-register shuffle with mask > > // Vector multiply long: > VMULLs, // ...signed > > Modified: llvm/trunk/test/CodeGen/ARM/vext.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vext.ll?rev=127694&r1=127693&r2=127694&view=diff > ============================================================================== > --- llvm/trunk/test/CodeGen/ARM/vext.ll (original) > +++ llvm/trunk/test/CodeGen/ARM/vext.ll Tue Mar 15 15:47:26 2011 > @@ -121,3 +121,15 @@ > %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <4 x i32> > ret <4 x i16> %tmp2 > } > + > +; The actual shuffle code only handles some cases, make sure we check > +; this rather than blindly emitting a VECTOR_SHUFFLE (infinite > +; lowering loop can result otherwise). > +define <8 x i16> @test_illegal(<8 x i16>* %A, <8 x i16>* %B) nounwind { > +;CHECK: test_illegal: > +;CHECK: vst1.16 > + %tmp1 = load <8 x i16>* %A > + %tmp2 = load <8 x i16>* %B > + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> > + ret <8 x i16> %tmp3 > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Tue Mar 15 16:04:13 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 15 Mar 2011 14:04:13 -0700 Subject: [llvm-commits] [llvm] r127694 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h test/CodeGen/ARM/vext.ll In-Reply-To: <2B0E56D9-7076-4AE2-B003-B6A367616B30@apple.com> References: <20110315204726.937702A6C12C@llvm.org> <2B0E56D9-7076-4AE2-B003-B6A367616B30@apple.com> Message-ID: <6B09378F-CC30-4015-AD90-324398CE70E2@gmail.com> Yes. -bw On Mar 15, 2011, at 2:02 PM, Bob Wilson wrote: > Thanks, Bill. You're still going to update ARMTargetLowering::isShuffleMaskLegal, right? > > On Mar 15, 2011, at 1:47 PM, Bill Wendling wrote: > >> Author: void >> Date: Tue Mar 15 15:47:26 2011 >> New Revision: 127694 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127694&view=rev >> Log: >> Some minor cleanups based on feedback. >> >> Modified: >> llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp >> llvm/trunk/lib/Target/ARM/ARMISelLowering.h >> llvm/trunk/test/CodeGen/ARM/vext.ll >> >> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127694&r1=127693&r2=127694&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Mar 15 15:47:26 2011 >> @@ -854,8 +854,6 @@ >> case ARMISD::VTRN: return "ARMISD::VTRN"; >> case ARMISD::VTBL1: return "ARMISD::VTBL1"; >> case ARMISD::VTBL2: return "ARMISD::VTBL2"; >> - case ARMISD::VTBL3: return "ARMISD::VTBL3"; >> - case ARMISD::VTBL4: return "ARMISD::VTBL4"; >> case ARMISD::VMULLs: return "ARMISD::VMULLs"; >> case ARMISD::VMULLu: return "ARMISD::VMULLu"; >> case ARMISD::BUILD_VECTOR: return "ARMISD::BUILD_VECTOR"; >> @@ -4076,10 +4074,10 @@ >> return DAG.getNode(ARMISD::VTBL1, DL, MVT::v8i8, V1, >> DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, >> &VTBLMask[0], 8)); >> - else >> - return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2, >> - DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, >> - &VTBLMask[0], 8)); >> + >> + return DAG.getNode(ARMISD::VTBL2, DL, MVT::v8i8, V1, V2, >> + DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v8i8, >> + &VTBLMask[0], 8)); >> } >> >> static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { >> >> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=127694&r1=127693&r2=127694&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) >> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Tue Mar 15 15:47:26 2011 >> @@ -155,8 +155,6 @@ >> VTRN, // transpose >> VTBL1, // 1-register shuffle with mask >> VTBL2, // 2-register shuffle with mask >> - VTBL3, // 3-register shuffle with mask >> - VTBL4, // 4-register shuffle with mask >> >> // Vector multiply long: >> VMULLs, // ...signed >> >> Modified: llvm/trunk/test/CodeGen/ARM/vext.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/vext.ll?rev=127694&r1=127693&r2=127694&view=diff >> ============================================================================== >> --- llvm/trunk/test/CodeGen/ARM/vext.ll (original) >> +++ llvm/trunk/test/CodeGen/ARM/vext.ll Tue Mar 15 15:47:26 2011 >> @@ -121,3 +121,15 @@ >> %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <4 x i32> >> ret <4 x i16> %tmp2 >> } >> + >> +; The actual shuffle code only handles some cases, make sure we check >> +; this rather than blindly emitting a VECTOR_SHUFFLE (infinite >> +; lowering loop can result otherwise). >> +define <8 x i16> @test_illegal(<8 x i16>* %A, <8 x i16>* %B) nounwind { >> +;CHECK: test_illegal: >> +;CHECK: vst1.16 >> + %tmp1 = load <8 x i16>* %A >> + %tmp2 = load <8 x i16>* %B >> + %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> >> + ret <8 x i16> %tmp3 >> +} >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From geek4civic at gmail.com Tue Mar 15 16:07:44 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Tue, 15 Mar 2011 21:07:44 -0000 Subject: [llvm-commits] [llvm] r127696 - /llvm/trunk/utils/lit/lit/ProgressBar.py Message-ID: <20110315210744.779AD2A6C12C@llvm.org> Author: chapuni Date: Tue Mar 15 16:07:44 2011 New Revision: 127696 URL: http://llvm.org/viewvc/llvm-project?rev=127696&view=rev Log: lit/ProgressBar.py: [PR7919] Improve line wrap for XN-incapable terminals. On Win32 console, emitting char to col#79 causes linefeed, and the cursor will not return to col#79 upper line with backspace. Modified: llvm/trunk/utils/lit/lit/ProgressBar.py Modified: llvm/trunk/utils/lit/lit/ProgressBar.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/ProgressBar.py?rev=127696&r1=127695&r2=127696&view=diff ============================================================================== --- llvm/trunk/utils/lit/lit/ProgressBar.py (original) +++ llvm/trunk/utils/lit/lit/ProgressBar.py Tue Mar 15 16:07:44 2011 @@ -105,6 +105,7 @@ # Look up numeric capabilities. self.COLS = curses.tigetnum('cols') self.LINES = curses.tigetnum('lines') + self.XN = curses.tigetflag('xenl') # Look up string capabilities. for capability in self._STRING_CAPABILITIES: @@ -205,7 +206,7 @@ The progress bar is colored, if the terminal supports color output; and adjusts to the width of the terminal. """ - BAR = '%s${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}%s\n' + BAR = '%s${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}%s' HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n' def __init__(self, term, header, useETA=True): @@ -213,7 +214,15 @@ if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL): raise ValueError("Terminal isn't capable enough -- you " "should use a simpler progress dispaly.") - self.width = self.term.COLS or 75 + self.BOL = self.term.BOL # BoL from col#79 + self.XNL = "\n" # Newline from col#79 + if self.term.COLS: + self.width = self.term.COLS + if not self.term.XN: + self.BOL = self.term.UP + self.term.BOL + self.XNL = "" # Cursor must be fed to the next line + else: + self.width = 75 self.bar = term.render(self.BAR) self.header = self.term.render(self.HEADER % header.center(self.width)) self.cleared = 1 #: true if we haven't drawn the bar yet. @@ -244,15 +253,19 @@ else: message = '... ' + message[-(self.width-4):] sys.stdout.write( - self.term.BOL + self.term.UP + self.term.CLEAR_EOL + + self.BOL + self.term.UP + self.term.CLEAR_EOL + (self.bar % (prefix, '='*n, '-'*(barWidth-n), suffix)) + + self.XNL + self.term.CLEAR_EOL + message) + if not self.term.XN: + sys.stdout.flush() def clear(self): if not self.cleared: - sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL + + sys.stdout.write(self.BOL + self.term.CLEAR_EOL + self.term.UP + self.term.CLEAR_EOL + self.term.UP + self.term.CLEAR_EOL) + sys.stdout.flush() self.cleared = 1 def test(): From stoklund at 2pi.dk Tue Mar 15 16:13:22 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 15 Mar 2011 21:13:22 -0000 Subject: [llvm-commits] [llvm] r127697 - /llvm/trunk/lib/CodeGen/SplitKit.cpp Message-ID: <20110315211322.E6CD82A6C12C@llvm.org> Author: stoklund Date: Tue Mar 15 16:13:22 2011 New Revision: 127697 URL: http://llvm.org/viewvc/llvm-project?rev=127697&view=rev Log: Preserve both isPHIDef and isDefByCopy bits when copying parent values. Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=127697&r1=127696&r2=127697&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Tue Mar 15 16:13:22 2011 @@ -274,10 +274,6 @@ // Create a new value. VNInfo *VNI = LI->getNextValue(Idx, 0, LIS.getVNInfoAllocator()); - // Preserve the PHIDef bit. - if (ParentVNI->isPHIDef() && Idx == ParentVNI->def) - VNI->setIsPHIDef(true); - // Use insert for lookup, so we can add missing values with a second lookup. std::pair InsP = Values.insert(std::make_pair(std::make_pair(RegIdx, ParentVNI->id), VNI)); @@ -845,7 +841,10 @@ if (ParentVNI->isUnused()) continue; unsigned RegIdx = RegAssign.lookup(ParentVNI->def); - defValue(RegIdx, ParentVNI, ParentVNI->def); + VNInfo *VNI = defValue(RegIdx, ParentVNI, ParentVNI->def); + VNI->setIsPHIDef(ParentVNI->isPHIDef()); + VNI->setCopy(ParentVNI->getCopy()); + // Mark rematted values as complex everywhere to force liveness computation. // The new live ranges may be truncated. if (Edit->didRematerialize(ParentVNI)) From stoklund at 2pi.dk Tue Mar 15 16:13:25 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 15 Mar 2011 21:13:25 -0000 Subject: [llvm-commits] [llvm] r127698 - /llvm/trunk/lib/CodeGen/InlineSpiller.cpp Message-ID: <20110315211325.647342A6C12D@llvm.org> Author: stoklund Date: Tue Mar 15 16:13:25 2011 New Revision: 127698 URL: http://llvm.org/viewvc/llvm-project?rev=127698&view=rev Log: Trace back through sibling copies to hoist spills and find rematerializable defs. After live range splitting, an original value may be available in multiple registers. Tracing back through the registers containing the same value, find the best place to insert a spill, determine if the value has already been spilled, or discover a reaching def that may be rematerialized. This is only the analysis part. The information is not used for anything yet. Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=127698&r1=127697&r2=127698&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Tue Mar 15 16:13:25 2011 @@ -19,8 +19,10 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/LiveStackAnalysis.h" +#include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" @@ -36,6 +38,8 @@ LiveIntervals &LIS; LiveStacks &LSS; AliasAnalysis *AA; + MachineDominatorTree &MDT; + MachineLoopInfo &Loops; VirtRegMap &VRM; MachineFrameInfo &MFI; MachineRegisterInfo &MRI; @@ -46,6 +50,7 @@ LiveRangeEdit *Edit; const TargetRegisterClass *RC; int StackSlot; + unsigned Original; // All registers to spill to StackSlot, including the main register. SmallVector RegsToSpill; @@ -57,6 +62,29 @@ // Values that failed to remat at some point. SmallPtrSet UsedValues; + // Information about a value that was defined by a copy from a sibling + // register. + struct SibValueInfo { + // True when all reaching defs were reloads: No spill is necessary. + bool AllDefsAreReloads; + + // The preferred register to spill. + unsigned SpillReg; + + // The value of SpillReg that should be spilled. + VNInfo *SpillVNI; + + // A defining instruction that is not a sibling copy or a reload, or NULL. + // This can be used as a template for rematerialization. + MachineInstr *DefMI; + + SibValueInfo(unsigned Reg, VNInfo *VNI) + : AllDefsAreReloads(false), SpillReg(Reg), SpillVNI(VNI), DefMI(0) {} + }; + + // Values in RegsToSpill defined by sibling copies. + DenseMap SibValues; + ~InlineSpiller() {} public: @@ -68,6 +96,8 @@ LIS(pass.getAnalysis()), LSS(pass.getAnalysis()), AA(&pass.getAnalysis()), + MDT(pass.getAnalysis()), + Loops(pass.getAnalysis()), VRM(vrm), MFI(*mf.getFrameInfo()), MRI(mf.getRegInfo()), @@ -80,6 +110,9 @@ bool isSnippet(const LiveInterval &SnipLI); void collectRegsToSpill(); + void traceSiblingValue(unsigned, VNInfo*, VNInfo*); + void analyzeSiblingValues(); + bool reMaterializeFor(MachineBasicBlock::iterator MI); void reMaterializeAll(); @@ -179,7 +212,6 @@ /// real use. void InlineSpiller::collectRegsToSpill() { unsigned Reg = Edit->getReg(); - unsigned Orig = VRM.getOriginal(Reg); // Main register always spills. RegsToSpill.assign(1, Reg); @@ -187,7 +219,7 @@ // Snippets all have the same original, so there can't be any for an original // register. - if (Orig == Reg) + if (Original == Reg) return; for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Reg); @@ -197,7 +229,7 @@ continue; if (!TargetRegisterInfo::isVirtualRegister(SnipReg)) continue; - if (VRM.getOriginal(SnipReg) != Orig) + if (VRM.getOriginal(SnipReg) != Original) continue; LiveInterval &SnipLI = LIS.getInterval(SnipReg); if (!isSnippet(SnipLI)) @@ -211,6 +243,169 @@ } } + +//===----------------------------------------------------------------------===// +// Sibling Values +//===----------------------------------------------------------------------===// + +// After live range splitting, some values to be spilled may be defined by +// copies from sibling registers. We trace the sibling copies back to the +// original value if it still exists. We need it for rematerialization. +// +// Even when the value can't be rematerialized, we still want to determine if +// the value has already been spilled, or we may want to hoist the spill from a +// loop. + +/// traceSiblingValue - Trace a value that is about to be spilled back to the +/// real defining instructions by looking through sibling copies. Always stay +/// within the range of OrigVNI so the registers are known to carry the same +/// value. +/// +/// Determine if the value is defined by all reloads, so spilling isn't +/// necessary - the value is already in the stack slot. +/// +/// Find a defining instruction that may be a candidate for rematerialization. +/// +void InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI, + VNInfo *OrigVNI) { + DEBUG(dbgs() << "Tracing value " << PrintReg(UseReg) << ':' + << UseVNI->id << '@' << UseVNI->def << '\n'); + SmallPtrSet Visited; + SmallVector, 8> WorkList; + WorkList.push_back(std::make_pair(UseReg, UseVNI)); + + // Best spill candidate seen so far. This must dominate UseVNI. + SibValueInfo SVI(UseReg, UseVNI); + MachineBasicBlock *UseMBB = LIS.getMBBFromIndex(UseVNI->def); + MachineBasicBlock *SpillMBB = UseMBB; + unsigned SpillDepth = Loops.getLoopDepth(SpillMBB); + bool SeenOrigPHI = false; // Original PHI met. + + do { + unsigned Reg; + VNInfo *VNI; + tie(Reg, VNI) = WorkList.pop_back_val(); + if (!Visited.insert(VNI)) + continue; + + // Is this value a better spill candidate? + if (VNI != SVI.SpillVNI) { + MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def); + if (MBB == SpillMBB) { + // Prefer to spill a previous value in the same block. + if (VNI->def < SVI.SpillVNI->def) + SVI.SpillReg = Reg, SVI.SpillVNI = VNI; + } else if (MDT.dominates(MBB, UseMBB)) { + // This is a valid spill location dominating UseVNI. + // Prefer to spill at a smaller loop depth. + unsigned Depth = Loops.getLoopDepth(MBB); + if (Depth < SpillDepth) { + DEBUG(dbgs() << " spill depth " << Depth << ": " << PrintReg(Reg) + << ':' << VNI->id << '@' << VNI->def << '\n'); + SVI.SpillReg = Reg; + SVI.SpillVNI = VNI; + SpillMBB = MBB; + SpillDepth = Depth; + } + } + } + + // Trace through PHI-defs created by live range splitting. + if (VNI->isPHIDef()) { + if (VNI->def == OrigVNI->def) { + DEBUG(dbgs() << " orig phi value " << PrintReg(Reg) << ':' + << VNI->id << '@' << VNI->def << '\n'); + SeenOrigPHI = true; + continue; + } + // Get values live-out of predecessors. + LiveInterval &LI = LIS.getInterval(Reg); + MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def); + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + VNInfo *PVNI = LI.getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot()); + if (PVNI) + WorkList.push_back(std::make_pair(Reg, PVNI)); + } + continue; + } + + MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def); + assert(MI && "Missing def"); + + // Trace through sibling copies. + if (unsigned SrcReg = isFullCopyOf(MI, Reg)) { + if (TargetRegisterInfo::isVirtualRegister(SrcReg) && + VRM.getOriginal(SrcReg) == Original) { + LiveInterval &SrcLI = LIS.getInterval(SrcReg); + VNInfo *SrcVNI = SrcLI.getVNInfoAt(VNI->def.getUseIndex()); + assert(SrcVNI && "Copy from non-existing value"); + DEBUG(dbgs() << " copy of " << PrintReg(SrcReg) << ':' + << SrcVNI->id << '@' << SrcVNI->def << '\n'); + WorkList.push_back(std::make_pair(SrcReg, SrcVNI)); + continue; + } + } + + // Track reachable reloads. + int FI; + if (Reg == TII.isLoadFromStackSlot(MI, FI) && FI == StackSlot) { + DEBUG(dbgs() << " reload " << PrintReg(Reg) << ':' + << VNI->id << "@" << VNI->def << '\n'); + SVI.AllDefsAreReloads = true; + continue; + } + + // We have an 'original' def. Don't record trivial cases. + if (VNI == UseVNI) { + DEBUG(dbgs() << "Not a sibling copy.\n"); + return; + } + + // Potential remat candidate. + DEBUG(dbgs() << " def " << PrintReg(Reg) << ':' + << VNI->id << '@' << VNI->def << '\t' << *MI); + SVI.DefMI = MI; + } while (!WorkList.empty()); + + if (SeenOrigPHI || SVI.DefMI) + SVI.AllDefsAreReloads = false; + + DEBUG({ + if (SVI.AllDefsAreReloads) + dbgs() << "All defs are reloads.\n"; + else + dbgs() << "Prefer to spill " << PrintReg(SVI.SpillReg) << ':' + << SVI.SpillVNI->id << '@' << SVI.SpillVNI->def << '\n'; + }); + SibValues.insert(std::make_pair(UseVNI, SVI)); +} + +/// analyzeSiblingValues - Trace values defined by sibling copies back to +/// something that isn't a sibling copy. +void InlineSpiller::analyzeSiblingValues() { + SibValues.clear(); + + // No siblings at all? + if (Edit->getReg() == Original) + return; + + LiveInterval &OrigLI = LIS.getInterval(Original); + for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) { + unsigned Reg = RegsToSpill[i]; + LiveInterval &LI = LIS.getInterval(Reg); + for (LiveInterval::const_vni_iterator VI = LI.vni_begin(), + VE = LI.vni_end(); VI != VE; ++VI) { + VNInfo *VNI = *VI; + if (VNI->isUnused() || !(VNI->isPHIDef() || VNI->getCopy())) + continue; + VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def); + if (OrigVNI->def != VNI->def) + traceSiblingValue(Reg, VNI, OrigVNI); + } + } +} + /// reMaterializeFor - Attempt to rematerialize before MI instead of reloading. bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) { SlotIndex UseIdx = LIS.getInstructionIndex(MI).getUseIndex(); @@ -522,19 +717,22 @@ Edit = &edit; assert(!TargetRegisterInfo::isStackSlot(edit.getReg()) && "Trying to spill a stack slot."); + + // Share a stack slot among all descendants of Original. + Original = VRM.getOriginal(edit.getReg()); + StackSlot = VRM.getStackSlot(Original); + DEBUG(dbgs() << "Inline spilling " << MRI.getRegClass(edit.getReg())->getName() << ':' << edit.getParent() << "\nFrom original " - << PrintReg(VRM.getOriginal(edit.getReg())) << '\n'); + << LIS.getInterval(Original) << '\n'); assert(edit.getParent().isSpillable() && "Attempting to spill already spilled value."); - // Share a stack slot among all descendants of Orig. - unsigned Orig = VRM.getOriginal(edit.getReg()); - StackSlot = VRM.getStackSlot(Orig); - collectRegsToSpill(); + analyzeSiblingValues(); + reMaterializeAll(); // Remat may handle everything. @@ -544,9 +742,9 @@ RC = MRI.getRegClass(edit.getReg()); if (StackSlot == VirtRegMap::NO_STACK_SLOT) - StackSlot = VRM.assignVirt2StackSlot(Orig); + StackSlot = VRM.assignVirt2StackSlot(Original); - if (Orig != edit.getReg()) + if (Original != edit.getReg()) VRM.assignVirt2StackSlot(edit.getReg(), StackSlot); // Update LiveStacks now that we are committed to spilling. From isanbard at gmail.com Tue Mar 15 16:15:20 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 15 Mar 2011 21:15:20 -0000 Subject: [llvm-commits] [llvm] r127700 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20110315211520.BEE832A6C12C@llvm.org> Author: void Date: Tue Mar 15 16:15:20 2011 New Revision: 127700 URL: http://llvm.org/viewvc/llvm-project?rev=127700&view=rev Log: The VTBL (and VTBX) instructions are rather permissive concerning the masks they accept. If a value in the mask is out of range, it uses the value 0, for VTBL, or leaves the value unchanged, for VTBX. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127700&r1=127699&r2=127700&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Mar 15 16:15:20 2011 @@ -3541,6 +3541,13 @@ return true; } +static bool isVTBLMask(const SmallVectorImpl &M, EVT VT) { + // We can handle <8 x i8> vector shuffles. If the index in the mask is out of + // range, then 0 is placed into the resulting vector. So pretty much any mask + // of 8 elements can work here. + return VT == MVT::v8i8 && M.size() == 8; +} + static bool isVTRNMask(const SmallVectorImpl &M, EVT VT, unsigned &WhichResult) { unsigned EltSz = VT.getVectorElementType().getSizeInBits(); @@ -3980,6 +3987,7 @@ isVREVMask(M, VT, 32) || isVREVMask(M, VT, 16) || isVEXTMask(M, VT, ReverseVEXT, Imm) || + isVTBLMask(M, VT) || isVTRNMask(M, VT, WhichResult) || isVUZPMask(M, VT, WhichResult) || isVZIPMask(M, VT, WhichResult) || From isanbard at gmail.com Tue Mar 15 16:19:50 2011 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 15 Mar 2011 14:19:50 -0700 Subject: [llvm-commits] [llvm] r127630 - in /llvm/trunk: lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h test/CodeGen/ARM/vext.ll In-Reply-To: <4BE24910-ABB6-435B-98EA-8917490B2751@apple.com> References: <20110314230238.AC3CF2A6C12C@llvm.org> <4BE24910-ABB6-435B-98EA-8917490B2751@apple.com> Message-ID: On Mar 14, 2011, at 11:04 PM, Bob Wilson wrote: > > On Mar 14, 2011, at 4:02 PM, Bill Wendling wrote: > >> Author: void >> Date: Mon Mar 14 18:02:38 2011 >> New Revision: 127630 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127630&view=rev >> Log: >> Generate a VTBL instruction instead of a series of loads and stores when we >> can. > > You need to update ARMTargetLowering::isShuffleMaskLegal to show that all v8i8 shuffles are legal. Done. Please check to see if it's okay. It's a very permissive set of instructions, re the mask. :-) -bw From bob.wilson at apple.com Tue Mar 15 16:24:32 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 15 Mar 2011 14:24:32 -0700 Subject: [llvm-commits] [llvm] r127630 - in /llvm/trunk: lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h test/CodeGen/ARM/vext.ll In-Reply-To: References: <20110314230238.AC3CF2A6C12C@llvm.org> <4BE24910-ABB6-435B-98EA-8917490B2751@apple.com> Message-ID: On Mar 15, 2011, at 2:19 PM, Bill Wendling wrote: > On Mar 14, 2011, at 11:04 PM, Bob Wilson wrote: > >> >> On Mar 14, 2011, at 4:02 PM, Bill Wendling wrote: >> >>> Author: void >>> Date: Mon Mar 14 18:02:38 2011 >>> New Revision: 127630 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=127630&view=rev >>> Log: >>> Generate a VTBL instruction instead of a series of loads and stores when we >>> can. >> >> You need to update ARMTargetLowering::isShuffleMaskLegal to show that all v8i8 shuffles are legal. > > Done. Please check to see if it's okay. It's a very permissive set of instructions, re the mask. :-) Yes, that looks right. Thanks! From John.Thompson.JTSoftware at gmail.com Tue Mar 15 16:51:56 2011 From: John.Thompson.JTSoftware at gmail.com (John Thompson) Date: Tue, 15 Mar 2011 21:51:56 -0000 Subject: [llvm-commits] [llvm] r127705 - in /llvm/trunk: include/llvm/ADT/Triple.h lib/Support/Triple.cpp Message-ID: <20110315215156.B09B22A6C12C@llvm.org> Author: jtsoftware Date: Tue Mar 15 16:51:56 2011 New Revision: 127705 URL: http://llvm.org/viewvc/llvm-project?rev=127705&view=rev Log: Add scei vendor Modified: llvm/trunk/include/llvm/ADT/Triple.h llvm/trunk/lib/Support/Triple.cpp Modified: llvm/trunk/include/llvm/ADT/Triple.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Triple.h?rev=127705&r1=127704&r2=127705&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/Triple.h (original) +++ llvm/trunk/include/llvm/ADT/Triple.h Tue Mar 15 16:51:56 2011 @@ -72,7 +72,8 @@ UnknownVendor, Apple, - PC + PC, + SCEI }; enum OSType { UnknownOS, Modified: llvm/trunk/lib/Support/Triple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Triple.cpp?rev=127705&r1=127704&r2=127705&view=diff ============================================================================== --- llvm/trunk/lib/Support/Triple.cpp (original) +++ llvm/trunk/lib/Support/Triple.cpp Tue Mar 15 16:51:56 2011 @@ -84,6 +84,7 @@ case Apple: return "apple"; case PC: return "pc"; + case SCEI: return "scei"; } return ""; @@ -296,6 +297,8 @@ return Apple; else if (VendorName == "pc") return PC; + else if (VendorName == "scei") + return SCEI; else return UnknownVendor; } From aggarwa4 at illinois.edu Tue Mar 15 17:03:36 2011 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 15 Mar 2011 22:03:36 -0000 Subject: [llvm-commits] [poolalloc] r127706 - /poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Message-ID: <20110315220336.DBEA02A6C12C@llvm.org> Author: aggarwa4 Date: Tue Mar 15 17:03:36 2011 New Revision: 127706 URL: http://llvm.org/viewvc/llvm-project?rev=127706&view=rev Log: Identify loopPHI nodes. Add stats. Added support to identify de-allocators. Modified: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Modified: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp?rev=127706&r1=127705&r2=127706&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp (original) +++ poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Tue Mar 15 17:03:36 2011 @@ -6,11 +6,15 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// A pass to identify functions that act as wrappers to malloc and other +// allocators. +//===----------------------------------------------------------------------===// #define DEBUG_TYPE "allocator-identify" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Pass.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/FormattedStream.h" @@ -23,15 +27,24 @@ using namespace llvm; +STATISTIC(numAllocators, "Number of malloc-like allocators"); +STATISTIC(numDeallocators, "Number of free-like deallocators"); namespace { - static bool flowsFrom(Value *Dest,Value *Src) { + class AllocIdentify : public ModulePass { + + bool flowsFrom(Value *Dest,Value *Src) { if(Dest == Src) return true; if(ReturnInst *Ret = dyn_cast(Dest)) { return flowsFrom(Ret->getReturnValue(), Src); } if(PHINode *PN = dyn_cast(Dest)) { + Function *F = PN->getParent()->getParent(); + LoopInfo &LI = getAnalysis(*F); + // If this is a loop phi, ignore. + if(LI.isLoopHeader(PN->getParent())) + return false; bool ret = true; for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { ret = ret && flowsFrom(PN->getIncomingValue(i), Src); @@ -45,9 +58,9 @@ return true; return false; } - static bool isNotStored(Value *V) { - // check that V is not stroed to a location taht is accessible outside this fn + bool isNotStored(Value *V) { + // check that V is not stroed to a location taht is accessible outside this fn for(Value::use_iterator ui = V->use_begin(), ue = V->use_end(); ui != ue; ++ui) { if(isa(ui)) @@ -67,14 +80,14 @@ else return false; - //ui->dump(); return false; } return true; } - class AllocIdentify : public ModulePass { + protected: std::set allocators; + std::set deallocators; public: static char ID; AllocIdentify() : ModulePass(&ID) {} @@ -84,6 +97,8 @@ allocators.insert("calloc"); allocators.insert("realloc"); allocators.insert("memset"); + deallocators.insert("free"); + deallocators.insert("cfree"); bool changed; do { @@ -125,9 +140,47 @@ if(isWrapper) isWrapper = isWrapper && isNotStored(CI); if(isWrapper) { - errs() << WrapperF->getNameStr() << "\n"; changed = (allocators.find(WrapperF->getName()) == allocators.end()); - allocators.insert(WrapperF->getName()); + if(changed) { + ++numAllocators; + allocators.insert(WrapperF->getName()); + DEBUG(errs() << WrapperF->getNameStr() << "\n"); + } + } + } + } + } + } while(changed); + + do { + changed = false; + std::set TempDeallocators; + TempDeallocators.insert( deallocators.begin(), deallocators.end()); + std::set::iterator it; + for(it = TempDeallocators.begin(); it != TempDeallocators.end(); ++it) { + Function* F = M.getFunction(*it); + + if(!F) + continue; + for(Value::use_iterator ui = F->use_begin(), ue = F->use_end(); + ui != ue; ++ui) { + // iterate though all calls to malloc + if (CallInst* CI = dyn_cast(ui)) { + // The function that calls malloc could be a potential allocator + Function *WrapperF = CI->getParent()->getParent(); + + if(WrapperF->arg_size() != 1) + continue; + if(!WrapperF->arg_begin()->getType()->isPointerTy()) + continue; + Argument *arg = dyn_cast(WrapperF->arg_begin()); + if(flowsFrom(CI->getOperand(1), arg)) { + changed = (deallocators.find(WrapperF->getName()) == deallocators.end()); + if(changed) { + ++numDeallocators; + deallocators.insert(WrapperF->getName()); + DEBUG(errs() << WrapperF->getNameStr() << "\n"); + } } } } @@ -135,6 +188,9 @@ } while(changed); return false; } + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredTransitive(); + } }; } From johnny.chen at apple.com Tue Mar 15 17:27:33 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 15 Mar 2011 22:27:33 -0000 Subject: [llvm-commits] [llvm] r127707 - in /llvm/trunk: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp test/MC/Disassembler/ARM/arm-tests.txt Message-ID: <20110315222733.9815D2A6C12C@llvm.org> Author: johnny Date: Tue Mar 15 17:27:33 2011 New Revision: 127707 URL: http://llvm.org/viewvc/llvm-project?rev=127707&view=rev Log: There were two issues fixed: 1. The ARM Darwin *r9 call instructions were pseudo-ized recently. Modify the ARMDisassemblerCore.cpp file to accomodate the change. 2. The disassembler was unnecessarily adding 8 to the sign-extended imm24: imm32 = SignExtend(imm24:'00', 32); // A8.6.23 BL, BLX (immediate) // Encoding A1 It has no business doing such. Removed the offending logic. Add test cases to arm-tests.txt. Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=127707&r1=127706&r2=127707&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Tue Mar 15 17:27:33 2011 @@ -679,8 +679,8 @@ } // Branch Instructions. -// BLr9: SignExtend(Imm24:'00', 32) -// Bcc, BLr9_pred: SignExtend(Imm24:'00', 32) Pred0 Pred1 +// BL: SignExtend(Imm24:'00', 32) +// Bcc, BL_pred: SignExtend(Imm24:'00', 32) Pred0 Pred1 // SMC: ZeroExtend(imm4, 32) // SVC: ZeroExtend(Imm24, 32) // @@ -760,7 +760,7 @@ return true; } - assert((Opcode == ARM::Bcc || Opcode == ARM::BLr9 || Opcode == ARM::BLr9_pred + assert((Opcode == ARM::Bcc || Opcode == ARM::BL || Opcode == ARM::BL_pred || Opcode == ARM::SMC || Opcode == ARM::SVC) && "Unexpected Opcode"); @@ -778,12 +778,6 @@ unsigned Imm26 = slice(insn, 23, 0) << 2; //Imm32 = signextend(Imm26); Imm32 = SignExtend32<26>(Imm26); - - // When executing an ARM instruction, PC reads as the address of the current - // instruction plus 8. The assembler subtracts 8 from the difference - // between the branch instruction and the target address, disassembler has - // to add 8 to compensate. - Imm32 += 8; } MI.addOperand(MCOperand::CreateImm(Imm32)); @@ -793,7 +787,7 @@ } // Misc. Branch Instructions. -// BLXr9, BXr9 +// BLX, BX // BX, BX_RET static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) { @@ -810,8 +804,7 @@ return true; // BLX and BX take one GPR reg. - if (Opcode == ARM::BLXr9 || Opcode == ARM::BLXr9_pred || - Opcode == ARM::BLX || Opcode == ARM::BLX_pred || + if (Opcode == ARM::BLX || Opcode == ARM::BLX_pred || Opcode == ARM::BX) { assert(NumOps >= 1 && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID && "Reg operand expected"); Modified: llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt?rev=127707&r1=127706&r2=127707&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/arm-tests.txt Tue Mar 15 17:27:33 2011 @@ -1,7 +1,13 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 | FileCheck %s # CHECK: b #0 -0xfe 0xff 0xff 0xea +0x00 0x00 0x00 0xea + +# CHECK: bl #7732 +0x8d 0x07 0x00 0xeb + +# CHECK: bleq #-4 +0xff 0xff 0xff 0x0b # CHECK: bfc r8, #0, #16 0x1f 0x80 0xcf 0xe7 From joerg at britannica.bec.de Tue Mar 15 18:59:12 2011 From: joerg at britannica.bec.de (Joerg Sonnenberger) Date: Wed, 16 Mar 2011 00:59:12 +0100 Subject: [llvm-commits] Support for explicit argument form of X86 string instructions In-Reply-To: References: <20110306232445.GA3958@britannica.bec.de> Message-ID: <20110315235912.GA12267@britannica.bec.de> Updated version is attached. Joerg -------------- next part -------------- A non-text attachment was scrubbed... Name: stringops.diff Type: text/x-diff Size: 10738 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110316/f135cdf7/attachment.bin From zwarich at apple.com Tue Mar 15 19:13:28 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 00:13:28 -0000 Subject: [llvm-commits] [llvm] r127714 - /llvm/trunk/include/llvm/Target/TargetData.h Message-ID: <20110316001328.F1CBB2A6C12E@llvm.org> Author: zwarich Date: Tue Mar 15 19:13:28 2011 New Revision: 127714 URL: http://llvm.org/viewvc/llvm-project?rev=127714&view=rev Log: Add TargetData::fitsInLegalInteger(). Modified: llvm/trunk/include/llvm/Target/TargetData.h Modified: llvm/trunk/include/llvm/Target/TargetData.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetData.h?rev=127714&r1=127713&r2=127714&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetData.h (original) +++ llvm/trunk/include/llvm/Target/TargetData.h Tue Mar 15 19:13:28 2011 @@ -160,7 +160,18 @@ bool isIllegalInteger(unsigned Width) const { return !isLegalInteger(Width); } - + + /// fitsInLegalInteger - This function returns true if the specified type fits + /// in a native integer type supported by the CPU. For example, if the CPU + /// only supports i32 as a native integer type, then i27 fits in a legal + // integer type but i45 does not. + bool fitsInLegalInteger(unsigned Width) const { + for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) + if (Width <= LegalIntWidths[i]) + return true; + return false; + } + /// Target pointer alignment unsigned getPointerABIAlignment() const { return PointerABIAlign; } /// Return target's alignment for stack-based pointers From zwarich at apple.com Tue Mar 15 19:13:35 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 00:13:35 -0000 Subject: [llvm-commits] [llvm] r127715 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <20110316001335.3B61A2A6C12F@llvm.org> Author: zwarich Date: Tue Mar 15 19:13:35 2011 New Revision: 127715 URL: http://llvm.org/viewvc/llvm-project?rev=127715&view=rev Log: Add a clarifying comment. Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=127715&r1=127714&r2=127715&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Mar 15 19:13:35 2011 @@ -219,7 +219,7 @@ /// optimization, which scans the uses of an alloca and determines if it can /// rewrite it in terms of a single new alloca that can be mem2reg'd. class ConvertToScalarInfo { - /// AllocaSize - The size of the alloca being considered. + /// AllocaSize - The size of the alloca being considered in bytes. unsigned AllocaSize; const TargetData &TD; From zwarich at apple.com Tue Mar 15 19:13:37 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 00:13:37 -0000 Subject: [llvm-commits] [llvm] r127716 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <20110316001337.E258D2A6C12E@llvm.org> Author: zwarich Date: Tue Mar 15 19:13:37 2011 New Revision: 127716 URL: http://llvm.org/viewvc/llvm-project?rev=127716&view=rev Log: Better use initializer lists. Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=127716&r1=127715&r2=127716&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Mar 15 19:13:37 2011 @@ -240,11 +240,8 @@ public: explicit ConvertToScalarInfo(unsigned Size, const TargetData &td) - : AllocaSize(Size), TD(td) { - IsNotTrivial = false; - VectorTy = 0; - HadAVector = false; - } + : AllocaSize(Size), TD(td), IsNotTrivial(false), VectorTy(0), + HadAVector(false) { } AllocaInst *TryConvert(AllocaInst *AI); From zwarich at apple.com Tue Mar 15 19:13:40 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 00:13:40 -0000 Subject: [llvm-commits] [llvm] r127717 - in /llvm/trunk/test/Transforms/ScalarRepl: 2008-01-29-PromoteBug.ll union-pointer.ll Message-ID: <20110316001340.DDB332A6C130@llvm.org> Author: zwarich Date: Tue Mar 15 19:13:40 2011 New Revision: 127717 URL: http://llvm.org/viewvc/llvm-project?rev=127717&view=rev Log: Add native integer type TargetData to some existing tests. Modified: llvm/trunk/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll llvm/trunk/test/Transforms/ScalarRepl/union-pointer.ll Modified: llvm/trunk/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll?rev=127717&r1=127716&r2=127717&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll Tue Mar 15 19:13:40 2011 @@ -1,6 +1,6 @@ ; RUN: opt < %s -scalarrepl -instcombine -S | grep {ret i8 17} ; rdar://5707076 -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" target triple = "i386-apple-darwin9.1.0" %struct.T = type <{ i8, [3 x i8] }> Modified: llvm/trunk/test/Transforms/ScalarRepl/union-pointer.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/union-pointer.ll?rev=127717&r1=127716&r2=127717&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/union-pointer.ll (original) +++ llvm/trunk/test/Transforms/ScalarRepl/union-pointer.ll Tue Mar 15 19:13:40 2011 @@ -3,7 +3,7 @@ ; RUN: not grep alloca ; RUN: opt < %s -scalarrepl -S | grep {ret i8} -target datalayout = "e-p:32:32" +target datalayout = "e-p:32:32-n8:16:32" target triple = "i686-apple-darwin8.7.2" %struct.Val = type { i32*, i32 } From zwarich at apple.com Tue Mar 15 19:13:44 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 00:13:44 -0000 Subject: [llvm-commits] [llvm] r127718 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/only-memcpy-uses.ll Message-ID: <20110316001344.69BBD2A6C12F@llvm.org> Author: zwarich Date: Tue Mar 15 19:13:44 2011 New Revision: 127718 URL: http://llvm.org/viewvc/llvm-project?rev=127718&view=rev Log: Only convert allocas to scalars if it is profitable. The profitability metric I chose is having a non-memcpy/memset use and being larger than any native integer type. Originally I chose having an access of a size smaller than the total size of the alloca, but this caused some minor issues on the spirit benchmark where SRoA runs again after some inlining. This fixes . Added: llvm/trunk/test/Transforms/ScalarRepl/only-memcpy-uses.ll Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=127718&r1=127717&r2=127718&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Mar 15 19:13:44 2011 @@ -238,10 +238,15 @@ /// also declared as a vector, we do want to promote to a vector. bool HadAVector; + /// HadAVector - True if there is at least one access to the alloca that is + /// not a MemTransferInst. We don't want to turn structs into large integers + /// unless there is some potential for optimization. + bool HadNonMemTransferAccess; + public: explicit ConvertToScalarInfo(unsigned Size, const TargetData &td) : AllocaSize(Size), TD(td), IsNotTrivial(false), VectorTy(0), - HadAVector(false) { } + HadAVector(false), HadNonMemTransferAccess(false) { } AllocaInst *TryConvert(AllocaInst *AI); @@ -280,9 +285,14 @@ << *VectorTy << '\n'); NewTy = VectorTy; // Use the vector type. } else { + unsigned BitWidth = AllocaSize * 8; + if (!HadAVector && !HadNonMemTransferAccess && + !TD.fitsInLegalInteger(BitWidth)) + return 0; + DEBUG(dbgs() << "CONVERT TO SCALAR INTEGER: " << *AI << "\n"); // Create and insert the integer alloca. - NewTy = IntegerType::get(AI->getContext(), AllocaSize*8); + NewTy = IntegerType::get(AI->getContext(), BitWidth); } AllocaInst *NewAI = new AllocaInst(NewTy, 0, "", AI->getParent()->begin()); ConvertUsesToScalar(AI, NewAI, 0); @@ -431,6 +441,7 @@ // Don't touch MMX operations. if (LI->getType()->isX86_MMXTy()) return false; + HadNonMemTransferAccess = true; MergeInType(LI->getType(), Offset); continue; } @@ -441,6 +452,7 @@ // Don't touch MMX operations. if (SI->getOperand(0)->getType()->isX86_MMXTy()) return false; + HadNonMemTransferAccess = true; MergeInType(SI->getOperand(0)->getType(), Offset); continue; } @@ -465,6 +477,7 @@ if (!CanConvertToScalar(GEP, Offset+GEPOffset)) return false; IsNotTrivial = true; // Can't be mem2reg'd. + HadNonMemTransferAccess = true; continue; } @@ -476,6 +489,7 @@ !isa(MSI->getLength())) return false; IsNotTrivial = true; // Can't be mem2reg'd. + HadNonMemTransferAccess = true; continue; } Added: llvm/trunk/test/Transforms/ScalarRepl/only-memcpy-uses.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/only-memcpy-uses.ll?rev=127718&view=auto ============================================================================== --- llvm/trunk/test/Transforms/ScalarRepl/only-memcpy-uses.ll (added) +++ llvm/trunk/test/Transforms/ScalarRepl/only-memcpy-uses.ll Tue Mar 15 19:13:44 2011 @@ -0,0 +1,27 @@ +; RUN: opt < %s -scalarrepl -S | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin10.0.0" + +%struct.S = type { [12 x i32] } + +; CHECK: @bar4 +define void @bar4(%struct.S* byval %s) nounwind ssp { +entry: +; CHECK: alloca +; CHECK-NOT: load +; CHECK: memcpy + %t = alloca %struct.S, align 4 + %agg.tmp = alloca %struct.S, align 4 + %tmp = bitcast %struct.S* %t to i8* + %tmp1 = bitcast %struct.S* %s to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %tmp1, i64 48, i32 4, i1 false) + %tmp2 = bitcast %struct.S* %agg.tmp to i8* + %tmp3 = bitcast %struct.S* %t to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* %tmp3, i64 48, i32 4, i1 false) + %call = call i32 (...)* @bazz(%struct.S* byval %agg.tmp) + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind + +declare i32 @bazz(...) From dpatel at apple.com Tue Mar 15 19:27:57 2011 From: dpatel at apple.com (Devang Patel) Date: Wed, 16 Mar 2011 00:27:57 -0000 Subject: [llvm-commits] [llvm] r127720 - /llvm/trunk/lib/VMCore/DebugInfoProbe.cpp Message-ID: <20110316002757.AC6A52A6C12C@llvm.org> Author: dpatel Date: Tue Mar 15 19:27:57 2011 New Revision: 127720 URL: http://llvm.org/viewvc/llvm-project?rev=127720&view=rev Log: Do not accidently initialize NumDbgValueLost and NumDbgLineLost counts. Modified: llvm/trunk/lib/VMCore/DebugInfoProbe.cpp Modified: llvm/trunk/lib/VMCore/DebugInfoProbe.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/DebugInfoProbe.cpp?rev=127720&r1=127719&r2=127720&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/DebugInfoProbe.cpp (original) +++ llvm/trunk/lib/VMCore/DebugInfoProbe.cpp Tue Mar 15 19:27:57 2011 @@ -80,8 +80,6 @@ void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) { if (!EnableDebugInfoProbe) return; PassName = PName; - NumDbgLineLost = 0; - NumDbgValueLost = 0; LineNos.clear(); DbgVariables.clear(); @@ -121,6 +119,8 @@ << PassName << "\n"; delete OutStream; } + NumDbgLineLost = 0; + NumDbgValueLost = 0; } /// finalize - Collect information after running an optimization pass. This @@ -135,7 +135,7 @@ E = LineNos.end(); I != E; ++I) { unsigned LineNo = *I; if (LineNos2.count(LineNo) == 0) { - DEBUG(dbgs() << "Losing dbg info intrinsic at line " << LineNo << " "); + DEBUG(dbgs() << "DebugInfoProbe: Losing dbg info intrinsic at line " << LineNo << "\n"); ++NumDbgLineLost; } } @@ -161,7 +161,7 @@ for (std::set::iterator I = DbgVariables.begin(), E = DbgVariables.end(); I != E; ++I) { if (DbgVariables2.count(*I) == 0) { - DEBUG(dbgs() << "Losing dbg info for variable: "); + DEBUG(dbgs() << "DebugInfoProbe: Losing dbg info for variable: "); DEBUG((*I)->print(dbgs())); ++NumDbgValueLost; } From grosbach at apple.com Tue Mar 15 20:21:55 2011 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 16 Mar 2011 01:21:55 -0000 Subject: [llvm-commits] [llvm] r127721 - in /llvm/trunk/lib/ExecutionEngine/JIT: JIT.h JITEmitter.cpp Message-ID: <20110316012155.988CC2A6C12C@llvm.org> Author: grosbach Date: Tue Mar 15 20:21:55 2011 New Revision: 127721 URL: http://llvm.org/viewvc/llvm-project?rev=127721&view=rev Log: Tidy up. Whitespace and 80 column. Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.h llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.h?rev=127721&r1=127720&r2=127721&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.h (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.h Tue Mar 15 20:21:55 2011 @@ -42,7 +42,7 @@ FunctionPassManager &getPM(const MutexGuard &L) { return PM; } - + Module *getModule() const { return M; } std::vector > &getPendingFunctions(const MutexGuard &L){ return PendingFunctions; @@ -86,7 +86,7 @@ static void Register() { JITCtor = createJIT; } - + /// getJITInfo - Return the target JIT information structure. /// TargetJITInfo &getJITInfo() const { return TJI; } @@ -106,7 +106,7 @@ } virtual void addModule(Module *M); - + /// removeModule - Remove a Module from the list of modules. Returns true if /// M is found. virtual bool removeModule(Module *M); @@ -146,7 +146,7 @@ /// getPointerToBasicBlock - This returns the address of the specified basic /// block, assuming function is compiled. void *getPointerToBasicBlock(BasicBlock *BB); - + /// getOrEmitGlobalVariable - Return the address of the specified global /// variable, possibly emitting it to memory if needed. This is used by the /// Emitter. @@ -172,7 +172,7 @@ void freeMachineCodeForFunction(Function *F); /// addPendingFunction - while jitting non-lazily, a called but non-codegen'd - /// function was encountered. Add it to a pending list to be processed after + /// function was encountered. Add it to a pending list to be processed after /// the current function. /// void addPendingFunction(Function *F); Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=127721&r1=127720&r2=127721&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Tue Mar 15 20:21:55 2011 @@ -123,8 +123,8 @@ return FunctionToLazyStubMap; } - GlobalToIndirectSymMapTy& getGlobalToIndirectSymMap(const MutexGuard& locked) { - assert(locked.holds(TheJIT->lock)); + GlobalToIndirectSymMapTy& getGlobalToIndirectSymMap(const MutexGuard& lck) { + assert(lck.holds(TheJIT->lock)); return GlobalToIndirectSymMap; } @@ -132,8 +132,9 @@ const MutexGuard &locked, void *CallSite) const { assert(locked.holds(TheJIT->lock)); - // The address given to us for the stub may not be exactly right, it might be - // a little bit after the stub. As such, use upper_bound to find it. + // The address given to us for the stub may not be exactly right, it + // might be a little bit after the stub. As such, use upper_bound to + // find it. CallSiteToFunctionMapTy::const_iterator I = CallSiteToFunctionMap.upper_bound(CallSite); assert(I != CallSiteToFunctionMap.begin() && @@ -659,7 +660,8 @@ // If lazy compilation is disabled, emit a useful error message and abort. if (!JR->TheJIT->isCompilingLazily()) { - report_fatal_error("LLVM JIT requested to do lazy compilation of function '" + report_fatal_error("LLVM JIT requested to do lazy compilation of" + " function '" + F->getName() + "' when lazy compiles are disabled!"); } @@ -745,7 +747,7 @@ void JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) { if (DL.isUnknown()) return; if (!BeforePrintingInsn) return; - + const LLVMContext &Context = EmissionDetails.MF->getFunction()->getContext(); if (DL.getScope(Context) != 0 && PrevDL != DL) { @@ -781,7 +783,7 @@ uintptr_t ActualSize = 0; // Set the memory writable, if it's not already MemMgr->setMemoryWritable(); - + if (SizeEstimate > 0) { // SizeEstimate will be non-zero on reallocation attempts. ActualSize = SizeEstimate; @@ -859,7 +861,8 @@ } else if (MR.isBasicBlock()) { ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock()); } else if (MR.isConstantPoolIndex()) { - ResultPtr = (void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex()); + ResultPtr = + (void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex()); } else { assert(MR.isJumpTableIndex()); ResultPtr=(void*)getJumpTableEntryAddress(MR.getJumpTableIndex()); @@ -1130,7 +1133,7 @@ const std::vector &JT = MJTI->getJumpTables(); if (JT.empty() || JumpTableBase == 0) return; - + switch (MJTI->getEntryKind()) { case MachineJumpTableInfo::EK_Inline: return; @@ -1139,11 +1142,11 @@ // .word LBB123 assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == sizeof(void*) && "Cross JIT'ing?"); - + // For each jump table, map each target in the jump table to the address of // an emitted MachineBasicBlock. intptr_t *SlotPtr = (intptr_t*)JumpTableBase; - + for (unsigned i = 0, e = JT.size(); i != e; ++i) { const std::vector &MBBs = JT[i].MBBs; // Store the address of the basic block for this jump table slot in the @@ -1153,7 +1156,7 @@ } break; } - + case MachineJumpTableInfo::EK_Custom32: case MachineJumpTableInfo::EK_GPRel32BlockAddress: case MachineJumpTableInfo::EK_LabelDifference32: { From geek4civic at gmail.com Tue Mar 15 20:39:41 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 10:39:41 +0900 Subject: [llvm-commits] [LLVMdev] Prevent unbounded memory consuption of long lived JIT processes In-Reply-To: <1300230955-24833-1-git-send-email-jfonseca@vmware.com> References: <1300230955-24833-1-git-send-email-jfonseca@vmware.com> Message-ID: Good morning Jose, Thank you to send patches. - Please send patches to llvm-commits. - Please make patches with "--attach". You may add "format.attach" to git config. I have not seen yours yet, but I pushed yours to github; https://github.com/chapuni/LLVM/compare/ed4edf9e...jfonseca%2F20110316 (Excuse me I could not input accent) ...Takumi On Wed, Mar 16, 2011 at 8:15 AM, wrote: > This series of patches address several issues causing memory usage to grow > indefinetely on a long lived process. > > These are not convenional leaks -- memory would have been freed when the LLVM > context or/and JIT engine is destroyed -- but for as long as they aren't the > memory is usage effectively ubounded. > > The issues were found using valgrind with '--show-reachable=yes' option: > 1. Compile a bunch of functions with JIT once; delete the result; and exit > ? without destroying LLVM context nor JIT engine. (valgrind will report a > ? bunch of unfreed LLVM objects) > 2. Do as 1, but compile and delete the functions twice > 3. Ditto three times. > 4. Etc. > > Flawless code should not cause the memory usage to increase when compiling the > same -- ie valgrind's log for every run should show the very same unfreed > objects, regardless of the number of times a given code was compilation, but > that was not the case. The attached patches cover most of the causes for new > objects being allocated. > > It should be possible to automate such test, but I didn't get that far. From geek4civic at gmail.com Tue Mar 15 21:53:24 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 02:53:24 -0000 Subject: [llvm-commits] [llvm] r127723 - /llvm/trunk/lib/Support/Windows/Path.inc Message-ID: <20110316025324.851C22A6C12C@llvm.org> Author: chapuni Date: Tue Mar 15 21:53:24 2011 New Revision: 127723 URL: http://llvm.org/viewvc/llvm-project?rev=127723&view=rev Log: Windows/Path.inc: [PR6270] PathV1::makeUnique(): Give arbitrary initial seed for workaround. FIXME: We should use sys::fs::unique_file() in future. Modified: llvm/trunk/lib/Support/Windows/Path.inc Modified: llvm/trunk/lib/Support/Windows/Path.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Path.inc?rev=127723&r1=127722&r2=127723&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/Path.inc (original) +++ llvm/trunk/lib/Support/Windows/Path.inc Tue Mar 15 21:53:24 2011 @@ -882,7 +882,17 @@ // Find a numeric suffix that isn't used by an existing file. Assume there // won't be more than 1 million files with the same prefix. Probably a safe // bet. - static unsigned FCounter = 0; + static int FCounter = -1; + if (FCounter < 0) { + // Give arbitrary initial seed. + // FIXME: We should use sys::fs::unique_file() in future. + LARGE_INTEGER cnt64; + DWORD x = GetCurrentProcessId(); + x = (x << 16) | (x >> 16); + if (QueryPerformanceCounter(&cnt64)) // RDTSC + x ^= cnt64.HighPart ^ cnt64.LowPart; + FCounter = x % 1000000; + } do { sprintf(FNBuffer+offset, "-%06u", FCounter); if (++FCounter > 999999) From geek4civic at gmail.com Tue Mar 15 21:53:32 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 02:53:32 -0000 Subject: [llvm-commits] [llvm] r127724 - /llvm/trunk/lib/Support/Windows/PathV2.inc Message-ID: <20110316025332.691012A6C12C@llvm.org> Author: chapuni Date: Tue Mar 15 21:53:32 2011 New Revision: 127724 URL: http://llvm.org/viewvc/llvm-project?rev=127724&view=rev Log: Windows/PathV2.inc: [PR8520] Recognize "NUL" as special (character) file. FIXME: It is a temporal hack. We should detect as many "special file name" as possible. Modified: llvm/trunk/lib/Support/Windows/PathV2.inc Modified: llvm/trunk/lib/Support/Windows/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=127724&r1=127723&r2=127724&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/PathV2.inc (original) +++ llvm/trunk/lib/Support/Windows/PathV2.inc Tue Mar 15 21:53:32 2011 @@ -449,7 +449,14 @@ SmallString<128> path_storage; SmallVector path_utf16; - if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage), + StringRef path8 = path.toStringRef(path_storage); + // FIXME: We should detect as many "special file name" as possible. + if (path8.compare_lower("nul") == 0) { + result = file_status(file_type::character_file); + return success; + } + + if (error_code ec = UTF8ToUTF16(path8, path_utf16)) return ec; From geek4civic at gmail.com Tue Mar 15 21:53:39 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 02:53:39 -0000 Subject: [llvm-commits] [llvm] r127726 - /llvm/trunk/lib/Support/raw_ostream.cpp Message-ID: <20110316025339.89DC12A6C12C@llvm.org> Author: chapuni Date: Tue Mar 15 21:53:39 2011 New Revision: 127726 URL: http://llvm.org/viewvc/llvm-project?rev=127726&view=rev Log: lib/Support/raw_ostream.cpp: On mingw, report_fatal_error() should not be called at dtor context. report_fatal_error() invokes exit(). We know report_fatal_error() might not write messages to stderr when any errors were detected on FD == 2. Modified: llvm/trunk/lib/Support/raw_ostream.cpp Modified: llvm/trunk/lib/Support/raw_ostream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/raw_ostream.cpp?rev=127726&r1=127725&r2=127726&view=diff ============================================================================== --- llvm/trunk/lib/Support/raw_ostream.cpp (original) +++ llvm/trunk/lib/Support/raw_ostream.cpp Tue Mar 15 21:53:39 2011 @@ -466,6 +466,14 @@ } } +#ifdef __MINGW32__ + // On mingw, global dtors should not call exit(). + // report_fatal_error() invokes exit(). We know report_fatal_error() + // might not write messages to stderr when any errors were detected + // on FD == 2. + if (FD == 2) return; +#endif + // If there are any pending errors, report them now. Clients wishing // to avoid report_fatal_error calls should check for errors with // has_error() and clear the error flag with clear_error() before From yuri at rawbw.com Tue Mar 15 23:44:22 2011 From: yuri at rawbw.com (Yuri) Date: Tue, 15 Mar 2011 21:44:22 -0700 Subject: [llvm-commits] [patch] Improvement of value printout in disassembler: adding value type Message-ID: <4D804026.1060007@rawbw.com> Please check this simple patch in. Thanks, Yuri -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: patch.txt Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110315/24504ca2/attachment.txt From baldrick at free.fr Wed Mar 16 03:08:01 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 16 Mar 2011 09:08:01 +0100 Subject: [llvm-commits] [llvm] r127714 - /llvm/trunk/include/llvm/Target/TargetData.h In-Reply-To: <20110316001328.F1CBB2A6C12E@llvm.org> References: <20110316001328.F1CBB2A6C12E@llvm.org> Message-ID: <4D806FE1.3050002@free.fr> Hi Cameron, > + bool fitsInLegalInteger(unsigned Width) const { > + for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) > + if (Width<= LegalIntWidths[i]) > + return true; if LegalIntWidths is sorted then you only need to do one comparison here. Ciao, Duncan. > + return false; > + } > + > /// Target pointer alignment > unsigned getPointerABIAlignment() const { return PointerABIAlign; } > /// Return target's alignment for stack-based pointers > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Wed Mar 16 03:10:25 2011 From: baldrick at free.fr (Duncan Sands) Date: Wed, 16 Mar 2011 09:10:25 +0100 Subject: [llvm-commits] [llvm] r127718 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/only-memcpy-uses.ll In-Reply-To: <20110316001344.69BBD2A6C12F@llvm.org> References: <20110316001344.69BBD2A6C12F@llvm.org> Message-ID: <4D807071.8010605@free.fr> Hi Cameron, > @@ -238,10 +238,15 @@ > /// also declared as a vector, we do want to promote to a vector. > bool HadAVector; > > + /// HadAVector - True if there is at least one access to the alloca that is HadAVector -> HadNonMemTransferAccess Ciao, Duncan. From zwarich at apple.com Wed Mar 16 03:14:10 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 01:14:10 -0700 Subject: [llvm-commits] [llvm] r127714 - /llvm/trunk/include/llvm/Target/TargetData.h In-Reply-To: <4D806FE1.3050002@free.fr> References: <20110316001328.F1CBB2A6C12E@llvm.org> <4D806FE1.3050002@free.fr> Message-ID: On 2011-03-16, at 1:08 AM, Duncan Sands wrote: > Hi Cameron, > >> + bool fitsInLegalInteger(unsigned Width) const { >> + for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) >> + if (Width<= LegalIntWidths[i]) >> + return true; > > if LegalIntWidths is sorted then you only need to do one comparison here. It isn't sorted, but maybe it makes sense to sort it and do that. Cameron From zwarich at apple.com Wed Mar 16 03:13:42 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 08:13:42 -0000 Subject: [llvm-commits] [llvm] r127728 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <20110316081342.E64672A6C12D@llvm.org> Author: zwarich Date: Wed Mar 16 03:13:42 2011 New Revision: 127728 URL: http://llvm.org/viewvc/llvm-project?rev=127728&view=rev Log: Fix a comment. Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=127728&r1=127727&r2=127728&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed Mar 16 03:13:42 2011 @@ -238,9 +238,9 @@ /// also declared as a vector, we do want to promote to a vector. bool HadAVector; - /// HadAVector - True if there is at least one access to the alloca that is - /// not a MemTransferInst. We don't want to turn structs into large integers - /// unless there is some potential for optimization. + /// HadNonMemTransferAccess - True if there is at least one access to the + /// alloca that is not a MemTransferInst. We don't want to turn structs into + /// large integers unless there is some potential for optimization. bool HadNonMemTransferAccess; public: From geek4civic at gmail.com Wed Mar 16 06:50:28 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 20:50:28 +0900 Subject: [llvm-commits] [PATCH] test/CodeGen/X86/constant-pool-remat-0.ll: Tweak to force all XMMs spilled, to let rematerialized on Win64. Message-ID: Win64cc preserves some caller's XMMs. Then rematerialization would not be expected. --- test/CodeGen/X86/constant-pool-remat-0.ll | 21 ++++++++++++++++----- 1 files changed, 16 insertions(+), 5 deletions(-) --- I wonder this tweak, ... I could suppress Win64 if this were overkill. ...Takumi -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-test-CodeGen-X86-constant-pool-remat-0.ll-Tweak-.patch.txt Type: text/x-patch Size: 1534 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110316/b9226e79/attachment.bin From geek4civic at gmail.com Wed Mar 16 08:47:15 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 22:47:15 +0900 Subject: [llvm-commits] [llvm] r127351 - in /llvm/trunk: lib/CodeGen/SimpleRegisterCoalescing.cpp test/CodeGen/X86/2011-03-09-Physreg-Coalescing.ll test/CodeGen/X86/fold-pcmpeqd-2.ll In-Reply-To: <20110309192706.B181C2A6C12D@llvm.org> References: <20110309192706.B181C2A6C12D@llvm.org> Message-ID: Hi Jakob, > Author: stoklund > Date: Wed Mar ?9 13:27:06 2011 > New Revision: 127351 > > URL: http://llvm.org/viewvc/llvm-project?rev=127351&view=rev > Log: > Make physreg coalescing independent on the number of uses of the virtual register. > > The damage done by physreg coalescing only depends on the number of instructions > the extended physreg live range covers. This fixes PR9438. > > The heuristic is still luck-based, and physreg coalescing really should be > disabled completely. We need a register allocator with better hinting support > before that is possible. > > Convert a test to FileCheck and force spilling by inserting an extra call. The > previous spilling behavior was dependent on misguided physreg coalescing > decisions. With r127351, X86/h-registers-1.ll is emitted differently on -mtriple=x86_64-win32. Is it expected or possible? llc -mtriple=x86_64-win32 < ~/llvm/test/CodeGen/X86/h-registers-1.ll \ | grep 'movzbl.%[abcd]h' \ | wc -l ; w/o r127351 movzbl %ah, %esi movzbl %ah, %eax movzbl %ah, %edi movzbl %bh, %ebx movzbl %dh, %edx movzbl %ah, %ebp movzbl %ch, %eax movzbl %ch, %ecx ; with r127351; movzbl %ah, %eax movzbl %ah, %eax movzbl %ah, %ecx movzbl %bh, %eax movzbl %dh, %edx movzbl %bh, %esi movzbl 15(%rsp), %edi # 1-byte Folded Reload movzbl %bh, %ebx ...Takumi ps. I've got lv3 earthquake just now :/ From geek4civic at gmail.com Wed Mar 16 08:52:08 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 13:52:08 -0000 Subject: [llvm-commits] [llvm] r127730 - /llvm/trunk/test/CodeGen/X86/dyn-stackalloc.ll Message-ID: <20110316135208.B089C2A6C12C@llvm.org> Author: chapuni Date: Wed Mar 16 08:52:08 2011 New Revision: 127730 URL: http://llvm.org/viewvc/llvm-project?rev=127730&view=rev Log: test/CodeGen/X86/dyn-stackalloc.ll: FileCheck-ize. Modified: llvm/trunk/test/CodeGen/X86/dyn-stackalloc.ll Modified: llvm/trunk/test/CodeGen/X86/dyn-stackalloc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dyn-stackalloc.ll?rev=127730&r1=127729&r2=127730&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/dyn-stackalloc.ll (original) +++ llvm/trunk/test/CodeGen/X86/dyn-stackalloc.ll Wed Mar 16 08:52:08 2011 @@ -1,6 +1,9 @@ -; RUN: llc < %s -mtriple=i686-linux | not egrep {\\\$4294967289|-7} -; RUN: llc < %s -mtriple=i686-linux | egrep {\\\$4294967280|-16} -; RUN: llc < %s -mtriple=x86_64-linux | grep {\\-16} +; RUN: llc < %s -mtriple=i686-linux | FileCheck %s -check-prefix=X32 +; X32-NOT: {{$429496728|-7}} +; X32: {{$4294967280|-16}} +; X32-NOT: {{$429496728|-7}} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X64 +; X64: -16 define void @t() nounwind { A: From geek4civic at gmail.com Wed Mar 16 08:52:20 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 13:52:20 -0000 Subject: [llvm-commits] [llvm] r127731 - in /llvm/trunk/test/CodeGen/X86: byval.ll byval2.ll byval3.ll byval4.ll byval5.ll Message-ID: <20110316135220.58BCA2A6C12C@llvm.org> Author: chapuni Date: Wed Mar 16 08:52:20 2011 New Revision: 127731 URL: http://llvm.org/viewvc/llvm-project?rev=127731&view=rev Log: test/CodeGen/X86/byval*.ll: Win64 has not supported byval yet. Modified: llvm/trunk/test/CodeGen/X86/byval.ll llvm/trunk/test/CodeGen/X86/byval2.ll llvm/trunk/test/CodeGen/X86/byval3.ll llvm/trunk/test/CodeGen/X86/byval4.ll llvm/trunk/test/CodeGen/X86/byval5.ll Modified: llvm/trunk/test/CodeGen/X86/byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/byval.ll?rev=127731&r1=127730&r2=127731&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/byval.ll (original) +++ llvm/trunk/test/CodeGen/X86/byval.ll Wed Mar 16 08:52:20 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 | FileCheck -check-prefix=X86-64 %s +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck -check-prefix=X86-64 %s +; Win64 has not supported byval yet. ; RUN: llc < %s -march=x86 | FileCheck -check-prefix=X86 %s ; X86: movl 4(%esp), %eax Modified: llvm/trunk/test/CodeGen/X86/byval2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/byval2.ll?rev=127731&r1=127730&r2=127731&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/byval2.ll (original) +++ llvm/trunk/test/CodeGen/X86/byval2.ll Wed Mar 16 08:52:20 2011 @@ -1,5 +1,28 @@ -; RUN: llc < %s -march=x86-64 | grep rep.movsq | count 2 -; RUN: llc < %s -march=x86 | grep rep.movsl | count 2 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X64 +; X64-NOT: movsq +; X64: rep +; X64-NOT: rep +; X64: movsq +; X64-NOT: movsq +; X64: rep +; X64-NOT: rep +; X64: movsq +; X64-NOT: rep +; X64-NOT: movsq + +; Win64 has not supported byval yet. + +; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32 +; X32-NOT: movsl +; X32: rep +; X32-NOT: rep +; X32: movsl +; X32-NOT: movsl +; X32: rep +; X32-NOT: rep +; X32: movsl +; X32-NOT: rep +; X32-NOT: movsl %struct.s = type { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, Modified: llvm/trunk/test/CodeGen/X86/byval3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/byval3.ll?rev=127731&r1=127730&r2=127731&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/byval3.ll (original) +++ llvm/trunk/test/CodeGen/X86/byval3.ll Wed Mar 16 08:52:20 2011 @@ -1,5 +1,28 @@ -; RUN: llc < %s -march=x86-64 | grep rep.movsq | count 2 -; RUN: llc < %s -march=x86 | grep rep.movsl | count 2 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X64 +; X64-NOT: movsq +; X64: rep +; X64-NOT: rep +; X64: movsq +; X64-NOT: movsq +; X64: rep +; X64-NOT: rep +; X64: movsq +; X64-NOT: rep +; X64-NOT: movsq + +; Win64 has not supported byval yet. + +; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32 +; X32-NOT: movsl +; X32: rep +; X32-NOT: rep +; X32: movsl +; X32-NOT: movsl +; X32: rep +; X32-NOT: rep +; X32: movsl +; X32-NOT: rep +; X32-NOT: movsl %struct.s = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, Modified: llvm/trunk/test/CodeGen/X86/byval4.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/byval4.ll?rev=127731&r1=127730&r2=127731&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/byval4.ll (original) +++ llvm/trunk/test/CodeGen/X86/byval4.ll Wed Mar 16 08:52:20 2011 @@ -1,5 +1,28 @@ -; RUN: llc < %s -march=x86-64 | grep rep.movsq | count 2 -; RUN: llc < %s -march=x86 | grep rep.movsl | count 2 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X64 +; X64-NOT: movsq +; X64: rep +; X64-NOT: rep +; X64: movsq +; X64-NOT: movsq +; X64: rep +; X64-NOT: rep +; X64: movsq +; X64-NOT: rep +; X64-NOT: movsq + +; Win64 has not supported byval yet. + +; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32 +; X32-NOT: movsl +; X32: rep +; X32-NOT: rep +; X32: movsl +; X32-NOT: movsl +; X32: rep +; X32-NOT: rep +; X32: movsl +; X32-NOT: rep +; X32-NOT: movsl %struct.s = type { i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, Modified: llvm/trunk/test/CodeGen/X86/byval5.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/byval5.ll?rev=127731&r1=127730&r2=127731&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/byval5.ll (original) +++ llvm/trunk/test/CodeGen/X86/byval5.ll Wed Mar 16 08:52:20 2011 @@ -1,5 +1,28 @@ -; RUN: llc < %s -march=x86-64 | grep rep.movsq | count 2 -; RUN: llc < %s -march=x86 | grep rep.movsl | count 2 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X64 +; X64-NOT: movsq +; X64: rep +; X64-NOT: rep +; X64: movsq +; X64-NOT: movsq +; X64: rep +; X64-NOT: rep +; X64: movsq +; X64-NOT: rep +; X64-NOT: movsq + +; Win64 has not supported byval yet. + +; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32 +; X32-NOT: movsl +; X32: rep +; X32-NOT: rep +; X32: movsl +; X32-NOT: movsl +; X32: rep +; X32-NOT: rep +; X32: movsl +; X32-NOT: rep +; X32-NOT: movsl %struct.s = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, From geek4civic at gmail.com Wed Mar 16 08:52:38 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 13:52:38 -0000 Subject: [llvm-commits] [llvm] r127732 - in /llvm/trunk/test/CodeGen/X86: coalescer-commute2.ll fold-mul-lohi.ll scalar-min-max-fill-operand.ll sse-align-0.ll sse-align-3.ll sse-align-7.ll sse-commute.ll sse_reload_fold.ll stdarg.ll stride-nine-with-base-reg.ll stride-reuse.ll tailcallbyval64.ll Message-ID: <20110316135238.7A3612A6C12C@llvm.org> Author: chapuni Date: Wed Mar 16 08:52:38 2011 New Revision: 127732 URL: http://llvm.org/viewvc/llvm-project?rev=127732&view=rev Log: test/CodeGen/X86: FileCheck-ize and add explicit -mtriple=x86_64-linux. They are useless to Win64 target. Modified: llvm/trunk/test/CodeGen/X86/coalescer-commute2.ll llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll llvm/trunk/test/CodeGen/X86/scalar-min-max-fill-operand.ll llvm/trunk/test/CodeGen/X86/sse-align-0.ll llvm/trunk/test/CodeGen/X86/sse-align-3.ll llvm/trunk/test/CodeGen/X86/sse-align-7.ll llvm/trunk/test/CodeGen/X86/sse-commute.ll llvm/trunk/test/CodeGen/X86/sse_reload_fold.ll llvm/trunk/test/CodeGen/X86/stdarg.ll llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll llvm/trunk/test/CodeGen/X86/stride-reuse.ll llvm/trunk/test/CodeGen/X86/tailcallbyval64.ll Modified: llvm/trunk/test/CodeGen/X86/coalescer-commute2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/coalescer-commute2.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/coalescer-commute2.ll (original) +++ llvm/trunk/test/CodeGen/X86/coalescer-commute2.ll Wed Mar 16 08:52:38 2011 @@ -1,5 +1,10 @@ -; RUN: llc < %s -march=x86-64 | grep paddw | count 2 -; RUN: llc < %s -march=x86-64 | not grep mov +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK-NOT: mov +; CHECK: paddw +; CHECK-NOT: mov +; CHECK: paddw +; CHECK-NOT: paddw +; CHECK-NOT: mov ; The 2-addr pass should ensure that identical code is produced for these functions ; no extra copy should be generated. Modified: llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll (original) +++ llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll Wed Mar 16 08:52:38 2011 @@ -1,5 +1,6 @@ -; RUN: llc < %s -march=x86 | not grep lea -; RUN: llc < %s -march=x86-64 | not grep lea +; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK-NOT: lea @B = external global [1000 x i8], align 32 @A = external global [1000 x i8], align 32 Modified: llvm/trunk/test/CodeGen/X86/scalar-min-max-fill-operand.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/scalar-min-max-fill-operand.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/scalar-min-max-fill-operand.ll (original) +++ llvm/trunk/test/CodeGen/X86/scalar-min-max-fill-operand.ll Wed Mar 16 08:52:38 2011 @@ -1,6 +1,13 @@ -; RUN: llc < %s -march=x86-64 | grep min | count 1 -; RUN: llc < %s -march=x86-64 | grep max | count 1 -; RUN: llc < %s -march=x86-64 | grep mov | count 2 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK-NOT: {{(min|max|mov)}} +; CHECK: mov +; CHECK-NOT: {{(min|max|mov)}} +; CHECK: min +; CHECK-NOT: {{(min|max|mov)}} +; CHECK: mov +; CHECK-NOT: {{(min|max|mov)}} +; CHECK: max +; CHECK-NOT: {{(min|max|mov)}} declare float @bar() Modified: llvm/trunk/test/CodeGen/X86/sse-align-0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse-align-0.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sse-align-0.ll (original) +++ llvm/trunk/test/CodeGen/X86/sse-align-0.ll Wed Mar 16 08:52:38 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 | not grep mov +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK-NOT: mov define <4 x float> @foo(<4 x float>* %p, <4 x float> %x) nounwind { %t = load <4 x float>* %p Modified: llvm/trunk/test/CodeGen/X86/sse-align-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse-align-3.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sse-align-3.ll (original) +++ llvm/trunk/test/CodeGen/X86/sse-align-3.ll Wed Mar 16 08:52:38 2011 @@ -1,4 +1,9 @@ -; RUN: llc < %s -march=x86-64 | grep movap | count 2 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK-NOT: movapd +; CHECK: movaps +; CHECK-NOT: movaps +; CHECK: movapd +; CHECK-NOT: movap define void @foo(<4 x float>* %p, <4 x float> %x) nounwind { store <4 x float> %x, <4 x float>* %p Modified: llvm/trunk/test/CodeGen/X86/sse-align-7.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse-align-7.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sse-align-7.ll (original) +++ llvm/trunk/test/CodeGen/X86/sse-align-7.ll Wed Mar 16 08:52:38 2011 @@ -1,4 +1,6 @@ -; RUN: llc < %s -march=x86-64 | grep movaps | count 1 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK: movaps +; CHECK-NOT: movaps define void @bar(<2 x i64>* %p, <2 x i64> %x) nounwind { store <2 x i64> %x, <2 x i64>* %p Modified: llvm/trunk/test/CodeGen/X86/sse-commute.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse-commute.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sse-commute.ll (original) +++ llvm/trunk/test/CodeGen/X86/sse-commute.ll Wed Mar 16 08:52:38 2011 @@ -1,4 +1,4 @@ -; RUN: llc -march=x86-64 < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s ; Commute the comparison to avoid a move. ; PR7500. Modified: llvm/trunk/test/CodeGen/X86/sse_reload_fold.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sse_reload_fold.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sse_reload_fold.ll (original) +++ llvm/trunk/test/CodeGen/X86/sse_reload_fold.ll Wed Mar 16 08:52:38 2011 @@ -1,5 +1,6 @@ -; RUN: llc < %s -march=x86-64 -mattr=+64bit,+sse3 -print-failed-fuse-candidates |& \ -; RUN: grep fail | count 1 +; RUN: llc < %s -mtriple=x86_64-linux -mattr=+64bit,+sse3 -print-failed-fuse-candidates |& FileCheck %s +; CHECK: fail +; CHECK-NOT: fail declare float @test_f(float %f) declare double @test_d(double %f) Modified: llvm/trunk/test/CodeGen/X86/stdarg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stdarg.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/stdarg.ll (original) +++ llvm/trunk/test/CodeGen/X86/stdarg.ll Wed Mar 16 08:52:38 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 | grep {testb \[%\]al, \[%\]al} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK: testb %al, %al %struct.__va_list_tag = type { i32, i32, i8*, i8* } Modified: llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll (original) +++ llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll Wed Mar 16 08:52:38 2011 @@ -1,5 +1,6 @@ -; RUN: llc < %s -march=x86 -relocation-model=static | not grep lea -; RUN: llc < %s -march=x86-64 | not grep lea +; RUN: llc < %s -march=x86 -relocation-model=static | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK-NOT: lea ; P should be sunk into the loop and folded into the address mode. There ; shouldn't be any lea instructions inside the loop. Modified: llvm/trunk/test/CodeGen/X86/stride-reuse.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stride-reuse.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/stride-reuse.ll (original) +++ llvm/trunk/test/CodeGen/X86/stride-reuse.ll Wed Mar 16 08:52:38 2011 @@ -1,5 +1,6 @@ -; RUN: llc < %s -march=x86 | not grep lea -; RUN: llc < %s -march=x86-64 | not grep lea +; RUN: llc < %s -march=x86 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; CHECK-NOT: lea @B = external global [1000 x float], align 32 @A = external global [1000 x float], align 32 Modified: llvm/trunk/test/CodeGen/X86/tailcallbyval64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallbyval64.ll?rev=127732&r1=127731&r2=127732&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcallbyval64.ll (original) +++ llvm/trunk/test/CodeGen/X86/tailcallbyval64.ll Wed Mar 16 08:52:38 2011 @@ -1,15 +1,30 @@ -; RUN: llc < %s -march=x86-64 -tailcallopt | grep TAILCALL +; RUN: llc < %s -mtriple=x86_64-linux -tailcallopt | FileCheck %s + +; FIXME: Win64 does not support byval. + +; Expect the entry point. +; CHECK: tailcaller: + ; Expect 2 rep;movs because of tail call byval lowering. -; RUN: llc < %s -march=x86-64 -tailcallopt | grep rep | wc -l | grep 2 +; CHECK: rep; +; CHECK: rep; + ; A sequence of copyto/copyfrom virtual registers is used to deal with byval ; lowering appearing after moving arguments to registers. The following two ; checks verify that the register allocator changes those sequences to direct ; moves to argument register where it can (for registers that are not used in ; byval lowering - not rsi, not rdi, not rcx). ; Expect argument 4 to be moved directly to register edx. -; RUN: llc < %s -march=x86-64 -tailcallopt | grep movl | grep {7} | grep edx +; CHECK: movl $7, %edx + ; Expect argument 6 to be moved directly to register r8. -; RUN: llc < %s -march=x86-64 -tailcallopt | grep movl | grep {17} | grep r8 +; CHECK: movl $17, %r8d + +; Expect not call but jmp to @tailcallee. +; CHECK: jmp tailcallee + +; Expect the trailer. +; CHECK: .size tailcaller %struct.s = type { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, @@ -25,5 +40,3 @@ %tmp4 = tail call fastcc i64 @tailcallee(%struct.s* %a byval, i64 %tmp3, i64 %b, i64 7, i64 13, i64 17) ret i64 %tmp4 } - - From geek4civic at gmail.com Wed Mar 16 08:52:51 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 13:52:51 -0000 Subject: [llvm-commits] [llvm] r127733 - in /llvm/trunk/test/CodeGen/X86: apm.ll h-register-store.ll h-registers-0.ll peep-vector-extract-concat.ll pmulld.ll v2f32.ll widen_load-0.ll Message-ID: <20110316135251.EF8F02A6C12C@llvm.org> Author: chapuni Date: Wed Mar 16 08:52:51 2011 New Revision: 127733 URL: http://llvm.org/viewvc/llvm-project?rev=127733&view=rev Log: test/CodeGen/X86: Add a pattern for Win64. Modified: llvm/trunk/test/CodeGen/X86/apm.ll llvm/trunk/test/CodeGen/X86/h-register-store.ll llvm/trunk/test/CodeGen/X86/h-registers-0.ll llvm/trunk/test/CodeGen/X86/peep-vector-extract-concat.ll llvm/trunk/test/CodeGen/X86/pmulld.ll llvm/trunk/test/CodeGen/X86/v2f32.ll llvm/trunk/test/CodeGen/X86/widen_load-0.ll Modified: llvm/trunk/test/CodeGen/X86/apm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/apm.ll?rev=127733&r1=127732&r2=127733&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/apm.ll (original) +++ llvm/trunk/test/CodeGen/X86/apm.ll Wed Mar 16 08:52:51 2011 @@ -1,10 +1,16 @@ -; RUN: llc < %s -o - -march=x86-64 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s -check-prefix=WIN64 ; PR8573 ; CHECK: foo: ; CHECK: leaq (%rdi), %rax ; CHECK-NEXT: movl %esi, %ecx ; CHECK-NEXT: monitor +; WIN64: foo: +; WIN64: leaq (%rcx), %rax +; WIN64-NEXT: movl %edx, %ecx +; WIN64-NEXT: movl %r8d, %edx +; WIN64-NEXT: monitor define void @foo(i8* %P, i32 %E, i32 %H) nounwind { entry: tail call void @llvm.x86.sse3.monitor(i8* %P, i32 %E, i32 %H) @@ -17,6 +23,9 @@ ; CHECK: movl %edi, %ecx ; CHECK-NEXT: movl %esi, %eax ; CHECK-NEXT: mwait +; WIN64: bar: +; WIN64: movl %edx, %eax +; WIN64-NEXT: mwait define void @bar(i32 %E, i32 %H) nounwind { entry: tail call void @llvm.x86.sse3.mwait(i32 %E, i32 %H) Modified: llvm/trunk/test/CodeGen/X86/h-register-store.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-register-store.ll?rev=127733&r1=127732&r2=127733&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-register-store.ll (original) +++ llvm/trunk/test/CodeGen/X86/h-register-store.ll Wed Mar 16 08:52:51 2011 @@ -1,9 +1,29 @@ -; RUN: llc < %s -march=x86-64 > %t -; RUN: grep mov %t | count 6 -; RUN: grep {movb %ah, (%rsi)} %t | count 3 -; RUN: llc < %s -march=x86 > %t -; RUN: grep mov %t | count 3 -; RUN: grep {movb %ah, (%e} %t | count 3 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X64 +; X64: mov +; X64-NEXT: movb %ah, (%rsi) +; X64: mov +; X64-NEXT: movb %ah, (%rsi) +; X64: mov +; X64-NEXT: movb %ah, (%rsi) +; X64-NOT: mov + +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s -check-prefix=W64 +; W64-NOT: mov +; W64: movb %ch, (%rdx) +; W64-NOT: mov +; W64: movb %ch, (%rdx) +; W64-NOT: mov +; W64: movb %ch, (%rdx) +; W64-NOT: mov + +; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32 +; X32-NOT: mov +; X32: movb %ah, (%e +; X32-NOT: mov +; X32: movb %ah, (%e +; X32-NOT: mov +; X32: movb %ah, (%e +; X32-NOT: mov ; Use h-register extract and store. Modified: llvm/trunk/test/CodeGen/X86/h-registers-0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers-0.ll?rev=127733&r1=127732&r2=127733&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-registers-0.ll (original) +++ llvm/trunk/test/CodeGen/X86/h-registers-0.ll Wed Mar 16 08:52:51 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=X86-64 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X86-64 +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s -check-prefix=WIN64 ; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X86-32 ; Use h registers. On x86-64, codegen doesn't support general allocation @@ -9,6 +10,12 @@ ; X86-64: shrq $8, %rdi ; X86-64: incb %dil +; See FIXME: on regclass GR8. +; It could be optimally transformed like; incb %ch; movb %ch, (%rdx) +; WIN64: bar64: +; WIN64: shrq $8, %rcx +; WIN64: incb %cl + ; X86-32: bar64: ; X86-32: incb %ah %t0 = lshr i64 %x, 8 @@ -23,6 +30,10 @@ ; X86-64: shrl $8, %edi ; X86-64: incb %dil +; WIN64: bar32: +; WIN64: shrl $8, %ecx +; WIN64: incb %cl + ; X86-32: bar32: ; X86-32: incb %ah %t0 = lshr i32 %x, 8 @@ -37,6 +48,10 @@ ; X86-64: shrl $8, %edi ; X86-64: incb %dil +; WIN64: bar16: +; WIN64: shrl $8, %ecx +; WIN64: incb %cl + ; X86-32: bar16: ; X86-32: incb %ah %t0 = lshr i16 %x, 8 @@ -51,6 +66,9 @@ ; X86-64: movq %rdi, %rax ; X86-64: movzbl %ah, %eax +; WIN64: qux64: +; WIN64: movzbl %ch, %eax + ; X86-32: qux64: ; X86-32: movzbl %ah, %eax %t0 = lshr i64 %x, 8 @@ -63,6 +81,9 @@ ; X86-64: movl %edi, %eax ; X86-64: movzbl %ah, %eax +; WIN64: qux32: +; WIN64: movzbl %ch, %eax + ; X86-32: qux32: ; X86-32: movzbl %ah, %eax %t0 = lshr i32 %x, 8 @@ -75,6 +96,9 @@ ; X86-64: movl %edi, %eax ; X86-64: movzbl %ah, %eax +; WIN64: qux16: +; WIN64: movzbl %ch, %eax + ; X86-32: qux16: ; X86-32: movzbl %ah, %eax %t0 = lshr i16 %x, 8 Modified: llvm/trunk/test/CodeGen/X86/peep-vector-extract-concat.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/peep-vector-extract-concat.ll?rev=127733&r1=127732&r2=127733&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/peep-vector-extract-concat.ll (original) +++ llvm/trunk/test/CodeGen/X86/peep-vector-extract-concat.ll Wed Mar 16 08:52:51 2011 @@ -1,4 +1,9 @@ -; RUN: llc < %s -march=x86-64 -mattr=+sse2,-sse41 | grep {pshufd \$3, %xmm0, %xmm0} +; RUN: llc < %s -mtriple=x86_64-linux -mattr=+sse2,-sse41 | FileCheck %s +; CHECK: pshufd $3, %xmm0, %xmm0 + +; RUN: llc < %s -mtriple=x86_64-win32 -mattr=+sse2,-sse41 | FileCheck %s -check-prefix=WIN64 +; %a is passed indirectly on Win64. +; WIN64: movss 12(%rcx), %xmm0 define float @foo(<8 x float> %a) nounwind { %c = extractelement <8 x float> %a, i32 3 Modified: llvm/trunk/test/CodeGen/X86/pmulld.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pmulld.ll?rev=127733&r1=127732&r2=127733&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/pmulld.ll (original) +++ llvm/trunk/test/CodeGen/X86/pmulld.ll Wed Mar 16 08:52:51 2011 @@ -1,8 +1,13 @@ -; RUN: llc < %s -march=x86-64 -mattr=+sse41 -asm-verbose=0 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux -mattr=+sse41 -asm-verbose=0 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 -mattr=+sse41 -asm-verbose=0 | FileCheck %s -check-prefix=WIN64 define <4 x i32> @test1(<4 x i32> %A, <4 x i32> %B) nounwind { ; CHECK: test1: ; CHECK-NEXT: pmulld + +; WIN64: test1: +; WIN64-NEXT: movdqa (%rcx), %xmm0 +; WIN64-NEXT: pmulld (%rdx), %xmm0 %C = mul <4 x i32> %A, %B ret <4 x i32> %C } @@ -10,6 +15,11 @@ define <4 x i32> @test1a(<4 x i32> %A, <4 x i32> *%Bp) nounwind { ; CHECK: test1a: ; CHECK-NEXT: pmulld + +; WIN64: test1a: +; WIN64-NEXT: movdqa (%rcx), %xmm0 +; WIN64-NEXT: pmulld (%rdx), %xmm0 + %B = load <4 x i32>* %Bp %C = mul <4 x i32> %A, %B ret <4 x i32> %C Modified: llvm/trunk/test/CodeGen/X86/v2f32.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/v2f32.ll?rev=127733&r1=127732&r2=127733&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/v2f32.ll (original) +++ llvm/trunk/test/CodeGen/X86/v2f32.ll Wed Mar 16 08:52:51 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 -mcpu=penryn -asm-verbose=0 -o - | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-linux -mcpu=penryn -asm-verbose=0 -o - | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-win32 -mcpu=penryn -asm-verbose=0 -o - | FileCheck %s -check-prefix=W64 ; RUN: llc < %s -mcpu=yonah -march=x86 -asm-verbose=0 -o - | FileCheck %s -check-prefix=X32 ; PR7518 @@ -15,6 +16,13 @@ ; X64-NEXT: movss %xmm1, (%rdi) ; X64-NEXT: ret +; W64: test1: +; W64-NEXT: movdqa (%rcx), %xmm0 +; W64-NEXT: pshufd $1, %xmm0, %xmm1 +; W64-NEXT: addss %xmm0, %xmm1 +; W64-NEXT: movss %xmm1, (%rdx) +; W64-NEXT: ret + ; X32: test1: ; X32-NEXT: pshufd $1, %xmm0, %xmm1 ; X32-NEXT: addss %xmm0, %xmm1 @@ -31,6 +39,14 @@ ; X64: test2: ; X64-NEXT: addps %xmm1, %xmm0 ; X64-NEXT: ret + +; W64: test2: +; W64-NEXT: movaps (%rcx), %xmm0 +; W64-NEXT: addps (%rdx), %xmm0 +; W64-NEXT: ret + +; X32: test2: +; X32: addps %xmm1, %xmm0 } @@ -38,17 +54,35 @@ %B = shufflevector <4 x float> %A, <4 x float> undef, <2 x i32> %C = fadd <2 x float> %B, %B ret <2 x float> %C -; CHECK: test3: -; CHECK-NEXT: addps %xmm0, %xmm0 -; CHECK-NEXT: ret +; X64: test3: +; X64-NEXT: addps %xmm0, %xmm0 +; X64-NEXT: ret + +; W64: test3: +; W64-NEXT: movaps (%rcx), %xmm0 +; W64-NEXT: addps %xmm0, %xmm0 +; W64-NEXT: ret + +; X32: test3: +; X32-NEXT: addps %xmm0, %xmm0 +; X32-NEXT: ret } define <2 x float> @test4(<2 x float> %A) nounwind { %C = fadd <2 x float> %A, %A ret <2 x float> %C -; CHECK: test4: -; CHECK-NEXT: addps %xmm0, %xmm0 -; CHECK-NEXT: ret +; X64: test4: +; X64-NEXT: addps %xmm0, %xmm0 +; X64-NEXT: ret + +; W64: test4: +; W64-NEXT: movaps (%rcx), %xmm0 +; W64-NEXT: addps %xmm0, %xmm0 +; W64-NEXT: ret + +; X32: test4: +; X32-NEXT: addps %xmm0, %xmm0 +; X32-NEXT: ret } define <4 x float> @test5(<4 x float> %A) nounwind { @@ -61,10 +95,21 @@ %E = shufflevector <2 x float> %D, <2 x float> undef, <4 x i32> ret <4 x float> %E -; CHECK: _test5: -; CHECK-NEXT: addps %xmm0, %xmm0 -; CHECK-NEXT: addps %xmm0, %xmm0 -; CHECK-NEXT: ret +; X64: test5: +; X64-NEXT: addps %xmm0, %xmm0 +; X64-NEXT: addps %xmm0, %xmm0 +; X64-NEXT: ret + +; W64: test5: +; W64-NEXT: movaps (%rcx), %xmm0 +; W64-NEXT: addps %xmm0, %xmm0 +; W64-NEXT: addps %xmm0, %xmm0 +; W64-NEXT: ret + +; X32: test5: +; X32-NEXT: addps %xmm0, %xmm0 +; X32-NEXT: addps %xmm0, %xmm0 +; X32-NEXT: ret } Modified: llvm/trunk/test/CodeGen/X86/widen_load-0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/widen_load-0.ll?rev=127733&r1=127732&r2=127733&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/widen_load-0.ll (original) +++ llvm/trunk/test/CodeGen/X86/widen_load-0.ll Wed Mar 16 08:52:51 2011 @@ -1,4 +1,5 @@ -; RUN: llc < %s -o - -march=x86-64 | FileCheck %s +; RUN: llc < %s -o - -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -o - -mtriple=x86_64-win32 | FileCheck %s -check-prefix=WIN64 ; PR4891 ; Both loads should happen before either store. @@ -8,6 +9,11 @@ ; CHECK: movl %ecx, (%rdi) ; CHECK: movl %eax, (%rsi) +; WIN64: movl (%rcx), %eax +; WIN64: movl (%rdx), %esi +; WIN64: movl %esi, (%rcx) +; WIN64: movl %eax, (%rdx) + define void @short2_int_swap(<2 x i16>* nocapture %b, i32* nocapture %c) nounwind { entry: %0 = load <2 x i16>* %b, align 2 ; <<2 x i16>> [#uses=1] From geek4civic at gmail.com Wed Mar 16 08:53:08 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 13:53:08 -0000 Subject: [llvm-commits] [llvm] r127734 - in /llvm/trunk/test/CodeGen/X86: 2007-01-08-X86-64-Pointer.ll 2007-07-18-Vector-Extract.ll avoid-lea-scale2.ll convert-2-addr-3-addr-inc64.ll i64-mem-copy.ll lea-3.ll mmx-copy-gprs.ll vec_set-8.ll vec_shuffle-17.ll x86-64-malloc.ll Message-ID: <20110316135308.3865B2A6C12C@llvm.org> Author: chapuni Date: Wed Mar 16 08:53:07 2011 New Revision: 127734 URL: http://llvm.org/viewvc/llvm-project?rev=127734&view=rev Log: test/CodeGen/X86: FileCheck-ize and add actions for x86_64-linux and x86_64-win32. Modified: llvm/trunk/test/CodeGen/X86/2007-01-08-X86-64-Pointer.ll llvm/trunk/test/CodeGen/X86/2007-07-18-Vector-Extract.ll llvm/trunk/test/CodeGen/X86/avoid-lea-scale2.ll llvm/trunk/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll llvm/trunk/test/CodeGen/X86/i64-mem-copy.ll llvm/trunk/test/CodeGen/X86/lea-3.ll llvm/trunk/test/CodeGen/X86/mmx-copy-gprs.ll llvm/trunk/test/CodeGen/X86/vec_set-8.ll llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll llvm/trunk/test/CodeGen/X86/x86-64-malloc.ll Modified: llvm/trunk/test/CodeGen/X86/2007-01-08-X86-64-Pointer.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-01-08-X86-64-Pointer.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-01-08-X86-64-Pointer.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-01-08-X86-64-Pointer.ll Wed Mar 16 08:53:07 2011 @@ -1,5 +1,8 @@ -; RUN: llc %s -o - -march=x86-64 | grep {(%rdi,%rax,8)} -; RUN: llc %s -o - -march=x86-64 | not grep {addq.*8} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s +; CHECK-NOT: {{addq.*8}} +; CHECK: ({{%rdi|%rcx}},%rax,8) +; CHECK-NOT: {{addq.*8}} define void @foo(double* %y) nounwind { entry: Modified: llvm/trunk/test/CodeGen/X86/2007-07-18-Vector-Extract.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-07-18-Vector-Extract.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-07-18-Vector-Extract.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-07-18-Vector-Extract.ll Wed Mar 16 08:53:07 2011 @@ -1,5 +1,7 @@ -; RUN: llc < %s -march=x86-64 -mattr=+sse | grep {movq (%rdi), %rax} -; RUN: llc < %s -march=x86-64 -mattr=+sse | grep {movq 8(%rdi), %rax} +; RUN: llc < %s -mtriple=x86_64-linux -mattr=+sse | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 -mattr=+sse | FileCheck %s +; CHECK: movq ([[A0:%rdi|%rcx]]), %rax +; CHECK: movq 8([[A0]]), %rax define i64 @foo_0(<2 x i64>* %val) { entry: %val12 = getelementptr <2 x i64>* %val, i32 0, i32 0 ; [#uses=1] Modified: llvm/trunk/test/CodeGen/X86/avoid-lea-scale2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avoid-lea-scale2.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/avoid-lea-scale2.ll (original) +++ llvm/trunk/test/CodeGen/X86/avoid-lea-scale2.ll Wed Mar 16 08:53:07 2011 @@ -1,4 +1,6 @@ -; RUN: llc < %s -march=x86-64 | grep {leal.*-2(\[%\]rdi,\[%\]rdi)} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s +; CHECK: leal -2({{%rdi,%rdi|%rcx,%rcx}}) define i32 @foo(i32 %x) nounwind readnone { %t0 = shl i32 %x, 1 Modified: llvm/trunk/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll (original) +++ llvm/trunk/test/CodeGen/X86/convert-2-addr-3-addr-inc64.ll Wed Mar 16 08:53:07 2011 @@ -1,6 +1,10 @@ -; RUN: llc < %s -march=x86-64 -o %t -stats -info-output-file - | \ -; RUN: grep {asm-printer} | grep {Number of machine instrs printed} | grep 9 -; RUN: grep {leal 1(\%rsi),} %t +; RUN: llc < %s -mtriple=x86_64-linux -o /dev/null -stats |& FileCheck %s -check-prefix=STATS +; RUN: llc < %s -mtriple=x86_64-win32 -o /dev/null -stats |& FileCheck %s -check-prefix=STATS +; STATS: 9 asm-printer + +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s +; CHECK: leal 1({{%rsi|%rdx}}), define fastcc zeroext i8 @fullGtU(i32 %i1, i32 %i2, i8* %ptr) nounwind optsize { entry: Modified: llvm/trunk/test/CodeGen/X86/i64-mem-copy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/i64-mem-copy.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/i64-mem-copy.ll (original) +++ llvm/trunk/test/CodeGen/X86/i64-mem-copy.ll Wed Mar 16 08:53:07 2011 @@ -1,5 +1,9 @@ -; RUN: llc < %s -march=x86-64 | grep {movq.*(%rsi), %rax} -; RUN: llc < %s -march=x86 -mattr=+sse2 | grep {movsd.*(%eax),} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s -check-prefix=X64 +; X64: movq ({{%rsi|%rdx}}), %r + +; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s -check-prefix=X32 +; X32: movsd (%eax), %xmm ; Uses movsd to load / store i64 values if sse2 is available. Modified: llvm/trunk/test/CodeGen/X86/lea-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lea-3.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/lea-3.ll (original) +++ llvm/trunk/test/CodeGen/X86/lea-3.ll Wed Mar 16 08:53:07 2011 @@ -1,16 +1,19 @@ -; RUN: llc < %s -march=x86-64 | grep {leal (%rdi,%rdi,2), %eax} -define i32 @test(i32 %a) { - %tmp2 = mul i32 %a, 3 ; [#uses=1] - ret i32 %tmp2 -} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s -; RUN: llc < %s -march=x86-64 | grep {leaq (,%rdi,4), %rax} +; CHECK: leaq (,[[A0:%rdi|%rcx]],4), %rax define i64 @test2(i64 %a) { %tmp2 = shl i64 %a, 2 %tmp3 = or i64 %tmp2, %a ret i64 %tmp3 } +; CHECK: leal ([[A0]],[[A0]],2), %eax +define i32 @test(i32 %a) { + %tmp2 = mul i32 %a, 3 ; [#uses=1] + ret i32 %tmp2 +} + ;; TODO! LEA instead of shift + copy. define i64 @test3(i64 %a) { %tmp2 = shl i64 %a, 3 Modified: llvm/trunk/test/CodeGen/X86/mmx-copy-gprs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mmx-copy-gprs.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/mmx-copy-gprs.ll (original) +++ llvm/trunk/test/CodeGen/X86/mmx-copy-gprs.ll Wed Mar 16 08:53:07 2011 @@ -1,6 +1,10 @@ -; RUN: llc < %s -march=x86-64 | grep {movq.*(%rsi), %rax} -; RUN: llc < %s -march=x86 -mattr=-sse2 | grep {movl.*4(%eax),} -; RUN: llc < %s -march=x86 -mattr=+sse2 | grep {movsd.(%eax),} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s -check-prefix=X64 +; X64: movq ({{%rsi|%rdx}}), %rax +; RUN: llc < %s -march=x86 -mattr=-sse2 | FileCheck %s -check-prefix=X32 +; X32: movl 4(%eax), +; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s -check-prefix=XMM +; XMM: movsd (%eax), ; This test should use GPRs to copy the mmx value, not MMX regs. Using mmx regs, ; increases the places that need to use emms. Modified: llvm/trunk/test/CodeGen/X86/vec_set-8.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_set-8.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_set-8.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_set-8.ll Wed Mar 16 08:53:07 2011 @@ -1,5 +1,8 @@ -; RUN: llc < %s -march=x86-64 | not grep movsd -; RUN: llc < %s -march=x86-64 | grep {movd.*%rdi,.*%xmm0} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s +; CHECK-NOT: movsd +; CHECK: movd {{%rdi|%rcx}}, %xmm0 +; CHECK-NOT: movsd define <2 x i64> @test(i64 %i) nounwind { entry: Modified: llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll (original) +++ llvm/trunk/test/CodeGen/X86/vec_shuffle-17.ll Wed Mar 16 08:53:07 2011 @@ -1,5 +1,8 @@ -; RUN: llc < %s -march=x86-64 | grep {movd.*%rdi, %xmm0} -; RUN: llc < %s -march=x86-64 | not grep xor +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s +; CHECK-NOT: xor +; CHECK: movd {{%rdi|%rcx}}, %xmm0 +; CHECK-NOT: xor ; PR2108 define <2 x i64> @doload64(i64 %x) nounwind { Modified: llvm/trunk/test/CodeGen/X86/x86-64-malloc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/x86-64-malloc.ll?rev=127734&r1=127733&r2=127734&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/x86-64-malloc.ll (original) +++ llvm/trunk/test/CodeGen/X86/x86-64-malloc.ll Wed Mar 16 08:53:07 2011 @@ -1,4 +1,6 @@ -; RUN: llc < %s -march=x86-64 | grep {shll.*3, %edi} +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s +; CHECK: shll $3, {{%edi|%ecx}} ; PR3829 ; The generated code should multiply by 3 (sizeof i8*) as an i32, ; not as an i64! From jfonseca at vmware.com Wed Mar 16 08:23:34 2011 From: jfonseca at vmware.com (=?ISO-8859-1?Q?Jos=E9?= Fonseca) Date: Wed, 16 Mar 2011 13:23:34 +0000 Subject: [llvm-commits] [LLVMdev] Prevent unbounded memory consuption of long lived JIT processes In-Reply-To: References: <1300230955-24833-1-git-send-email-jfonseca@vmware.com> Message-ID: <1300281814.27102.311.camel@jfonseca-laptop.eng.vmware.com> On Tue, 2011-03-15 at 18:39 -0700, NAKAMURA Takumi wrote: > Good morning Jose, > > Thank you to send patches. > > - Please send patches to llvm-commits. > - Please make patches with "--attach". You may add "format.attach" > to git config. Will do, thanks. > I have not seen yours yet, but I pushed yours to github; > https://github.com/chapuni/LLVM/compare/ed4edf9e...jfonseca%2F20110316 > (Excuse me I could not input accent) > > ...Takumi Nice. I haven't used github yet, but I'll try using it going forward. Jose > > On Wed, Mar 16, 2011 at 8:15 AM, wrote: > > This series of patches address several issues causing memory usage to grow > > indefinetely on a long lived process. > > > > These are not convenional leaks -- memory would have been freed when the LLVM > > context or/and JIT engine is destroyed -- but for as long as they aren't the > > memory is usage effectively ubounded. > > > > The issues were found using valgrind with '--show-reachable=yes' option: > > 1. Compile a bunch of functions with JIT once; delete the result; and exit > > without destroying LLVM context nor JIT engine. (valgrind will report a > > bunch of unfreed LLVM objects) > > 2. Do as 1, but compile and delete the functions twice > > 3. Ditto three times. > > 4. Etc. > > > > Flawless code should not cause the memory usage to increase when compiling the > > same -- ie valgrind's log for every run should show the very same unfreed > > objects, regardless of the number of times a given code was compilation, but > > that was not the case. The attached patches cover most of the causes for new > > objects being allocated. > > > > It should be possible to automate such test, but I didn't get that far. From nadav.rotem at intel.com Wed Mar 16 10:37:13 2011 From: nadav.rotem at intel.com (Rotem, Nadav) Date: Wed, 16 Mar 2011 17:37:13 +0200 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors Message-ID: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> Hi, I attached a patch for legalizing UINT_TO_FP of vectors on platforms which do not have this operation (such as X86). The legalized code uses the vector INT_TO_FP operations and is faster than scalarizing. Nadav --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110316/6cc30acd/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: ui2fp.diff Type: application/octet-stream Size: 4371 bytes Desc: ui2fp.diff Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110316/6cc30acd/attachment.obj From stoklund at 2pi.dk Wed Mar 16 12:19:07 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 16 Mar 2011 10:19:07 -0700 Subject: [llvm-commits] [llvm] r127351 - in /llvm/trunk: lib/CodeGen/SimpleRegisterCoalescing.cpp test/CodeGen/X86/2011-03-09-Physreg-Coalescing.ll test/CodeGen/X86/fold-pcmpeqd-2.ll In-Reply-To: References: <20110309192706.B181C2A6C12D@llvm.org> Message-ID: On Mar 16, 2011, at 6:47 AM, NAKAMURA Takumi wrote: >> Author: stoklund >> Date: Wed Mar 9 13:27:06 2011 >> New Revision: 127351 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127351&view=rev >> Log: >> Make physreg coalescing independent on the number of uses of the virtual register. > > With r127351, X86/h-registers-1.ll is emitted differently on > -mtriple=x86_64-win32. > Is it expected or possible? Yes, it is possible because the win32 calling convention uses different registers for the incoming arguments. Physreg coalescing would extend the range of incoming physregs into the body of the function. That is actually a really bad idea in this function where the ABCD register classes are in use. > llc -mtriple=x86_64-win32 < ~/llvm/test/CodeGen/X86/h-registers-1.ll \ > | grep 'movzbl.%[abcd]h' \ > | wc -l > > ; w/o r127351 > movzbl %ah, %esi > movzbl %ah, %eax > movzbl %ah, %edi > movzbl %bh, %ebx > movzbl %dh, %edx > movzbl %ah, %ebp > movzbl %ch, %eax > movzbl %ch, %ecx > > ; with r127351; > movzbl %ah, %eax > movzbl %ah, %eax > movzbl %ah, %ecx > movzbl %bh, %eax > movzbl %dh, %edx > movzbl %bh, %esi > movzbl 15(%rsp), %edi # 1-byte Folded Reload > movzbl %bh, %ebx In this case, the change caused a different register to be spilled, and the reload was folded into one of the movzbl instructions. We can add an -mtriple argument to the test to make sure the calling convention doesn't change. The test isn't trying to test register allocation or spilling anyway. /jakob From dpatel at apple.com Wed Mar 16 12:46:51 2011 From: dpatel at apple.com (Devang Patel) Date: Wed, 16 Mar 2011 10:46:51 -0700 Subject: [llvm-commits] Debug Relocation Patch In-Reply-To: <4D7F9E20.70203@arm.com> References: <4D7E5C2E.1000803@gmail.com> <4D7E7064.5060101@gmail.com> <4D7F9E20.70203@arm.com> Message-ID: Renato, On Mar 15, 2011, at 10:13 AM, Renato Golin wrote: > On 14/03/11 19:45, Rafael Avila de Espindola wrote: >> We might need a virtual method or similar. Devang, for testing on linux >> I normally use a current version of the gdb testsuite. I assume that for >> darwin it is better to use an older one. Which testsuite do you normally >> use? > > Hi all, > > I've just compiled LLVM on an old Mac box (9.1.0, 2007) and compiled the > same example in the test case and everything (symbols, stepping, > debugging experience) was ok. All tests, including my new one, pass. > > I don't know how to dump mach-o objects nor how to check for the > relocation sections, though. Somebody with more experience in Mach-o > should take a look. We had a bug in older assembler, which we still support, where it could not handle constructs like, .long (Ltmp5-Ltmp4)-4 This required use of .set However in this case we emitting reference to label directly without doing any arithmetic so it should be OK. If all testings looks OK, please go ahead and commit. If someone complains from our side, I'll let you know! - Devang -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110316/4774bde9/attachment.html From stoklund at 2pi.dk Wed Mar 16 13:26:09 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 16 Mar 2011 11:26:09 -0700 Subject: [llvm-commits] [PATCH] test/CodeGen/X86/constant-pool-remat-0.ll: Tweak to force all XMMs spilled, to let rematerialized on Win64. In-Reply-To: References: Message-ID: On Mar 16, 2011, at 4:50 AM, NAKAMURA Takumi wrote: > Win64cc preserves some caller's XMMs. Then rematerialization would not > be expected. > --- > test/CodeGen/X86/constant-pool-remat-0.ll | 21 ++++++++++++++++----- > 1 files changed, 16 insertions(+), 5 deletions(-) > --- > > I wonder this tweak, ... I could suppress Win64 if this were overkill. That's a neat trick, but I don't think it is necessary. The test is checking that the register allocator can fold constant pool loads instead of spilling an xmm register. That is not necessary on windows, so you can just force the triple to linux or darwin. /jakob From richard at xmos.com Wed Mar 16 13:34:00 2011 From: richard at xmos.com (Richard Osborne) Date: Wed, 16 Mar 2011 18:34:00 -0000 Subject: [llvm-commits] [llvm] r127741 - in /llvm/trunk: include/llvm/IntrinsicsXCore.td lib/Target/XCore/XCoreISelDAGToDAG.cpp lib/Target/XCore/XCoreInstrInfo.td test/CodeGen/XCore/events.ll Message-ID: <20110316183400.D0E472A6C12C@llvm.org> Author: friedgold Date: Wed Mar 16 13:34:00 2011 New Revision: 127741 URL: http://llvm.org/viewvc/llvm-project?rev=127741&view=rev Log: Add checkevent intrinsic to check if any resources owned by the current thread can event. Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td llvm/trunk/test/CodeGen/XCore/events.ll Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsXCore.td?rev=127741&r1=127740&r2=127741&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsXCore.td (original) +++ llvm/trunk/include/llvm/IntrinsicsXCore.td Wed Mar 16 13:34:00 2011 @@ -56,5 +56,11 @@ // Intrinsics for events. def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>; + + // If any of the resources owned by the thread are ready this returns the + // vector of one of the ready resources. If no resources owned by the thread + // are ready then the operand passed to the intrinsic is returned. + def int_xcore_checkevent : Intrinsic<[llvm_ptr_ty],[llvm_ptr_ty]>; + def int_xcore_clre : Intrinsic<[],[],[]>; } Modified: llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp?rev=127741&r1=127740&r2=127741&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreISelDAGToDAG.cpp Wed Mar 16 13:34:00 2011 @@ -49,7 +49,8 @@ Subtarget(*TM.getSubtargetImpl()) { } SDNode *Select(SDNode *N); - + SDNode *SelectBRIND(SDNode *N); + /// getI32Imm - Return a target constant with the specified value, of type /// i32. inline SDValue getI32Imm(unsigned Imm) { @@ -154,62 +155,133 @@ SDNode *XCoreDAGToDAGISel::Select(SDNode *N) { DebugLoc dl = N->getDebugLoc(); - EVT NVT = N->getValueType(0); - if (NVT == MVT::i32) { - switch (N->getOpcode()) { - default: break; - case ISD::Constant: { - uint64_t Val = cast(N)->getZExtValue(); - if (immMskBitp(N)) { - // Transformation function: get the size of a mask - // Look for the first non-zero bit - SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(Val)); - return CurDAG->getMachineNode(XCore::MKMSK_rus, dl, - MVT::i32, MskSize); - } - else if (!isUInt<16>(Val)) { - SDValue CPIdx = - CurDAG->getTargetConstantPool(ConstantInt::get( - Type::getInt32Ty(*CurDAG->getContext()), Val), - TLI.getPointerTy()); - return CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32, - MVT::Other, CPIdx, - CurDAG->getEntryNode()); - } - break; - } - case XCoreISD::LADD: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2) }; - return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32, - Ops, 3); - } - case XCoreISD::LSUB: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2) }; - return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32, - Ops, 3); - } - case XCoreISD::MACCU: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2), N->getOperand(3) }; - return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32, - Ops, 4); - } - case XCoreISD::MACCS: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2), N->getOperand(3) }; - return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32, - Ops, 4); - } - case XCoreISD::LMUL: { - SDValue Ops[] = { N->getOperand(0), N->getOperand(1), - N->getOperand(2), N->getOperand(3) }; - return CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32, - Ops, 4); - } - // Other cases are autogenerated. - } + switch (N->getOpcode()) { + default: break; + case ISD::Constant: { + uint64_t Val = cast(N)->getZExtValue(); + if (immMskBitp(N)) { + // Transformation function: get the size of a mask + // Look for the first non-zero bit + SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(Val)); + return CurDAG->getMachineNode(XCore::MKMSK_rus, dl, + MVT::i32, MskSize); + } + else if (!isUInt<16>(Val)) { + SDValue CPIdx = + CurDAG->getTargetConstantPool(ConstantInt::get( + Type::getInt32Ty(*CurDAG->getContext()), Val), + TLI.getPointerTy()); + return CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32, + MVT::Other, CPIdx, + CurDAG->getEntryNode()); + } + break; + } + case XCoreISD::LADD: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2) }; + return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32, + Ops, 3); + } + case XCoreISD::LSUB: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2) }; + return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32, + Ops, 3); + } + case XCoreISD::MACCU: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2), N->getOperand(3) }; + return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32, + Ops, 4); + } + case XCoreISD::MACCS: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2), N->getOperand(3) }; + return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32, + Ops, 4); + } + case XCoreISD::LMUL: { + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2), N->getOperand(3) }; + return CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32, + Ops, 4); + } + case ISD::BRIND: + if (SDNode *ResNode = SelectBRIND(N)) + return ResNode; + break; + // Other cases are autogenerated. } return SelectCode(N); } + +/// Given a chain return a new chain where any appearance of Old is replaced +/// by New. There must be at most one instruction between Old and Chain and +/// this instruction must be a TokenFactor. Returns an empty SDValue if +/// these conditions don't hold. +static SDValue +replaceInChain(SelectionDAG *CurDAG, SDValue Chain, SDValue Old, SDValue New) +{ + if (Chain == Old) + return New; + if (Chain->getOpcode() != ISD::TokenFactor) + return SDValue(); + SmallVector Ops; + bool found = false; + for (unsigned i = 0, e = Chain->getNumOperands(); i != e; ++i) { + if (Chain->getOperand(i) == Old) { + Ops.push_back(New); + found = true; + } else { + Ops.push_back(Chain->getOperand(i)); + } + } + if (!found) + return SDValue(); + return CurDAG->getNode(ISD::TokenFactor, Chain->getDebugLoc(), MVT::Other, + &Ops[0], Ops.size()); +} + +SDNode *XCoreDAGToDAGISel::SelectBRIND(SDNode *N) { + DebugLoc dl = N->getDebugLoc(); + // (brind (int_xcore_checkevent (addr))) + SDValue Chain = N->getOperand(0); + SDValue Addr = N->getOperand(1); + if (Addr->getOpcode() != ISD::INTRINSIC_W_CHAIN) + return 0; + unsigned IntNo = cast(Addr->getOperand(1))->getZExtValue(); + if (IntNo != Intrinsic::xcore_checkevent) + return 0; + SDValue nextAddr = Addr->getOperand(2); + SDValue CheckEventChainOut(Addr.getNode(), 1); + if (!CheckEventChainOut.use_empty()) { + // If the chain out of the checkevent intrinsic is an operand of the + // indirect branch or used in a TokenFactor which is the operand of the + // indirect branch then build a new chain which uses the chain coming into + // the checkevent intrinsic instead. + SDValue CheckEventChainIn = Addr->getOperand(0); + SDValue NewChain = replaceInChain(CurDAG, Chain, CheckEventChainOut, + CheckEventChainIn); + if (!NewChain.getNode()) + return 0; + Chain = NewChain; + } + // Enable events on the thread using setsr 1 and then disable them immediately + // after with clrsr 1. If any resources owned by the thread are ready an event + // will be taken. If no resource is ready we branch to the address which was + // the operand to the checkevent intrinsic. + SDValue constOne = getI32Imm(1); + SDValue Glue = + SDValue(CurDAG->getMachineNode(XCore::SETSR_branch_u6, dl, MVT::Glue, + constOne, Chain), 0); + Glue = + SDValue(CurDAG->getMachineNode(XCore::CLRSR_branch_u6, dl, MVT::Glue, + constOne, Glue), 0); + if (nextAddr->getOpcode() == XCoreISD::PCRelativeWrapper && + nextAddr->getOperand(0)->getOpcode() == ISD::TargetBlockAddress) { + return CurDAG->SelectNodeTo(N, XCore::BRFU_lu6, MVT::Other, + nextAddr->getOperand(0), Glue); + } + return CurDAG->SelectNodeTo(N, XCore::BAU_1r, MVT::Other, nextAddr, Glue); +} Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=127741&r1=127740&r2=127741&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Wed Mar 16 13:34:00 2011 @@ -692,6 +692,13 @@ defm CLRSR : FU6_LU6_int<"clrsr", int_xcore_clrsr>; +// setsr may cause a branch if it is used to enable events. clrsr may +// branch if it is executed while events are enabled. +let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in { +defm SETSR_branch : FU6_LU6_np<"setsr">; +defm CLRSR_branch : FU6_LU6_np<"clrsr">; +} + // U10 // TODO ldwcpl, blacp Modified: llvm/trunk/test/CodeGen/XCore/events.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/events.ll?rev=127741&r1=127740&r2=127741&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/events.ll (original) +++ llvm/trunk/test/CodeGen/XCore/events.ll Wed Mar 16 13:34:00 2011 @@ -2,6 +2,7 @@ declare void @llvm.xcore.setv.p1i8(i8 addrspace(1)* %r, i8* %p) declare i8* @llvm.xcore.waitevent() +declare i8* @llvm.xcore.checkevent(i8*) declare void @llvm.xcore.clre() define i32 @f(i8 addrspace(1)* %r) nounwind { @@ -22,3 +23,22 @@ %retval = phi i32 [1, %L1], [2, %L2] ret i32 %retval } + +define i32 @g(i8 addrspace(1)* %r) nounwind { +; CHECK: g: +entry: +; CHECK: clre + call void @llvm.xcore.clre() + call void @llvm.xcore.setv.p1i8(i8 addrspace(1)* %r, i8* blockaddress(@f, %L1)) + %goto_addr = call i8* @llvm.xcore.checkevent(i8 *blockaddress(@f, %L2)) +; CHECK: setsr 1 +; CHECK: clrsr 1 + indirectbr i8* %goto_addr, [label %L1, label %L2] +L1: + br label %ret +L2: + br label %ret +ret: + %retval = phi i32 [1, %L1], [2, %L2] + ret i32 %retval +} From benny.kra at googlemail.com Wed Mar 16 14:32:56 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 16 Mar 2011 20:32:56 +0100 Subject: [llvm-commits] [llvm] r127673 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp In-Reply-To: <20110315073133.23F762A6C12D@llvm.org> References: <20110315073133.23F762A6C12D@llvm.org> Message-ID: <9202B122-660C-4307-953F-266BF2CA2125@googlemail.com> On 15.03.2011, at 08:31, Nick Lewycky wrote: > Author: nicholas > Date: Tue Mar 15 02:31:32 2011 > New Revision: 127673 > > URL: http://llvm.org/viewvc/llvm-project?rev=127673&view=rev > Log: > Add C++ global operator {new,new[],delete,delete[]}(unsigned {int,long}) to the > memory builtins as equivalent to malloc/free. > > This is different from any attribute we have. For example, you can delete the > allocators when their result is unused, but you can't collapse two calls to the > same function, even if no global/memory state has changed in between. The > noalias return states that the result does not alias any other pointer, but > instcombine optimizes malloc() as though the result is non-null for the purpose > of eliminating unused pointers. > > > Modified: > llvm/trunk/lib/Analysis/MemoryBuiltins.cpp > > Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=127673&r1=127672&r2=127673&view=diff > ============================================================================== > --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) > +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Tue Mar 15 02:31:32 2011 > @@ -35,7 +35,11 @@ > return false; > > Function *Callee = CI->getCalledFunction(); > - if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "malloc") > + if (Callee == 0 || !Callee->isDeclaration()) > + return false; > + if (Callee->getName() != "malloc" && > + Callee->getName() != "_Znwj" && Callee->getName() != "_Znwm" && > + Callee->getName() != "_Znaj" && Callee->getName() != "_Znam") > return false; What about the nothrow versions of operator new/delete? > // Check malloc prototype. > @@ -189,7 +193,12 @@ > if (!CI) > return 0; > Function *Callee = CI->getCalledFunction(); > - if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "free") > + if (Callee == 0 || !Callee->isDeclaration()) > + return 0; > + > + if (Callee->getName() != "free" && > + Callee->getName() != "_Zdlj" && Callee->getName() != "_Zdlm" && > + Callee->getName() != "_Zdaj" && Callee->getName() != "_Zdam") > return 0; The signature of operator delete is "operator delete(void*)" aka _ZdlPv, not "operator delete(int)". Comments with the demangled names would be helpful here. From zwarich at apple.com Wed Mar 16 15:15:44 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 20:15:44 -0000 Subject: [llvm-commits] [llvm] r127754 - /llvm/trunk/test/CodeGen/X86/bool-args-zext.ll Message-ID: <20110316201544.D2A722A6C12D@llvm.org> Author: zwarich Date: Wed Mar 16 15:15:44 2011 New Revision: 127754 URL: http://llvm.org/viewvc/llvm-project?rev=127754&view=rev Log: Add a test for i1 zeroext arguments on x86-64. We currently generate code that conforms to the ABI, but DAGCombine could in theory recognize the sequence of zext asserts and truncates and generate incorrect code. Added: llvm/trunk/test/CodeGen/X86/bool-args-zext.ll Added: llvm/trunk/test/CodeGen/X86/bool-args-zext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-args-zext.ll?rev=127754&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/bool-args-zext.ll (added) +++ llvm/trunk/test/CodeGen/X86/bool-args-zext.ll Wed Mar 16 15:15:44 2011 @@ -0,0 +1,23 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +; CHECK: @bar1 +; CHECK: movzbl +; CHECK: callq +define void @bar1(i1 zeroext %v1) nounwind ssp { +entry: + %conv = zext i1 %v1 to i32 + %call = tail call i32 (...)* @foo(i32 %conv) nounwind + ret void +} + +; CHECK: @bar2 +; CHECK-NOT: movzbl +; CHECK: callq +define void @bar2(i8 zeroext %v1) nounwind ssp { +entry: + %conv = zext i8 %v1 to i32 + %call = tail call i32 (...)* @foo(i32 %conv) nounwind + ret void +} + +declare i32 @foo(...) From steinke.dirk.ml at googlemail.com Wed Mar 16 16:00:49 2011 From: steinke.dirk.ml at googlemail.com (Dirk Steinke) Date: Wed, 16 Mar 2011 22:00:49 +0100 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors In-Reply-To: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> References: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> Message-ID: <4D812501.9020808@gmail.com> Hi Nadav, On 03/16/2011 04:37 PM, Rotem, Nadav wrote: > Hi, > > I attached a patch for legalizing UINT_TO_FP of vectors on platforms > which do not have this operation (such as X86). The legalized code uses > the vector INT_TO_FP operations and is faster than scalarizing. > [snip] > SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) { > + > + > + EVT VT = Op.getOperand(0).getValueType(); > + DebugLoc DL = Op.getDebugLoc(); > + > + // Make sure that the SINT_TO_FP and SRL instructions are available. > + if (!TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, VT) || > + !TLI.isOperationLegalOrCustom(ISD::SRL, VT)) > + return DAG.UnrollVectorOp(Op.getNode()); > + > + EVT SVT = VT.getScalarType(); > + assert((SVT.getSizeInBits() == 64 || SVT.getSizeInBits() == 32) && > + "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide"); > + > + unsigned BW = SVT.getSizeInBits(); > + SDValue HalfWord = DAG.getConstant(BW/2, VT); > + > + // Constants to clear the upper part of the word. > + // Notice that we can also use SHL+SHR, but using a constant is slightly > + // faster on x86. > + uint64_t HWMask = (SVT.getSizeInBits()==64)?0x00000000FFFFFFFF:0x0000FFFF; > + SDValue HalfWordMask = DAG.getConstant(HWMask, VT); > + > + // Two to the power of half-word-size. > + SDValue TWOHW = DAG.getConstantFP((1<<(BW/2)), Op.getValueType()); > + > + // Clear upper part of LO, lower HI > + SDValue HI = DAG.getNode(ISD::SRL, DL, VT, Op.getOperand(0), HalfWord); > + SDValue LO = DAG.getNode(ISD::AND, DL, VT, Op.getOperand(0), HalfWordMask); > + > + // Convert hi and lo to floats > + // Convert the hi part back to the upper values > + SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), HI); > + fHI = DAG.getNode(ISD::FMUL, DL, Op.getValueType(), fHI, TWOHW); > + SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), LO); > + > + // Add the two halves > + return DAG.getNode(ISD::FADD, DL, Op.getValueType(), fHI, fLO); > +} > + thanks for working on this, but your code seems suboptimal to me. If I'm not mistaken, you should be able to turn UINT_TO_FP(a) into SINT_TO_FP(a & ~SIGNBIT) - SINT_TO_FP(a & SIGNBIT) which gets rid of one floating point multiplication, and replaces one shift by an AND, but at the cost of one extra vector constant. In theory, using PANDN on x86, one memory load should be enough, but well... What do you think? Dirk From steinke.dirk.ml at googlemail.com Wed Mar 16 16:08:36 2011 From: steinke.dirk.ml at googlemail.com (Dirk Steinke) Date: Wed, 16 Mar 2011 22:08:36 +0100 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors In-Reply-To: <4D812501.9020808@gmail.com> References: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> <4D812501.9020808@gmail.com> Message-ID: <4D8126D4.2070307@gmail.com> On 03/16/2011 10:00 PM, Dirk Steinke wrote: > Hi Nadav, > > On 03/16/2011 04:37 PM, Rotem, Nadav wrote: >> Hi, >> >> I attached a patch for legalizing UINT_TO_FP of vectors on platforms >> which do not have this operation (such as X86). The legalized code uses >> the vector INT_TO_FP operations and is faster than scalarizing. >> > [snip] >> SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) { >> + >> + >> + EVT VT = Op.getOperand(0).getValueType(); >> + DebugLoc DL = Op.getDebugLoc(); >> + >> + // Make sure that the SINT_TO_FP and SRL instructions are available. >> + if (!TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, VT) || >> + !TLI.isOperationLegalOrCustom(ISD::SRL, VT)) >> + return DAG.UnrollVectorOp(Op.getNode()); >> + >> + EVT SVT = VT.getScalarType(); >> + assert((SVT.getSizeInBits() == 64 || SVT.getSizeInBits() == 32) && >> + "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide"); >> + >> + unsigned BW = SVT.getSizeInBits(); >> + SDValue HalfWord = DAG.getConstant(BW/2, VT); >> + >> + // Constants to clear the upper part of the word. >> + // Notice that we can also use SHL+SHR, but using a constant is >> slightly >> + // faster on x86. >> + uint64_t HWMask = >> (SVT.getSizeInBits()==64)?0x00000000FFFFFFFF:0x0000FFFF; >> + SDValue HalfWordMask = DAG.getConstant(HWMask, VT); >> + >> + // Two to the power of half-word-size. >> + SDValue TWOHW = DAG.getConstantFP((1<<(BW/2)), Op.getValueType()); >> + >> + // Clear upper part of LO, lower HI >> + SDValue HI = DAG.getNode(ISD::SRL, DL, VT, Op.getOperand(0), HalfWord); >> + SDValue LO = DAG.getNode(ISD::AND, DL, VT, Op.getOperand(0), >> HalfWordMask); >> + >> + // Convert hi and lo to floats >> + // Convert the hi part back to the upper values >> + SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), HI); >> + fHI = DAG.getNode(ISD::FMUL, DL, Op.getValueType(), fHI, TWOHW); >> + SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), LO); >> + >> + // Add the two halves >> + return DAG.getNode(ISD::FADD, DL, Op.getValueType(), fHI, fLO); >> +} >> + > > thanks for working on this, but your code seems suboptimal to me. If I'm > not mistaken, you should be able to turn > UINT_TO_FP(a) into SINT_TO_FP(a & ~SIGNBIT) - SINT_TO_FP(a & SIGNBIT) > which gets rid of one floating point multiplication, and replaces one > shift by an AND, but at the cost of one extra vector constant. In > theory, using PANDN on x86, one memory load should be enough, but > well... What do you think? > > Dirk Hi Nadav, now that I think about it, why not simply UINT_FP(a) = SINT_TO_FP(a - SIGNBIT) + FLOAT(SIGNBIT)? Dirk From renato.golin at arm.com Wed Mar 16 16:05:52 2011 From: renato.golin at arm.com (Renato Golin) Date: Wed, 16 Mar 2011 21:05:52 -0000 Subject: [llvm-commits] [llvm] r127757 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/CodeGen/ARM/dwarf-relocation.ll Message-ID: <20110316210552.3BA5F2A6C12C@llvm.org> Author: rengolin Date: Wed Mar 16 16:05:52 2011 New Revision: 127757 URL: http://llvm.org/viewvc/llvm-project?rev=127757&view=rev Log: Patch to a fix dwarf relocation problem on ARM. One-line fix plus the test where it used to break. Added: llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=127757&r1=127756&r2=127757&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Mar 16 16:05:52 2011 @@ -3272,7 +3272,9 @@ case dwarf::DW_AT_location: { if (UseDotDebugLocEntry.count(Die) != 0) { DIELabel *L = cast(Values[i]); - Asm->EmitLabelDifference(L->getValue(), DwarfDebugLocSectionSym, 4); + // Emitting reference to label directly, so the assembler can + // emit the relocations and the offset automatically. + Asm->EmitReference(L->getValue(), dwarf::DW_EH_PE_udata4); } else Values[i]->EmitValue(Asm, Form); break; @@ -3623,6 +3625,7 @@ if (DotDebugLocEntries.empty()) return; + // Group debug entries. for (SmallVector::iterator I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end(); I != E; ++I) { @@ -3631,7 +3634,7 @@ Entry.Merge(I+1); } - // Start the dwarf loc section. + // Start the dwarf location section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfLocSection()); unsigned char Size = Asm->getTargetData().getPointerSize(); Added: llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll?rev=127757&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll (added) +++ llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll Wed Mar 16 16:05:52 2011 @@ -0,0 +1,111 @@ +; RUN: llc -asm-verbose=true -O1 %s -o - | FileCheck %s + +; // The variable 'x' live on both R0 and R1, so they need an entry in .debug_loc table +; // For that, the DW_AT_location needs to have relocation to that section +; extern int g(int, int); +; extern int a; +; +; void f(void) { +; int x; +; a = g(0, 0); +; x = 1; +; while (x & 1) { x *= a; } +; a = g(x, 0); +; x = 2; +; while (x & 2) { x *= a; } +; a = g(0, x); +; } + +; // The 'x' variable and its symbol reference location +; CHECK: @ Abbrev [{{.*}}] 0x{{.*}}:0x{{.*}} DW_TAG_variable +; CHECK-NEXT: @ DW_AT_name +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: @ DW_AT_decl_file +; CHECK-NEXT: @ DW_AT_decl_line +; CHECK-NEXT: @ DW_AT_type +; CHECK-NEXT: .long .Ldebug_loc0 @ DW_AT_location +; CHECK-NEXT: .byte 0 @ End Of Children Mark + +; // The .debug_loc entry, with the two registers +; CHECK: .Ldebug_loc0: +; CHECK: .long .Ltmp{{.*}} +; CHECK: .long .Ltmp{{.*}} +; CHECK: .short 1 @ Loc expr size +; CHECK: .byte 80 @ DW_OP_reg0 +; CHECK: .long .Ltmp{{.*}} +; CHECK: .long .Lfunc_end0 +; CHECK: .short 1 @ Loc expr size +; CHECK: .byte 81 @ DW_OP_reg1 +; CHECK: .long 0 +; CHECK: .long 0 + + +; ModuleID = 'simple.c' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32" +target triple = "armv7-none--eabi" + + at a = external global i32 + +define void @f() nounwind { +entry: + %call = tail call i32 @g(i32 0, i32 0) nounwind, !dbg !8 + store i32 %call, i32* @a, align 4, !dbg !8, !tbaa !9 + tail call void @llvm.dbg.value(metadata !12, i64 0, metadata !5), !dbg !13 + br label %while.body + +while.body: ; preds = %entry, %while.body + %x.017 = phi i32 [ 1, %entry ], [ %mul, %while.body ] + %mul = mul nsw i32 %call, %x.017, !dbg !14 + %and = and i32 %mul, 1, !dbg !14 + %tobool = icmp eq i32 %and, 0, !dbg !14 + br i1 %tobool, label %while.end, label %while.body, !dbg !14 + +while.end: ; preds = %while.body + tail call void @llvm.dbg.value(metadata !{i32 %mul}, i64 0, metadata !5), !dbg !14 + %call4 = tail call i32 @g(i32 %mul, i32 0) nounwind, !dbg !15 + store i32 %call4, i32* @a, align 4, !dbg !15, !tbaa !9 + tail call void @llvm.dbg.value(metadata !16, i64 0, metadata !5), !dbg !17 + br label %while.body9 + +while.body9: ; preds = %while.end, %while.body9 + %x.116 = phi i32 [ 2, %while.end ], [ %mul12, %while.body9 ] + %mul12 = mul nsw i32 %call4, %x.116, !dbg !18 + %and7 = and i32 %mul12, 2, !dbg !18 + %tobool8 = icmp eq i32 %and7, 0, !dbg !18 + br i1 %tobool8, label %while.end13, label %while.body9, !dbg !18 + +while.end13: ; preds = %while.body9 + tail call void @llvm.dbg.value(metadata !{i32 %mul12}, i64 0, metadata !5), !dbg !18 + %call15 = tail call i32 @g(i32 0, i32 %mul12) nounwind, !dbg !19 + store i32 %call15, i32* @a, align 4, !dbg !19, !tbaa !9 + ret void, !dbg !20 +} + +declare i32 @g(i32, i32) + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.sp = !{!0} +!llvm.dbg.lv.f = !{!5} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"f", metadata !"f", metadata !"", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void ()* @f} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"simple.c", metadata !"/home/rengol01/temp/tests/dwarf/relocation", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"simple.c", metadata !"/home/rengol01/temp/tests/dwarf/relocation", metadata !"clang version 3.0 (trunk)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null} +!5 = metadata !{i32 590080, metadata !6, metadata !"x", metadata !1, i32 5, metadata !7, i32 0} ; [ DW_TAG_auto_variable ] +!6 = metadata !{i32 589835, metadata !0, i32 4, i32 14, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!7 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!8 = metadata !{i32 6, i32 3, metadata !6, null} +!9 = metadata !{metadata !"int", metadata !10} +!10 = metadata !{metadata !"omnipotent char", metadata !11} +!11 = metadata !{metadata !"Simple C/C++ TBAA", null} +!12 = metadata !{i32 1} +!13 = metadata !{i32 7, i32 3, metadata !6, null} +!14 = metadata !{i32 8, i32 3, metadata !6, null} +!15 = metadata !{i32 9, i32 3, metadata !6, null} +!16 = metadata !{i32 2} +!17 = metadata !{i32 10, i32 3, metadata !6, null} +!18 = metadata !{i32 11, i32 3, metadata !6, null} +!19 = metadata !{i32 12, i32 3, metadata !6, null} +!20 = metadata !{i32 13, i32 1, metadata !6, null} From scanon at apple.com Wed Mar 16 16:29:10 2011 From: scanon at apple.com (Stephen Canon) Date: Wed, 16 Mar 2011 14:29:10 -0700 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors In-Reply-To: <4D812501.9020808@gmail.com> References: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> <4D812501.9020808@gmail.com> Message-ID: <1BC27846-E3EC-4EDA-AB97-D25D902C5C4C@apple.com> > thanks for working on this, but your code seems suboptimal to me. If I'm > not mistaken, you should be able to turn > UINT_TO_FP(a) into SINT_TO_FP(a & ~SIGNBIT) - SINT_TO_FP(a & SIGNBIT) > which gets rid of one floating point multiplication, and replaces one > shift by an AND, but at the cost of one extra vector constant. In > theory, using PANDN on x86, one memory load should be enough, but > well... What do you think? You are mistaken. You cannot implement uint -> fp as you describe, as it introduces a double-rounding for certain values. There are many, but here is one example to illustrate the problem 0x81000081. It is one greater than an exact halfway case for rounding to single-precision, but the result when using the algorithm you describe is rounded *down* instead of up with default IEEE-754 rounding. - Steve From richard at xmos.com Wed Mar 16 16:56:00 2011 From: richard at xmos.com (Richard Osborne) Date: Wed, 16 Mar 2011 21:56:00 -0000 Subject: [llvm-commits] [llvm] r127761 - in /llvm/trunk: include/llvm/IntrinsicsXCore.td lib/Target/XCore/XCoreInstrInfo.td test/CodeGen/XCore/resources.ll Message-ID: <20110316215600.77CDD2A6C12C@llvm.org> Author: friedgold Date: Wed Mar 16 16:56:00 2011 New Revision: 127761 URL: http://llvm.org/viewvc/llvm-project?rev=127761&view=rev Log: Add XCore intrinsics for setclk, setrdy. Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td llvm/trunk/test/CodeGen/XCore/resources.ll Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsXCore.td?rev=127761&r1=127760&r2=127761&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsXCore.td (original) +++ llvm/trunk/include/llvm/IntrinsicsXCore.td Wed Mar 16 16:56:00 2011 @@ -53,6 +53,10 @@ def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty], [NoCapture<0>]>; def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>; + def int_xcore_setclk : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty], + [NoCapture<0>, NoCapture<1>]>; + def int_xcore_setrdy : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty], + [NoCapture<0>, NoCapture<1>]>; // Intrinsics for events. def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>; Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=127761&r1=127760&r2=127761&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Wed Mar 16 16:56:00 2011 @@ -838,7 +838,7 @@ [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>; // Two operand long -// TODO setclk, setrdy, setpsc, endin, peek, +// TODO setpsc, endin, peek, // getd, testlcl, tinitlr def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), "bitrev $dst, $src", @@ -868,6 +868,14 @@ "set ps[$src1], $src2", [(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>; +def SETCLK_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), + "setclk res[$src1], $src2", + [(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>; + +def SETRDY_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), + "setrdy res[$src1], $src2", + [(int_xcore_setrdy GRRegs:$src1, GRRegs:$src2)]>; + // One operand short // TODO edu, eeu, waitet, waitef, tstart, msync, mjoin, clrtp // setdp, setcp, setev, kcall Modified: llvm/trunk/test/CodeGen/XCore/resources.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/resources.ll?rev=127761&r1=127760&r2=127761&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/resources.ll (original) +++ llvm/trunk/test/CodeGen/XCore/resources.ll Wed Mar 16 16:56:00 2011 @@ -19,6 +19,8 @@ declare void @llvm.xcore.settw.p1i8(i8 addrspace(1)* %r, i32 %value) declare void @llvm.xcore.setv.p1i8(i8 addrspace(1)* %r, i8* %p) declare void @llvm.xcore.eeu.p1i8(i8 addrspace(1)* %r) +declare void @llvm.xcore.setclk.p1i8.p1i8(i8 addrspace(1)* %a, i8 addrspace(1)* %b) +declare void @llvm.xcore.setrdy.p1i8.p1i8(i8 addrspace(1)* %a, i8 addrspace(1)* %b) define i8 addrspace(1)* @getr() { ; CHECK: getr: @@ -174,3 +176,17 @@ call void @llvm.xcore.eeu.p1i8(i8 addrspace(1)* %r) ret void } + +define void @setclk(i8 addrspace(1)* %a, i8 addrspace(1)* %b) { +; CHECK: setclk +; CHECK: setclk res[r0], r1 + call void @llvm.xcore.setclk.p1i8.p1i8(i8 addrspace(1)* %a, i8 addrspace(1)* %b) + ret void +} + +define void @setrdy(i8 addrspace(1)* %a, i8 addrspace(1)* %b) { +; CHECK: setrdy +; CHECK: setrdy res[r0], r1 + call void @llvm.xcore.setrdy.p1i8.p1i8(i8 addrspace(1)* %a, i8 addrspace(1)* %b) + ret void +} From daniel at zuster.org Wed Mar 16 17:17:59 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 16 Mar 2011 15:17:59 -0700 Subject: [llvm-commits] [llvm] r127757 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/CodeGen/ARM/dwarf-relocation.ll In-Reply-To: <20110316210552.3BA5F2A6C12C@llvm.org> References: <20110316210552.3BA5F2A6C12C@llvm.org> Message-ID: Hi Renato, This broke a Debug+Asserts self-host build of Clang, at least on Darwin, I'm reverting it for now. Can you take a look? Thanks, - Daniel On Wed, Mar 16, 2011 at 2:05 PM, Renato Golin wrote: > Author: rengolin > Date: Wed Mar 16 16:05:52 2011 > New Revision: 127757 > > URL: http://llvm.org/viewvc/llvm-project?rev=127757&view=rev > Log: > Patch to a fix dwarf relocation problem on ARM. One-line fix plus the test where it used to break. > > Added: > ? ?llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll > Modified: > ? ?llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=127757&r1=127756&r2=127757&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Mar 16 16:05:52 2011 > @@ -3272,7 +3272,9 @@ > ? ? case dwarf::DW_AT_location: { > ? ? ? if (UseDotDebugLocEntry.count(Die) != 0) { > ? ? ? ? DIELabel *L = cast(Values[i]); > - ? ? ? ?Asm->EmitLabelDifference(L->getValue(), DwarfDebugLocSectionSym, 4); > + ? ? ? ?// Emitting reference to label directly, so the assembler can > + ? ? ? ?// emit the relocations and the offset automatically. > + ? ? ? ?Asm->EmitReference(L->getValue(), dwarf::DW_EH_PE_udata4); > ? ? ? } else > ? ? ? ? Values[i]->EmitValue(Asm, Form); > ? ? ? break; > @@ -3623,6 +3625,7 @@ > ? if (DotDebugLocEntries.empty()) > ? ? return; > > + ?// Group debug entries. > ? for (SmallVector::iterator > ? ? ? ? ?I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end(); > ? ? ? ?I != E; ++I) { > @@ -3631,7 +3634,7 @@ > ? ? ? Entry.Merge(I+1); > ? } > > - ?// Start the dwarf loc section. > + ?// Start the dwarf location section. > ? Asm->OutStreamer.SwitchSection( > ? ? Asm->getObjFileLowering().getDwarfLocSection()); > ? unsigned char Size = Asm->getTargetData().getPointerSize(); > > Added: llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll?rev=127757&view=auto > ============================================================================== > --- llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll (added) > +++ llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll Wed Mar 16 16:05:52 2011 > @@ -0,0 +1,111 @@ > +; RUN: llc -asm-verbose=true -O1 %s -o - | FileCheck %s > + > +; // The variable 'x' live on both R0 and R1, so they need an entry in .debug_loc table > +; // For that, the DW_AT_location needs to have relocation to that section > +; extern int g(int, int); > +; extern int a; > +; > +; void f(void) { > +; ? int x; > +; ? a = g(0, 0); > +; ? x = 1; > +; ? while (x & 1) { x *= a; } > +; ? a = g(x, 0); > +; ? x = 2; > +; ? while (x & 2) { x *= a; } > +; ? a = g(0, x); > +; } > + > +; // The 'x' variable and its symbol reference location > +; CHECK: @ Abbrev [{{.*}}] 0x{{.*}}:0x{{.*}} DW_TAG_variable > +; CHECK-NEXT: @ DW_AT_name > +; CHECK-NEXT: .byte 0 > +; CHECK-NEXT: @ DW_AT_decl_file > +; CHECK-NEXT: @ DW_AT_decl_line > +; CHECK-NEXT: @ DW_AT_type > +; CHECK-NEXT: .long .Ldebug_loc0 ? ? ? ? ? ?@ DW_AT_location > +; CHECK-NEXT: .byte 0 ? ? ? ? ? ? ? ? ? ? ? @ End Of Children Mark > + > +; // The .debug_loc entry, with the two registers > +; CHECK: .Ldebug_loc0: > +; CHECK: ?.long .Ltmp{{.*}} > +; CHECK: ?.long .Ltmp{{.*}} > +; CHECK: ?.short 1 ? ? ? ? ? ? ? ? ? ? @ Loc expr size > +; CHECK: ?.byte 80 ? ? ? ? ? ? ? ? ? ? ?@ DW_OP_reg0 > +; CHECK: ?.long .Ltmp{{.*}} > +; CHECK: ?.long .Lfunc_end0 > +; CHECK: ?.short 1 ? ? ? ? ? ? ? ? ? ? @ Loc expr size > +; CHECK: ?.byte 81 ? ? ? ? ? ? ? ? ? ? ?@ DW_OP_reg1 > +; CHECK: ?.long 0 > +; CHECK: ?.long 0 > + > + > +; ModuleID = 'simple.c' > +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32" > +target triple = "armv7-none--eabi" > + > + at a = external global i32 > + > +define void @f() nounwind { > +entry: > + ?%call = tail call i32 @g(i32 0, i32 0) nounwind, !dbg !8 > + ?store i32 %call, i32* @a, align 4, !dbg !8, !tbaa !9 > + ?tail call void @llvm.dbg.value(metadata !12, i64 0, metadata !5), !dbg !13 > + ?br label %while.body > + > +while.body: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ; preds = %entry, %while.body > + ?%x.017 = phi i32 [ 1, %entry ], [ %mul, %while.body ] > + ?%mul = mul nsw i32 %call, %x.017, !dbg !14 > + ?%and = and i32 %mul, 1, !dbg !14 > + ?%tobool = icmp eq i32 %and, 0, !dbg !14 > + ?br i1 %tobool, label %while.end, label %while.body, !dbg !14 > + > +while.end: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; preds = %while.body > + ?tail call void @llvm.dbg.value(metadata !{i32 %mul}, i64 0, metadata !5), !dbg !14 > + ?%call4 = tail call i32 @g(i32 %mul, i32 0) nounwind, !dbg !15 > + ?store i32 %call4, i32* @a, align 4, !dbg !15, !tbaa !9 > + ?tail call void @llvm.dbg.value(metadata !16, i64 0, metadata !5), !dbg !17 > + ?br label %while.body9 > + > +while.body9: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; preds = %while.end, %while.body9 > + ?%x.116 = phi i32 [ 2, %while.end ], [ %mul12, %while.body9 ] > + ?%mul12 = mul nsw i32 %call4, %x.116, !dbg !18 > + ?%and7 = and i32 %mul12, 2, !dbg !18 > + ?%tobool8 = icmp eq i32 %and7, 0, !dbg !18 > + ?br i1 %tobool8, label %while.end13, label %while.body9, !dbg !18 > + > +while.end13: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; preds = %while.body9 > + ?tail call void @llvm.dbg.value(metadata !{i32 %mul12}, i64 0, metadata !5), !dbg !18 > + ?%call15 = tail call i32 @g(i32 0, i32 %mul12) nounwind, !dbg !19 > + ?store i32 %call15, i32* @a, align 4, !dbg !19, !tbaa !9 > + ?ret void, !dbg !20 > +} > + > +declare i32 @g(i32, i32) > + > +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone > + > +!llvm.dbg.sp = !{!0} > +!llvm.dbg.lv.f = !{!5} > + > +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"f", metadata !"f", metadata !"", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void ()* @f} ; [ DW_TAG_subprogram ] > +!1 = metadata !{i32 589865, metadata !"simple.c", metadata !"/home/rengol01/temp/tests/dwarf/relocation", metadata !2} ; [ DW_TAG_file_type ] > +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"simple.c", metadata !"/home/rengol01/temp/tests/dwarf/relocation", metadata !"clang version 3.0 (trunk)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] > +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] > +!4 = metadata !{null} > +!5 = metadata !{i32 590080, metadata !6, metadata !"x", metadata !1, i32 5, metadata !7, i32 0} ; [ DW_TAG_auto_variable ] > +!6 = metadata !{i32 589835, metadata !0, i32 4, i32 14, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] > +!7 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] > +!8 = metadata !{i32 6, i32 3, metadata !6, null} > +!9 = metadata !{metadata !"int", metadata !10} > +!10 = metadata !{metadata !"omnipotent char", metadata !11} > +!11 = metadata !{metadata !"Simple C/C++ TBAA", null} > +!12 = metadata !{i32 1} > +!13 = metadata !{i32 7, i32 3, metadata !6, null} > +!14 = metadata !{i32 8, i32 3, metadata !6, null} > +!15 = metadata !{i32 9, i32 3, metadata !6, null} > +!16 = metadata !{i32 2} > +!17 = metadata !{i32 10, i32 3, metadata !6, null} > +!18 = metadata !{i32 11, i32 3, metadata !6, null} > +!19 = metadata !{i32 12, i32 3, metadata !6, null} > +!20 = metadata !{i32 13, i32 1, metadata !6, null} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From daniel at zuster.org Wed Mar 16 17:16:39 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 16 Mar 2011 22:16:39 -0000 Subject: [llvm-commits] [llvm] r127763 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/CodeGen/ARM/dwarf-relocation.ll Message-ID: <20110316221639.EF3C62A6C12C@llvm.org> Author: ddunbar Date: Wed Mar 16 17:16:39 2011 New Revision: 127763 URL: http://llvm.org/viewvc/llvm-project?rev=127763&view=rev Log: Revert r127757, "Patch to a fix dwarf relocation problem on ARM. One-line fix plus the test where it used to break.", which broke Clang self-host of a Debug+Asserts compiler, on OS X. Removed: llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=127763&r1=127762&r2=127763&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Mar 16 17:16:39 2011 @@ -3272,9 +3272,7 @@ case dwarf::DW_AT_location: { if (UseDotDebugLocEntry.count(Die) != 0) { DIELabel *L = cast(Values[i]); - // Emitting reference to label directly, so the assembler can - // emit the relocations and the offset automatically. - Asm->EmitReference(L->getValue(), dwarf::DW_EH_PE_udata4); + Asm->EmitLabelDifference(L->getValue(), DwarfDebugLocSectionSym, 4); } else Values[i]->EmitValue(Asm, Form); break; @@ -3625,7 +3623,6 @@ if (DotDebugLocEntries.empty()) return; - // Group debug entries. for (SmallVector::iterator I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end(); I != E; ++I) { @@ -3634,7 +3631,7 @@ Entry.Merge(I+1); } - // Start the dwarf location section. + // Start the dwarf loc section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfLocSection()); unsigned char Size = Asm->getTargetData().getPointerSize(); Removed: llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll?rev=127762&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll (original) +++ llvm/trunk/test/CodeGen/ARM/dwarf-relocation.ll (removed) @@ -1,111 +0,0 @@ -; RUN: llc -asm-verbose=true -O1 %s -o - | FileCheck %s - -; // The variable 'x' live on both R0 and R1, so they need an entry in .debug_loc table -; // For that, the DW_AT_location needs to have relocation to that section -; extern int g(int, int); -; extern int a; -; -; void f(void) { -; int x; -; a = g(0, 0); -; x = 1; -; while (x & 1) { x *= a; } -; a = g(x, 0); -; x = 2; -; while (x & 2) { x *= a; } -; a = g(0, x); -; } - -; // The 'x' variable and its symbol reference location -; CHECK: @ Abbrev [{{.*}}] 0x{{.*}}:0x{{.*}} DW_TAG_variable -; CHECK-NEXT: @ DW_AT_name -; CHECK-NEXT: .byte 0 -; CHECK-NEXT: @ DW_AT_decl_file -; CHECK-NEXT: @ DW_AT_decl_line -; CHECK-NEXT: @ DW_AT_type -; CHECK-NEXT: .long .Ldebug_loc0 @ DW_AT_location -; CHECK-NEXT: .byte 0 @ End Of Children Mark - -; // The .debug_loc entry, with the two registers -; CHECK: .Ldebug_loc0: -; CHECK: .long .Ltmp{{.*}} -; CHECK: .long .Ltmp{{.*}} -; CHECK: .short 1 @ Loc expr size -; CHECK: .byte 80 @ DW_OP_reg0 -; CHECK: .long .Ltmp{{.*}} -; CHECK: .long .Lfunc_end0 -; CHECK: .short 1 @ Loc expr size -; CHECK: .byte 81 @ DW_OP_reg1 -; CHECK: .long 0 -; CHECK: .long 0 - - -; ModuleID = 'simple.c' -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32" -target triple = "armv7-none--eabi" - - at a = external global i32 - -define void @f() nounwind { -entry: - %call = tail call i32 @g(i32 0, i32 0) nounwind, !dbg !8 - store i32 %call, i32* @a, align 4, !dbg !8, !tbaa !9 - tail call void @llvm.dbg.value(metadata !12, i64 0, metadata !5), !dbg !13 - br label %while.body - -while.body: ; preds = %entry, %while.body - %x.017 = phi i32 [ 1, %entry ], [ %mul, %while.body ] - %mul = mul nsw i32 %call, %x.017, !dbg !14 - %and = and i32 %mul, 1, !dbg !14 - %tobool = icmp eq i32 %and, 0, !dbg !14 - br i1 %tobool, label %while.end, label %while.body, !dbg !14 - -while.end: ; preds = %while.body - tail call void @llvm.dbg.value(metadata !{i32 %mul}, i64 0, metadata !5), !dbg !14 - %call4 = tail call i32 @g(i32 %mul, i32 0) nounwind, !dbg !15 - store i32 %call4, i32* @a, align 4, !dbg !15, !tbaa !9 - tail call void @llvm.dbg.value(metadata !16, i64 0, metadata !5), !dbg !17 - br label %while.body9 - -while.body9: ; preds = %while.end, %while.body9 - %x.116 = phi i32 [ 2, %while.end ], [ %mul12, %while.body9 ] - %mul12 = mul nsw i32 %call4, %x.116, !dbg !18 - %and7 = and i32 %mul12, 2, !dbg !18 - %tobool8 = icmp eq i32 %and7, 0, !dbg !18 - br i1 %tobool8, label %while.end13, label %while.body9, !dbg !18 - -while.end13: ; preds = %while.body9 - tail call void @llvm.dbg.value(metadata !{i32 %mul12}, i64 0, metadata !5), !dbg !18 - %call15 = tail call i32 @g(i32 0, i32 %mul12) nounwind, !dbg !19 - store i32 %call15, i32* @a, align 4, !dbg !19, !tbaa !9 - ret void, !dbg !20 -} - -declare i32 @g(i32, i32) - -declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone - -!llvm.dbg.sp = !{!0} -!llvm.dbg.lv.f = !{!5} - -!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"f", metadata !"f", metadata !"", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void ()* @f} ; [ DW_TAG_subprogram ] -!1 = metadata !{i32 589865, metadata !"simple.c", metadata !"/home/rengol01/temp/tests/dwarf/relocation", metadata !2} ; [ DW_TAG_file_type ] -!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"simple.c", metadata !"/home/rengol01/temp/tests/dwarf/relocation", metadata !"clang version 3.0 (trunk)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] -!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] -!4 = metadata !{null} -!5 = metadata !{i32 590080, metadata !6, metadata !"x", metadata !1, i32 5, metadata !7, i32 0} ; [ DW_TAG_auto_variable ] -!6 = metadata !{i32 589835, metadata !0, i32 4, i32 14, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] -!7 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] -!8 = metadata !{i32 6, i32 3, metadata !6, null} -!9 = metadata !{metadata !"int", metadata !10} -!10 = metadata !{metadata !"omnipotent char", metadata !11} -!11 = metadata !{metadata !"Simple C/C++ TBAA", null} -!12 = metadata !{i32 1} -!13 = metadata !{i32 7, i32 3, metadata !6, null} -!14 = metadata !{i32 8, i32 3, metadata !6, null} -!15 = metadata !{i32 9, i32 3, metadata !6, null} -!16 = metadata !{i32 2} -!17 = metadata !{i32 10, i32 3, metadata !6, null} -!18 = metadata !{i32 11, i32 3, metadata !6, null} -!19 = metadata !{i32 12, i32 3, metadata !6, null} -!20 = metadata !{i32 13, i32 1, metadata !6, null} From zwarich at apple.com Wed Mar 16 17:20:07 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 22:20:07 -0000 Subject: [llvm-commits] [llvm] r127764 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Message-ID: <20110316222007.CE5FD2A6C12C@llvm.org> Author: zwarich Date: Wed Mar 16 17:20:07 2011 New Revision: 127764 URL: http://llvm.org/viewvc/llvm-project?rev=127764&view=rev Log: Don't recompute something that we already have in a local variable. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=127764&r1=127763&r2=127764&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Mar 16 17:20:07 2011 @@ -1151,9 +1151,9 @@ Flags.setInReg(); // Propagate extension type if any - if (F->paramHasAttr(0, Attribute::SExt)) + if (ExtendKind == ISD::SIGN_EXTEND) Flags.setSExt(); - else if (F->paramHasAttr(0, Attribute::ZExt)) + else if (ExtendKind == ISD::ZERO_EXTEND) Flags.setZExt(); for (unsigned i = 0; i < NumParts; ++i) { From zwarich at apple.com Wed Mar 16 17:20:13 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 22:20:13 -0000 Subject: [llvm-commits] [llvm] r127765 - in /llvm/trunk/test/CodeGen/X86: bool-args-zext.ll bool-zext.ll Message-ID: <20110316222013.1FFCE2A6C12D@llvm.org> Author: zwarich Date: Wed Mar 16 17:20:12 2011 New Revision: 127765 URL: http://llvm.org/viewvc/llvm-project?rev=127765&view=rev Log: Rename a test to be more inclusive. Added: llvm/trunk/test/CodeGen/X86/bool-zext.ll - copied, changed from r127764, llvm/trunk/test/CodeGen/X86/bool-args-zext.ll Removed: llvm/trunk/test/CodeGen/X86/bool-args-zext.ll Removed: llvm/trunk/test/CodeGen/X86/bool-args-zext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-args-zext.ll?rev=127764&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/bool-args-zext.ll (original) +++ llvm/trunk/test/CodeGen/X86/bool-args-zext.ll (removed) @@ -1,23 +0,0 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s - -; CHECK: @bar1 -; CHECK: movzbl -; CHECK: callq -define void @bar1(i1 zeroext %v1) nounwind ssp { -entry: - %conv = zext i1 %v1 to i32 - %call = tail call i32 (...)* @foo(i32 %conv) nounwind - ret void -} - -; CHECK: @bar2 -; CHECK-NOT: movzbl -; CHECK: callq -define void @bar2(i8 zeroext %v1) nounwind ssp { -entry: - %conv = zext i8 %v1 to i32 - %call = tail call i32 (...)* @foo(i32 %conv) nounwind - ret void -} - -declare i32 @foo(...) Copied: llvm/trunk/test/CodeGen/X86/bool-zext.ll (from r127764, llvm/trunk/test/CodeGen/X86/bool-args-zext.ll) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-zext.ll?p2=llvm/trunk/test/CodeGen/X86/bool-zext.ll&p1=llvm/trunk/test/CodeGen/X86/bool-args-zext.ll&r1=127764&r2=127765&rev=127765&view=diff ============================================================================== (empty) From zwarich at apple.com Wed Mar 16 17:20:18 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 22:20:18 -0000 Subject: [llvm-commits] [llvm] r127766 - in /llvm/trunk: docs/LangRef.html include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/bool-zext.ll Message-ID: <20110316222019.528DA2A6C12C@llvm.org> Author: zwarich Date: Wed Mar 16 17:20:18 2011 New Revision: 127766 URL: http://llvm.org/viewvc/llvm-project?rev=127766&view=rev Log: The x86-64 ABI says that a bool is only guaranteed to be sign-extended to a byte rather than an int. Thankfully, this only causes LLVM to miss optimizations, not generate incorrect code. This just fixes the zext at the return. We still insert an i32 ZextAssert when reading a function's arguments, but it is followed by a truncate and another i8 ZextAssert so it is not optimized. Modified: llvm/trunk/docs/LangRef.html llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/test/CodeGen/X86/bool-zext.ll Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=127766&r1=127765&r2=127766&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Wed Mar 16 17:20:18 2011 @@ -1017,8 +1017,9 @@
zeroext
This indicates to the code generator that the parameter or return value - should be zero-extended to a 32-bit value by the caller (for a parameter) - or the callee (for a return value).
+ should be zero-extended to the extent required by the target's ABI (which + is usually 32-bits, but is 8-bits for a i1 on x86-64) by the caller (for a + parameter) or the callee (for a return value).
signext
This indicates to the code generator that the parameter or return value Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127766&r1=127765&r2=127766&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Wed Mar 16 17:20:18 2011 @@ -1287,6 +1287,17 @@ return false; } + /// getTypeForExtendedInteger - Return the type that should be used to zero or + /// sign extend a zeroext/signext integer argument or return value. + /// FIXME: Most C calling convention requires the return type to be promoted, + /// but this is not true all the time, e.g. i1 on x86-64. It is also not + /// necessary for non-C calling conventions. The frontend should handle this + /// and include all of the necessary information. + virtual MVT + getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const { + return MVT::i32; + } + /// LowerOperationWrapper - This callback is invoked by the type legalizer /// to legalize nodes with an illegal operand type but legal result types. /// It replaces the LowerOperation callback in the type Legalizer. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=127766&r1=127765&r2=127766&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Mar 16 17:20:18 2011 @@ -1128,12 +1128,9 @@ else if (F->paramHasAttr(0, Attribute::ZExt)) ExtendKind = ISD::ZERO_EXTEND; - // FIXME: C calling convention requires the return type to be promoted - // to at least 32-bit. But this is not necessary for non-C calling - // conventions. The frontend should mark functions whose return values - // require promoting with signext or zeroext attributes. if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { - EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32); + MVT ReturnMVT = TLI.getTypeForExtendedInteger(VT, ExtendKind); + EVT MinVT = TLI.getRegisterType(*DAG.getContext(), ReturnMVT); if (VT.bitsLT(MinVT)) VT = MinVT; } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127766&r1=127765&r2=127766&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Mar 16 17:20:18 2011 @@ -1448,6 +1448,15 @@ return HasRet; } +MVT +X86TargetLowering::getTypeForExtendedInteger(EVT VT, + ISD::NodeType ExtendKind) const { + // TODO: Is this also valid on 32-bit? + if (Subtarget->is64Bit() && VT == MVT::i1 && ExtendKind == ISD::ZERO_EXTEND) + return MVT::i8; + return MVT::i32; +} + /// LowerCallResult - Lower the result values of a call into the /// appropriate copies out of appropriate physical registers. /// Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127766&r1=127765&r2=127766&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Mar 16 17:20:18 2011 @@ -843,6 +843,9 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; + virtual MVT + getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const; + virtual bool CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, Modified: llvm/trunk/test/CodeGen/X86/bool-zext.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-zext.ll?rev=127766&r1=127765&r2=127766&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/bool-zext.ll (original) +++ llvm/trunk/test/CodeGen/X86/bool-zext.ll Wed Mar 16 17:20:18 2011 @@ -6,7 +6,7 @@ define void @bar1(i1 zeroext %v1) nounwind ssp { entry: %conv = zext i1 %v1 to i32 - %call = tail call i32 (...)* @foo(i32 %conv) nounwind + %call = tail call i32 (...)* @foo1(i32 %conv) nounwind ret void } @@ -16,8 +16,20 @@ define void @bar2(i8 zeroext %v1) nounwind ssp { entry: %conv = zext i8 %v1 to i32 - %call = tail call i32 (...)* @foo(i32 %conv) nounwind + %call = tail call i32 (...)* @foo1(i32 %conv) nounwind ret void } -declare i32 @foo(...) +; CHECK: @bar3 +; CHECK: callq +; CHECK-NOT: movzbl +; CHECK-NOT: and +; CHECK: ret +define zeroext i1 @bar3() nounwind ssp { +entry: + %call = call i1 @foo2() nounwind + ret i1 %call +} + +declare i32 @foo1(...) +declare zeroext i1 @foo2() From kledzik at apple.com Wed Mar 16 17:23:24 2011 From: kledzik at apple.com (Nick Kledzik) Date: Wed, 16 Mar 2011 22:23:24 -0000 Subject: [llvm-commits] [compiler-rt] r127767 - /compiler-rt/trunk/make/AppleBI.mk Message-ID: <20110316222324.51ABD2A6C12C@llvm.org> Author: kledzik Date: Wed Mar 16 17:23:24 2011 New Revision: 127767 URL: http://llvm.org/viewvc/llvm-project?rev=127767&view=rev Log: use -Os for release builds Modified: compiler-rt/trunk/make/AppleBI.mk Modified: compiler-rt/trunk/make/AppleBI.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/make/AppleBI.mk?rev=127767&r1=127766&r2=127767&view=diff ============================================================================== --- compiler-rt/trunk/make/AppleBI.mk (original) +++ compiler-rt/trunk/make/AppleBI.mk Wed Mar 16 17:23:24 2011 @@ -17,10 +17,10 @@ LD_OTHER_FLAGS = else INSTALL_TARGET = install-iOS - CFLAGS.Release.armv6 := $(CFLAGS) -isysroot $(SDKROOT) - CFLAGS.Release.armv7 := $(CFLAGS) -isysroot $(SDKROOT) - CFLAGS.Static.armv6 := $(CFLAGS) -isysroot $(SDKROOT) - CFLAGS.Static.armv7 := $(CFLAGS) -isysroot $(SDKROOT) + CFLAGS.Release.armv6 := $(CFLAGS) -Wall -Os -fomit-frame-pointer -g -isysroot $(SDKROOT) + CFLAGS.Release.armv7 := $(CFLAGS) -Wall -Os -fomit-frame-pointer -g -isysroot $(SDKROOT) + CFLAGS.Static.armv6 := $(CFLAGS) -Wall -Os -fomit-frame-pointer -g -isysroot $(SDKROOT) + CFLAGS.Static.armv7 := $(CFLAGS) -Wall -Os -fomit-frame-pointer -g -isysroot $(SDKROOT) LD_OTHER_FLAGS = -Wl,-alias_list,$(SRCROOT)/lib/arm/softfloat-alias.list -isysroot $(SDKROOT) endif From steinke.dirk.ml at googlemail.com Wed Mar 16 17:29:55 2011 From: steinke.dirk.ml at googlemail.com (Dirk Steinke) Date: Wed, 16 Mar 2011 23:29:55 +0100 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors In-Reply-To: <1BC27846-E3EC-4EDA-AB97-D25D902C5C4C@apple.com> References: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> <4D812501.9020808@gmail.com> <1BC27846-E3EC-4EDA-AB97-D25D902C5C4C@apple.com> Message-ID: <4D8139E3.3010208@gmail.com> On 03/16/2011 10:29 PM, Stephen Canon wrote: >> thanks for working on this, but your code seems suboptimal to me. If I'm >> not mistaken, you should be able to turn >> UINT_TO_FP(a) into SINT_TO_FP(a& ~SIGNBIT) - SINT_TO_FP(a& SIGNBIT) >> which gets rid of one floating point multiplication, and replaces one >> shift by an AND, but at the cost of one extra vector constant. In >> theory, using PANDN on x86, one memory load should be enough, but >> well... What do you think? > > You are mistaken. > > You cannot implement uint -> fp as you describe, as it introduces a double-rounding for certain values. There are many, but here is one example to illustrate the problem 0x81000081. It is one greater than an exact halfway case for rounding to single-precision, but the result when using the algorithm you describe is rounded *down* instead of up with default IEEE-754 rounding. > > - Steve > > Hi Steve, thanks. I had just realized myself, that the number of mantissa bits are quite smaller than the bits in the equivalent integer, and there will be rounding when the high bits of the integer are set. So changing the sign bit is a bad idea. The only other thing I could come up with right now, is changing the partitioning from like SINT_TO_FP(high 16 bits) * (2^16) + SINT_TO_FP(low 16 bits) to SINT_TO_FP(high 31 bits) * (2) + SINT_TO_FP(low 1 bit) so that the mul could be turned into an add instead. But with fmadd-units around the corner, and separate fmul- and fadd-units at least on x86, that would be counter-productive. Nadav, sorry for the noise. Dirk From steinke.dirk.ml at googlemail.com Wed Mar 16 17:40:01 2011 From: steinke.dirk.ml at googlemail.com (Dirk Steinke) Date: Wed, 16 Mar 2011 23:40:01 +0100 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors In-Reply-To: <4D8139E3.3010208@gmail.com> References: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> <4D812501.9020808@gmail.com> <1BC27846-E3EC-4EDA-AB97-D25D902C5C4C@apple.com> <4D8139E3.3010208@gmail.com> Message-ID: <4D813C41.70407@gmail.com> Hi Steve, On 03/16/2011 11:29 PM, Dirk Steinke wrote: > On 03/16/2011 10:29 PM, Stephen Canon wrote: [snip] >> >> You are mistaken. >> >> You cannot implement uint -> fp as you describe, as it introduces a >> double-rounding for certain values. There are many, but here is one [snip] > The only other thing I could come up with right now, is changing the > partitioning from like > SINT_TO_FP(high 16 bits) * (2^16) + SINT_TO_FP(low 16 bits) > to > SINT_TO_FP(high 31 bits) * (2) + SINT_TO_FP(low 1 bit) Which of course wouldn't work anyway for the reason, you already described. I guess I must be much more careful when thinking about floating point operations. Dirk From geek4civic at gmail.com Wed Mar 16 17:40:47 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 17 Mar 2011 07:40:47 +0900 Subject: [llvm-commits] [llvm] r127351 - in /llvm/trunk: lib/CodeGen/SimpleRegisterCoalescing.cpp test/CodeGen/X86/2011-03-09-Physreg-Coalescing.ll test/CodeGen/X86/fold-pcmpeqd-2.ll In-Reply-To: References: <20110309192706.B181C2A6C12D@llvm.org> Message-ID: Good morning, Jakob. On Thu, Mar 17, 2011 at 2:19 AM, Jakob Stoklund Olesen wrote: >> With r127351, X86/h-registers-1.ll is emitted differently on >> -mtriple=x86_64-win32. >> Is it expected or possible? > > Yes, it is possible because the win32 calling convention uses different registers for the incoming arguments. > > Physreg coalescing would extend the range of incoming physregs into the body of the function. That is actually a really bad idea in this function where the ABCD register classes are in use. (snip) > In this case, the change caused a different register to be spilled, and the reload was folded into one of the movzbl instructions. I see. I wondered it might be regression for win64. > We can add an -mtriple argument to the test to make sure the calling convention doesn't change. The test isn't trying to test register allocation or spilling anyway. Ok. I will do, thank you. ...Takumi From scanon at apple.com Wed Mar 16 17:40:39 2011 From: scanon at apple.com (Stephen Canon) Date: Wed, 16 Mar 2011 15:40:39 -0700 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors In-Reply-To: <4D8139E3.3010208@gmail.com> References: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> <4D812501.9020808@gmail.com> <1BC27846-E3EC-4EDA-AB97-D25D902C5C4C@apple.com> <4D8139E3.3010208@gmail.com> Message-ID: On Mar 16, 2011, at 3:29 PM, Dirk Steinke wrote: [snip] > SINT_TO_FP(high 31 bits) * (2) + SINT_TO_FP(low 1 bit) This actually suffers from the same problem; 0x81000081 rounds to 0x81000000 instead of 0x81000100 as it should. In order to work properly, an int->float conversion needs to consist of a sum of two values, both of which are guaranteed to have been converted without rounding. There are tricks (sticky bits) that can be used to simplify this somewhat in more extreme cases (like uint64_t -> float), but generally you need each of the components to be built from fewer bits than the precision of the floating-point type. - Steve From stoklund at 2pi.dk Wed Mar 16 17:56:08 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 16 Mar 2011 22:56:08 -0000 Subject: [llvm-commits] [llvm] r127771 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp LiveRangeEdit.cpp RegAllocGreedy.cpp Message-ID: <20110316225608.F32652A6C12C@llvm.org> Author: stoklund Date: Wed Mar 16 17:56:08 2011 New Revision: 127771 URL: http://llvm.org/viewvc/llvm-project?rev=127771&view=rev Log: Clarify debugging output. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=127771&r1=127770&r2=127771&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Mar 16 17:56:08 2011 @@ -854,7 +854,7 @@ assert(MI && "No instruction defining live value"); MI->addRegisterDead(li->reg, tri_); if (dead && MI->allDefsAreDead()) { - DEBUG(dbgs() << "All defs dead: " << *MI); + DEBUG(dbgs() << "All defs dead: " << VNI->def << '\t' << *MI); dead->push_back(MI); } } @@ -862,7 +862,7 @@ // Move the trimmed ranges back. li->ranges.swap(NewLI.ranges); - DEBUG(dbgs() << "Shrink: " << *li << '\n'); + DEBUG(dbgs() << "Shrunk: " << *li << '\n'); } Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=127771&r1=127770&r2=127771&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Wed Mar 16 17:56:08 2011 @@ -148,17 +148,21 @@ while (!Dead.empty()) { MachineInstr *MI = Dead.pop_back_val(); assert(MI->allDefsAreDead() && "Def isn't really dead"); + SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex(); // Never delete inline asm. - if (MI->isInlineAsm()) + if (MI->isInlineAsm()) { + DEBUG(dbgs() << "Won't delete: " << Idx << '\t' << *MI); continue; + } // Use the same criteria as DeadMachineInstructionElim. bool SawStore = false; - if (!MI->isSafeToMove(&TII, 0, SawStore)) + if (!MI->isSafeToMove(&TII, 0, SawStore)) { + DEBUG(dbgs() << "Can't delete: " << Idx << '\t' << *MI); continue; + } - SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex(); DEBUG(dbgs() << "Deleting dead def " << Idx << '\t' << *MI); // Check for live intervals that may shrink Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=127771&r1=127770&r2=127771&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Wed Mar 16 17:56:08 2011 @@ -646,7 +646,9 @@ IndexPair &IP = InterferenceRanges[i]; DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " -> EB#" << Bundles->getBundle(BI.MBB->getNumber(), 1) - << " intf [" << IP.first << ';' << IP.second << ')'); + << " [" << BI.Start << ';' << BI.LastSplitPoint << '-' + << BI.Stop << ") intf [" << IP.first << ';' << IP.second + << ')'); // The interference interval should either be invalid or overlap MBB. assert((!IP.first.isValid() || IP.first < BI.Stop) && "Bad interference"); @@ -741,7 +743,8 @@ IndexPair &IP = InterferenceRanges[i]; DEBUG(dbgs() << "EB#" << Bundles->getBundle(BI.MBB->getNumber(), 0) - << " -> BB#" << BI.MBB->getNumber()); + << " -> BB#" << BI.MBB->getNumber() << " [" << BI.Start << ';' + << BI.LastSplitPoint << '-' << BI.Stop << ')'); // Check interference entering the block. if (!IP.first.isValid()) { @@ -1266,6 +1269,9 @@ LiveRangeEdit LRE(VirtReg, NewVRegs, this); spiller().spill(LRE); + if (VerifyEnabled) + MF->verify(this, "After spilling"); + // The live virtual register requesting allocation was spilled, so tell // the caller not to allocate anything during this round. return 0; From stoklund at 2pi.dk Wed Mar 16 17:56:11 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 16 Mar 2011 22:56:11 -0000 Subject: [llvm-commits] [llvm] r127772 - in /llvm/trunk/lib/CodeGen: LiveIntervalUnion.h RegAllocBase.h RegAllocBasic.cpp Message-ID: <20110316225611.AE8FF2A6C12D@llvm.org> Author: stoklund Date: Wed Mar 16 17:56:11 2011 New Revision: 127772 URL: http://llvm.org/viewvc/llvm-project?rev=127772&view=rev Log: Tag cached interference with a user-provided tag instead of the virtual register number. The live range of a virtual register may change which invalidates the cached interference information. Modified: llvm/trunk/lib/CodeGen/LiveIntervalUnion.h llvm/trunk/lib/CodeGen/RegAllocBase.h llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalUnion.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalUnion.h?rev=127772&r1=127771&r2=127772&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalUnion.h (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalUnion.h Wed Mar 16 17:56:11 2011 @@ -163,7 +163,7 @@ bool CheckedFirstInterference; bool SeenAllInterferences; bool SeenUnspillableVReg; - unsigned Tag, VTag; + unsigned Tag, UserTag; public: Query(): LiveUnion(), VirtReg() {} @@ -181,12 +181,13 @@ SeenAllInterferences = false; SeenUnspillableVReg = false; Tag = 0; - VTag = 0; + UserTag = 0; } - void init(LiveInterval *VReg, LiveIntervalUnion *LIU) { + void init(unsigned UTag, LiveInterval *VReg, LiveIntervalUnion *LIU) { assert(VReg && LIU && "Invalid arguments"); - if (VReg->reg == VTag && LiveUnion == LIU && !LIU->changedSince(Tag)) { + if (UserTag == UTag && VirtReg == VReg && + LiveUnion == LIU && !LIU->changedSince(Tag)) { // Retain cached results, e.g. firstInterference. return; } @@ -194,7 +195,7 @@ LiveUnion = LIU; VirtReg = VReg; Tag = LIU->getTag(); - VTag = VReg->reg; + UserTag = UTag; } LiveInterval &virtReg() const { Modified: llvm/trunk/lib/CodeGen/RegAllocBase.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBase.h?rev=127772&r1=127771&r2=127772&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBase.h (original) +++ llvm/trunk/lib/CodeGen/RegAllocBase.h Wed Mar 16 17:56:11 2011 @@ -61,6 +61,11 @@ /// assignment order. class RegAllocBase { LiveIntervalUnion::Allocator UnionAllocator; + + // Cache tag for PhysReg2LiveUnion entries. Increment whenever virtual + // registers may have changed. + unsigned UserTag; + protected: // Array of LiveIntervalUnions indexed by physical register. class LiveUnionArray { @@ -92,7 +97,7 @@ // query on a new live virtual register. OwningArrayPtr Queries; - RegAllocBase(): TRI(0), MRI(0), VRM(0), LIS(0) {} + RegAllocBase(): UserTag(0), TRI(0), MRI(0), VRM(0), LIS(0) {} virtual ~RegAllocBase() {} @@ -104,7 +109,7 @@ // before querying a new live virtual register. This ties Queries and // PhysReg2LiveUnion together. LiveIntervalUnion::Query &query(LiveInterval &VirtReg, unsigned PhysReg) { - Queries[PhysReg].init(&VirtReg, &PhysReg2LiveUnion[PhysReg]); + Queries[PhysReg].init(UserTag, &VirtReg, &PhysReg2LiveUnion[PhysReg]); return Queries[PhysReg]; } Modified: llvm/trunk/lib/CodeGen/RegAllocBasic.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBasic.cpp?rev=127772&r1=127771&r2=127772&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBasic.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Wed Mar 16 17:56:11 2011 @@ -296,6 +296,9 @@ continue; } + // Invalidate all interference queries, live ranges could have changed. + ++UserTag; + // selectOrSplit requests the allocator to return an available physical // register if possible and populate a list of new live intervals that // result from splitting. From stoklund at 2pi.dk Wed Mar 16 17:56:14 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 16 Mar 2011 22:56:14 -0000 Subject: [llvm-commits] [llvm] r127773 - /llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Message-ID: <20110316225614.24D1D2A6C12E@llvm.org> Author: stoklund Date: Wed Mar 16 17:56:13 2011 New Revision: 127773 URL: http://llvm.org/viewvc/llvm-project?rev=127773&view=rev Log: Erase virtual registers that are unused after DCE. Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=127773&r1=127772&r2=127773&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Wed Mar 16 17:56:13 2011 @@ -174,13 +174,21 @@ if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; LiveInterval &LI = LIS.getInterval(Reg); - // Remove defined value. - if (MOI->isDef()) - if (VNInfo *VNI = LI.getVNInfoAt(Idx)) - LI.removeValNo(VNI); + // Shrink read registers. if (MI->readsVirtualRegister(Reg)) ToShrink.insert(&LI); + + // Remove defined value. + if (MOI->isDef()) { + if (VNInfo *VNI = LI.getVNInfoAt(Idx)) { + LI.removeValNo(VNI); + if (LI.empty()) { + ToShrink.remove(&LI); + eraseVirtReg(Reg, LIS); + } + } + } } if (delegate_) From stoklund at 2pi.dk Wed Mar 16 17:56:16 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 16 Mar 2011 22:56:16 -0000 Subject: [llvm-commits] [llvm] r127774 - in /llvm/trunk/lib/CodeGen: LiveRangeEdit.cpp LiveRangeEdit.h RegAllocGreedy.cpp Message-ID: <20110316225616.AE1372A6C12C@llvm.org> Author: stoklund Date: Wed Mar 16 17:56:16 2011 New Revision: 127774 URL: http://llvm.org/viewvc/llvm-project?rev=127774&view=rev Log: Add a LiveRangeEdit delegate callback before shrinking a live range. The register allocator needs to adjust its live interval unions when that happens. Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.h llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=127774&r1=127773&r2=127774&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Wed Mar 16 17:56:16 2011 @@ -201,8 +201,11 @@ break; // Shrink just one live interval. Then delete new dead defs. - LIS.shrinkToUses(ToShrink.back(), &Dead); + LiveInterval *LI = ToShrink.back(); ToShrink.pop_back(); + if (delegate_) + delegate_->LRE_WillShrinkVirtReg(LI->reg); + LIS.shrinkToUses(LI, &Dead); } } Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.h?rev=127774&r1=127773&r2=127774&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.h (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.h Wed Mar 16 17:56:16 2011 @@ -39,6 +39,9 @@ /// its deletion from LiveIntervals. virtual bool LRE_CanEraseVirtReg(unsigned) { return true; } + /// Called before shrinking the live range of a virtual register. + virtual void LRE_WillShrinkVirtReg(unsigned) {} + virtual ~Delegate() {} }; Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=127774&r1=127773&r2=127774&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Wed Mar 16 17:56:16 2011 @@ -162,6 +162,7 @@ private: void LRE_WillEraseInstruction(MachineInstr*); bool LRE_CanEraseVirtReg(unsigned); + void LRE_WillShrinkVirtReg(unsigned); bool checkUncachedInterference(LiveInterval&, unsigned); LiveInterval *getSingleInterference(LiveInterval&, unsigned); @@ -260,6 +261,17 @@ return false; } +void RAGreedy::LRE_WillShrinkVirtReg(unsigned VirtReg) { + unsigned PhysReg = VRM->getPhys(VirtReg); + if (!PhysReg) + return; + + // Register is assigned, put it back on the queue for reassignment. + LiveInterval &LI = LIS->getInterval(VirtReg); + unassign(LI, PhysReg); + enqueue(&LI); +} + void RAGreedy::releaseMemory() { SpillerInstance.reset(0); LRStage.clear(); From geek4civic at gmail.com Wed Mar 16 18:01:31 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Wed, 16 Mar 2011 23:01:31 -0000 Subject: [llvm-commits] [llvm] r127775 - /llvm/trunk/test/CodeGen/X86/constant-pool-remat-0.ll Message-ID: <20110316230131.330FF2A6C12C@llvm.org> Author: chapuni Date: Wed Mar 16 18:01:31 2011 New Revision: 127775 URL: http://llvm.org/viewvc/llvm-project?rev=127775&view=rev Log: test/CodeGen/X86/constant-pool-remat-0.ll: FileCheck-ize and add explicit -mtriple=x86_64-linux. Modified: llvm/trunk/test/CodeGen/X86/constant-pool-remat-0.ll Modified: llvm/trunk/test/CodeGen/X86/constant-pool-remat-0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/constant-pool-remat-0.ll?rev=127775&r1=127774&r2=127775&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/constant-pool-remat-0.ll (original) +++ llvm/trunk/test/CodeGen/X86/constant-pool-remat-0.ll Wed Mar 16 18:01:31 2011 @@ -1,7 +1,15 @@ -; RUN: llc < %s -march=x86-64 | grep LCPI | count 3 -; RUN: llc < %s -march=x86-64 -o /dev/null -stats -info-output-file - | grep asm-printer | grep 6 -; RUN: llc < %s -march=x86 -mattr=+sse2 | grep LCPI | count 3 -; RUN: llc < %s -march=x86 -mattr=+sse2 -o /dev/null -stats -info-output-file - | grep asm-printer | grep 12 +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s +; CHECK: LCPI +; CHECK: LCPI +; CHECK: LCPI +; CHECK-NOT: LCPI + +; RUN: llc < %s -mtriple=x86_64-linux -o /dev/null -stats -info-output-file - | FileCheck %s -check-prefix=X64stat +; X64stat: 6 asm-printer + +; RUN: llc < %s -march=x86 -mattr=+sse2 -o /dev/null -stats -info-output-file - | FileCheck %s -check-prefix=X32stat +; X32stat: 12 asm-printer declare float @qux(float %y) From geek4civic at gmail.com Wed Mar 16 18:08:43 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 17 Mar 2011 08:08:43 +0900 Subject: [llvm-commits] [PATCH] test/CodeGen/X86/constant-pool-remat-0.ll: Tweak to force all XMMs spilled, to let rematerialized on Win64. In-Reply-To: References: Message-ID: On Thu, Mar 17, 2011 at 3:26 AM, Jakob Stoklund Olesen wrote: > That's a neat trick, but I don't think it is necessary. > > The test is checking that the register allocator can fold constant pool loads instead of spilling an xmm register. That is not necessary on windows, so you can just force the triple to linux or darwin. I see, and I have committed in r127775 to eliminate win64 stuff and asm, thank you. ...Takumi From eli.friedman at gmail.com Wed Mar 16 19:00:49 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Wed, 16 Mar 2011 17:00:49 -0700 Subject: [llvm-commits] [llvm] r127766 - in /llvm/trunk: docs/LangRef.html include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/bool-zext Message-ID: On Wed, Mar 16, 2011 at 3:20 PM, Cameron Zwarich wrote: > Author: zwarich > Date: Wed Mar 16 17:20:18 2011 > New Revision: 127766 > > URL: http://llvm.org/viewvc/llvm-project?rev=127766&view=rev > Log: > The x86-64 ABI says that a bool is only guaranteed to be sign-extended to a byte > rather than an int. Thankfully, this only causes LLVM to miss optimizations, not > generate incorrect code. Ooo, wow, nasty... I was just going to quote the ABI, but then I found out that there have been relevant changes here in the latest revision. > This just fixes the zext at the return. We still insert an i32 ZextAssert when > reading a function's arguments, but it is followed by a truncate and another i8 > ZextAssert so it is not optimized. > > Modified: > ? ?llvm/trunk/docs/LangRef.html > ? ?llvm/trunk/include/llvm/Target/TargetLowering.h > ? ?llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp > ? ?llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > ? ?llvm/trunk/lib/Target/X86/X86ISelLowering.h > ? ?llvm/trunk/test/CodeGen/X86/bool-zext.ll > > Modified: llvm/trunk/docs/LangRef.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/docs/LangRef.html (original) > +++ llvm/trunk/docs/LangRef.html Wed Mar 16 17:20:18 2011 > @@ -1017,8 +1017,9 @@ > ?
> ?
zeroext
> ?
This indicates to the code generator that the parameter or return value > - ? ? ?should be zero-extended to a 32-bit value by the caller (for a parameter) > - ? ? ?or the callee (for a return value).
> + ? ? ?should be zero-extended to the extent required by the target's ABI (which > + ? ? ?is usually 32-bits, but is 8-bits for a i1 on x86-64) by the caller (for a > + ? ? ?parameter) or the callee (for a return value).
> > ?
signext
> ?
This indicates to the code generator that the parameter or return value > > Modified: llvm/trunk/include/llvm/Target/TargetLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) > +++ llvm/trunk/include/llvm/Target/TargetLowering.h Wed Mar 16 17:20:18 2011 > @@ -1287,6 +1287,17 @@ > ? ? return false; > ? } > > + ?/// getTypeForExtendedInteger - Return the type that should be used to zero or > + ?/// sign extend a zeroext/signext integer argument or return value. > + ?/// FIXME: Most C calling convention requires the return type to be promoted, > + ?/// but this is not true all the time, e.g. i1 on x86-64. It is also not > + ?/// necessary for non-C calling conventions. The frontend should handle this > + ?/// and include all of the necessary information. > + ?virtual MVT > + ?getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const { > + ? ?return MVT::i32; > + ?} > + > ? /// LowerOperationWrapper - This callback is invoked by the type legalizer > ? /// to legalize nodes with an illegal operand type but legal result types. > ? /// It replaces the LowerOperation callback in the type Legalizer. > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Mar 16 17:20:18 2011 > @@ -1128,12 +1128,9 @@ > ? ? ? ? else if (F->paramHasAttr(0, Attribute::ZExt)) > ? ? ? ? ? ExtendKind = ISD::ZERO_EXTEND; > > - ? ? ? ?// FIXME: C calling convention requires the return type to be promoted > - ? ? ? ?// to at least 32-bit. But this is not necessary for non-C calling > - ? ? ? ?// conventions. The frontend should mark functions whose return values > - ? ? ? ?// require promoting with signext or zeroext attributes. > ? ? ? ? if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { > - ? ? ? ? ?EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32); > + ? ? ? ? ?MVT ReturnMVT = TLI.getTypeForExtendedInteger(VT, ExtendKind); > + ? ? ? ? ?EVT MinVT = TLI.getRegisterType(*DAG.getContext(), ReturnMVT); > ? ? ? ? ? if (VT.bitsLT(MinVT)) > ? ? ? ? ? ? VT = MinVT; > ? ? ? ? } > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Mar 16 17:20:18 2011 > @@ -1448,6 +1448,15 @@ > ? return HasRet; > ?} > > +MVT > +X86TargetLowering::getTypeForExtendedInteger(EVT VT, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ISD::NodeType ExtendKind) const { > + ?// TODO: Is this also valid on 32-bit? > + ?if (Subtarget->is64Bit() && VT == MVT::i1 && ExtendKind == ISD::ZERO_EXTEND) > + ? ?return MVT::i8; > + ?return MVT::i32; > +} > + > ?/// LowerCallResult - Lower the result values of a call into the > ?/// appropriate copies out of appropriate physical registers. > ?/// > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Mar 16 17:20:18 2011 > @@ -843,6 +843,9 @@ > > ? ? virtual bool isUsedByReturnOnly(SDNode *N) const; > > + ? ?virtual MVT > + ? ?getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const; > + > ? ? virtual bool > ? ? ? CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, > ? ? ? ? ? ? ? ? ? ? ?const SmallVectorImpl &Outs, > > Modified: llvm/trunk/test/CodeGen/X86/bool-zext.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-zext.ll?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/test/CodeGen/X86/bool-zext.ll (original) > +++ llvm/trunk/test/CodeGen/X86/bool-zext.ll Wed Mar 16 17:20:18 2011 > @@ -6,7 +6,7 @@ > ?define void @bar1(i1 zeroext %v1) nounwind ssp { > ?entry: > ? %conv = zext i1 %v1 to i32 > - ?%call = tail call i32 (...)* @foo(i32 %conv) nounwind > + ?%call = tail call i32 (...)* @foo1(i32 %conv) nounwind > ? ret void > ?} > > @@ -16,8 +16,20 @@ > ?define void @bar2(i8 zeroext %v1) nounwind ssp { > ?entry: > ? %conv = zext i8 %v1 to i32 > - ?%call = tail call i32 (...)* @foo(i32 %conv) nounwind > + ?%call = tail call i32 (...)* @foo1(i32 %conv) nounwind > ? ret void > ?} > > -declare i32 @foo(...) > +; CHECK: @bar3 > +; CHECK: callq > +; CHECK-NOT: movzbl > +; CHECK-NOT: and > +; CHECK: ret > +define zeroext i1 @bar3() nounwind ssp { > +entry: > + ?%call = call i1 @foo2() nounwind > + ?ret i1 %call > +} > + > +declare i32 @foo1(...) > +declare zeroext i1 @foo2() > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From kledzik at apple.com Wed Mar 16 19:09:13 2011 From: kledzik at apple.com (Nick Kledzik) Date: Thu, 17 Mar 2011 00:09:13 -0000 Subject: [llvm-commits] [compiler-rt] r127778 - in /compiler-rt/trunk: README.txt lib/divmodsi4.c lib/udivmodsi4.c make/platform/darwin_bni.mk test/Unit/divmodsi4_test.c test/Unit/udivmodsi4_test.c Message-ID: <20110317000913.CB29E2A6C12C@llvm.org> Author: kledzik Date: Wed Mar 16 19:09:13 2011 New Revision: 127778 URL: http://llvm.org/viewvc/llvm-project?rev=127778&view=rev Log: implement udivmodsi4 and divmodsi4 for ARM Added: compiler-rt/trunk/lib/divmodsi4.c compiler-rt/trunk/lib/udivmodsi4.c compiler-rt/trunk/test/Unit/divmodsi4_test.c compiler-rt/trunk/test/Unit/udivmodsi4_test.c Modified: compiler-rt/trunk/README.txt compiler-rt/trunk/make/platform/darwin_bni.mk Modified: compiler-rt/trunk/README.txt URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/README.txt?rev=127778&r1=127777&r2=127778&view=diff ============================================================================== --- compiler-rt/trunk/README.txt (original) +++ compiler-rt/trunk/README.txt Wed Mar 16 19:09:13 2011 @@ -77,8 +77,12 @@ su_int __umodsi3 (su_int a, su_int b); // a % b unsigned du_int __umoddi3 (du_int a, du_int b); // a % b unsigned tu_int __umodti3 (tu_int a, tu_int b); // a % b unsigned -du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b -tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); // a / b, *rem = a % b +du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b unsigned +tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); // a / b, *rem = a % b unsigned +su_int __udivmodsi4(su_int a, su_int b, su_int* rem); // a / b, *rem = a % b unsigned +si_int __divmodsi4(si_int a, si_int b, si_int* rem); // a / b, *rem = a % b signed + + // Integral arithmetic with trapping overflow Added: compiler-rt/trunk/lib/divmodsi4.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/divmodsi4.c?rev=127778&view=auto ============================================================================== --- compiler-rt/trunk/lib/divmodsi4.c (added) +++ compiler-rt/trunk/lib/divmodsi4.c Wed Mar 16 19:09:13 2011 @@ -0,0 +1,30 @@ +/*===-- divmodsi4.c - Implement __divmodsi4 --------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __divmodsi4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +#include "int_lib.h" + +extern si_int __divsi3(si_int a, si_int b); + + +/* Returns: a / b, *rem = a % b */ + +si_int +__divmodsi4(si_int a, si_int b, si_int* rem) +{ + si_int d = __divsi3(a,b); + *rem = a - (d*b); + return d; +} + + Added: compiler-rt/trunk/lib/udivmodsi4.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/udivmodsi4.c?rev=127778&view=auto ============================================================================== --- compiler-rt/trunk/lib/udivmodsi4.c (added) +++ compiler-rt/trunk/lib/udivmodsi4.c Wed Mar 16 19:09:13 2011 @@ -0,0 +1,30 @@ +/*===-- udivmodsi4.c - Implement __udivmodsi4 ------------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file implements __udivmodsi4 for the compiler_rt library. + * + * ===----------------------------------------------------------------------=== + */ + +#include "int_lib.h" + +extern su_int __udivsi3(su_int n, su_int d); + + +/* Returns: a / b, *rem = a % b */ + +su_int +__udivmodsi4(su_int a, su_int b, su_int* rem) +{ + si_int d = __udivsi3(a,b); + *rem = a - (d*b); + return d; +} + + Modified: compiler-rt/trunk/make/platform/darwin_bni.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/make/platform/darwin_bni.mk?rev=127778&r1=127777&r2=127778&view=diff ============================================================================== --- compiler-rt/trunk/make/platform/darwin_bni.mk (original) +++ compiler-rt/trunk/make/platform/darwin_bni.mk Wed Mar 16 19:09:13 2011 @@ -61,10 +61,10 @@ muldf3 mulsf3 \ negdf2 negsf2 \ truncdfsf2 \ - modsi3 umodsi3 udivsi3 divsi3 \ + modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4 \ switch8 switchu8 switch16 switch32 \ sync_synchronize - + FUNCTIONS.armv6 := $(FUNCTIONS) \ comparedf2 comparesf2 \ adddf3vfp addsf3vfp bswapdi2 bswapsi2 divdf3vfp \ @@ -76,10 +76,11 @@ muldf3vfp mulsf3vfp \ nedf2vfp nesf2vfp \ subdf3vfp subsf3vfp truncdfsf2vfp unorddf2vfp unordsf2vfp \ - modsi3 umodsi3 udivsi3 divsi3 \ + modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4 \ switch8 switchu8 switch16 switch32 \ restore_vfp_d8_d15_regs save_vfp_d8_d15_regs \ sync_synchronize + FUNCTIONS.armv7 := $(FUNCTIONS) \ comparedf2 comparesf2 \ adddf3vfp addsf3vfp bswapdi2 bswapsi2 divdf3vfp \ @@ -91,5 +92,5 @@ muldf3vfp mulsf3vfp \ nedf2vfp nesf2vfp \ subdf3vfp subsf3vfp truncdfsf2vfp unorddf2vfp unordsf2vfp \ - modsi3 umodsi3 udivsi3 divsi3 + modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4 Added: compiler-rt/trunk/test/Unit/divmodsi4_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/divmodsi4_test.c?rev=127778&view=auto ============================================================================== --- compiler-rt/trunk/test/Unit/divmodsi4_test.c (added) +++ compiler-rt/trunk/test/Unit/divmodsi4_test.c Wed Mar 16 19:09:13 2011 @@ -0,0 +1,73 @@ +//===-- divmodsi4_test.c - Test __divmodsi4 -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __divmodsi4 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include "int_lib.h" +#include + +// Returns: a / b + +extern si_int __divmodsi4(si_int a, si_int b, si_int* rem); + + +int test__divmodsi4(si_int a, si_int b, + si_int expected_result, si_int expected_rem) +{ + si_int rem; + si_int result = __divmodsi4(a, b, &rem); + if (result != expected_result) { + printf("error in __divmodsi4: %d / %d = %d, expected %d\n", + a, b, result, expected_result); + return 1; + } + if (rem != expected_rem) { + printf("error in __divmodsi4: %d mod %d = %d, expected %d\n", + a, b, rem, expected_rem); + return 1; + } + + return 0; +} + + +int main() +{ + if (test__divmodsi4(0, 1, 0, 0)) + return 1; + if (test__divmodsi4(0, -1, 0, 0)) + return 1; + + if (test__divmodsi4(2, 1, 2, 0)) + return 1; + if (test__divmodsi4(2, -1, -2, 0)) + return 1; + if (test__divmodsi4(-2, 1, -2, 0)) + return 1; + if (test__divmodsi4(-2, -1, 2, 0)) + return 1; + + if (test__divmodsi4(7, 5, 1, 2)) + return 1; + if (test__divmodsi4(-7, 5, -1, -2)) + return 1; + if (test__divmodsi4(19, 5, 3, 4)) + return 1; + if (test__divmodsi4(19, -5, -3, 4)) + return 1; + + if (test__divmodsi4(0x80000000, 8, 0xf0000000, 0)) + return 1; + if (test__divmodsi4(0x80000007, 8, 0xf0000001, -1)) + return 1; + + return 0; +} Added: compiler-rt/trunk/test/Unit/udivmodsi4_test.c URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/Unit/udivmodsi4_test.c?rev=127778&view=auto ============================================================================== --- compiler-rt/trunk/test/Unit/udivmodsi4_test.c (added) +++ compiler-rt/trunk/test/Unit/udivmodsi4_test.c Wed Mar 16 19:09:13 2011 @@ -0,0 +1,59 @@ +//===-- udivmodsi4_test.c - Test __udivmodsi4 -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __udivmodsi4 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include "int_lib.h" +#include + +// Returns: a / b + +extern su_int __udivmodsi4(su_int a, su_int b, su_int* rem); + +int test__udivmodsi4(su_int a, su_int b, + su_int expected_result, su_int expected_rem) +{ + su_int rem; + su_int result = __udivmodsi4(a, b, &rem); + if (result != expected_result) { + printf("error in __udivmodsi4: %u / %u = %u, expected %u\n", + a, b, result, expected_result); + return 1; + } + if (rem != expected_rem) { + printf("error in __udivmodsi4: %u mod %u = %u, expected %u\n", + a, b, rem, expected_rem); + return 1; + } + + return 0; +} + + +int main() +{ + if (test__udivmodsi4(0, 1, 0, 0)) + return 1; + + if (test__udivmodsi4(2, 1, 2, 0)) + return 1; + + if (test__udivmodsi4(19, 5, 3, 4)) + return 1; + + if (test__udivmodsi4(0x80000000, 8, 0x10000000, 0)) + return 1; + + if (test__udivmodsi4(0x80000003, 8, 0x10000000, 3)) + return 1; + + return 0; +} From steinke.dirk.ml at googlemail.com Wed Mar 16 19:13:41 2011 From: steinke.dirk.ml at googlemail.com (Dirk Steinke) Date: Thu, 17 Mar 2011 01:13:41 +0100 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors In-Reply-To: References: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> <4D812501.9020808@gmail.com> <1BC27846-E3EC-4EDA-AB97-D25D902C5C4C@apple.com> <4D8139E3.3010208@gmail.com> Message-ID: <4D815235.2060106@gmail.com> On 03/16/2011 11:40 PM, Stephen Canon wrote: > On Mar 16, 2011, at 3:29 PM, Dirk Steinke wrote: > > [snip] >> SINT_TO_FP(high 31 bits) * (2) + SINT_TO_FP(low 1 bit) > > This actually suffers from the same problem; 0x81000081 rounds to 0x81000000 instead of 0x81000100 as it should. > > In order to work properly, an int->float conversion needs to consist of a sum of two values, both of which are guaranteed to have been converted without rounding. There are tricks (sticky bits) that can be used to simplify this somewhat in more extreme cases (like uint64_t -> float), but generally you need each of the components to be built from fewer bits than the precision of the floating-point type. > > - Steve The way I see it, you can still simplify, if you know that the rounding is correct in the first place. That is, if the msb or lsb of the integer is zero, you can use a single SINT_TO_FP. (If the msb is zero, UINT_TO_FP is the same as SINT_TO_FP. If the lsb is zero, SRL by 1, SINT_TO_FP and FADD to double the number should work. Correct me if I'm wrong - again. :) Unfortunately, for a vector, you have to prove that all msbs or all lsbs of the elements are zero. Tricky. If the integers are fed from memory, the original value range information is probably already lost... Well, thanks for the enlightening discussion. Dirk From evan.cheng at apple.com Wed Mar 16 19:17:58 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 16 Mar 2011 17:17:58 -0700 Subject: [llvm-commits] [llvm] r127766 - in /llvm/trunk: docs/LangRef.html include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/bool-zext.ll In-Reply-To: <20110316222019.528DA2A6C12C@llvm.org> References: <20110316222019.528DA2A6C12C@llvm.org> Message-ID: Thanks. But I am not crazy about getTypeForExtendedInteger(). Can you name it better so it's clear it's used for argument passing and return values? Evan On Mar 16, 2011, at 3:20 PM, Cameron Zwarich wrote: > Author: zwarich > Date: Wed Mar 16 17:20:18 2011 > New Revision: 127766 > > URL: http://llvm.org/viewvc/llvm-project?rev=127766&view=rev > Log: > The x86-64 ABI says that a bool is only guaranteed to be sign-extended to a byte > rather than an int. Thankfully, this only causes LLVM to miss optimizations, not > generate incorrect code. > > This just fixes the zext at the return. We still insert an i32 ZextAssert when > reading a function's arguments, but it is followed by a truncate and another i8 > ZextAssert so it is not optimized. > > Modified: > llvm/trunk/docs/LangRef.html > llvm/trunk/include/llvm/Target/TargetLowering.h > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > llvm/trunk/lib/Target/X86/X86ISelLowering.h > llvm/trunk/test/CodeGen/X86/bool-zext.ll > > Modified: llvm/trunk/docs/LangRef.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/docs/LangRef.html (original) > +++ llvm/trunk/docs/LangRef.html Wed Mar 16 17:20:18 2011 > @@ -1017,8 +1017,9 @@ >
>
zeroext
>
This indicates to the code generator that the parameter or return value > - should be zero-extended to a 32-bit value by the caller (for a parameter) > - or the callee (for a return value).
> + should be zero-extended to the extent required by the target's ABI (which > + is usually 32-bits, but is 8-bits for a i1 on x86-64) by the caller (for a > + parameter) or the callee (for a return value).
> >
signext
>
This indicates to the code generator that the parameter or return value > > Modified: llvm/trunk/include/llvm/Target/TargetLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) > +++ llvm/trunk/include/llvm/Target/TargetLowering.h Wed Mar 16 17:20:18 2011 > @@ -1287,6 +1287,17 @@ > return false; > } > > + /// getTypeForExtendedInteger - Return the type that should be used to zero or > + /// sign extend a zeroext/signext integer argument or return value. > + /// FIXME: Most C calling convention requires the return type to be promoted, > + /// but this is not true all the time, e.g. i1 on x86-64. It is also not > + /// necessary for non-C calling conventions. The frontend should handle this > + /// and include all of the necessary information. > + virtual MVT > + getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const { > + return MVT::i32; > + } > + > /// LowerOperationWrapper - This callback is invoked by the type legalizer > /// to legalize nodes with an illegal operand type but legal result types. > /// It replaces the LowerOperation callback in the type Legalizer. > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Mar 16 17:20:18 2011 > @@ -1128,12 +1128,9 @@ > else if (F->paramHasAttr(0, Attribute::ZExt)) > ExtendKind = ISD::ZERO_EXTEND; > > - // FIXME: C calling convention requires the return type to be promoted > - // to at least 32-bit. But this is not necessary for non-C calling > - // conventions. The frontend should mark functions whose return values > - // require promoting with signext or zeroext attributes. > if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { > - EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32); > + MVT ReturnMVT = TLI.getTypeForExtendedInteger(VT, ExtendKind); > + EVT MinVT = TLI.getRegisterType(*DAG.getContext(), ReturnMVT); > if (VT.bitsLT(MinVT)) > VT = MinVT; > } > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Mar 16 17:20:18 2011 > @@ -1448,6 +1448,15 @@ > return HasRet; > } > > +MVT > +X86TargetLowering::getTypeForExtendedInteger(EVT VT, > + ISD::NodeType ExtendKind) const { > + // TODO: Is this also valid on 32-bit? > + if (Subtarget->is64Bit() && VT == MVT::i1 && ExtendKind == ISD::ZERO_EXTEND) > + return MVT::i8; > + return MVT::i32; > +} > + > /// LowerCallResult - Lower the result values of a call into the > /// appropriate copies out of appropriate physical registers. > /// > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Mar 16 17:20:18 2011 > @@ -843,6 +843,9 @@ > > virtual bool isUsedByReturnOnly(SDNode *N) const; > > + virtual MVT > + getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const; > + > virtual bool > CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, > const SmallVectorImpl &Outs, > > Modified: llvm/trunk/test/CodeGen/X86/bool-zext.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-zext.ll?rev=127766&r1=127765&r2=127766&view=diff > ============================================================================== > --- llvm/trunk/test/CodeGen/X86/bool-zext.ll (original) > +++ llvm/trunk/test/CodeGen/X86/bool-zext.ll Wed Mar 16 17:20:18 2011 > @@ -6,7 +6,7 @@ > define void @bar1(i1 zeroext %v1) nounwind ssp { > entry: > %conv = zext i1 %v1 to i32 > - %call = tail call i32 (...)* @foo(i32 %conv) nounwind > + %call = tail call i32 (...)* @foo1(i32 %conv) nounwind > ret void > } > > @@ -16,8 +16,20 @@ > define void @bar2(i8 zeroext %v1) nounwind ssp { > entry: > %conv = zext i8 %v1 to i32 > - %call = tail call i32 (...)* @foo(i32 %conv) nounwind > + %call = tail call i32 (...)* @foo1(i32 %conv) nounwind > ret void > } > > -declare i32 @foo(...) > +; CHECK: @bar3 > +; CHECK: callq > +; CHECK-NOT: movzbl > +; CHECK-NOT: and > +; CHECK: ret > +define zeroext i1 @bar3() nounwind ssp { > +entry: > + %call = call i1 @foo2() nounwind > + ret i1 %call > +} > + > +declare i32 @foo1(...) > +declare zeroext i1 @foo2() > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From zwarich at apple.com Wed Mar 16 19:26:50 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Wed, 16 Mar 2011 17:26:50 -0700 Subject: [llvm-commits] [llvm] r127766 - in /llvm/trunk: docs/LangRef.html include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/bool-zext.ll In-Reply-To: References: <20110316222019.528DA2A6C12C@llvm.org> Message-ID: <8A7FD4AF-059E-4351-98B9-B4B0205BD4CA@apple.com> I am not too crazy about the name either. I originally had it named something return-specific (since my patch is return-specific), but remembered it also applies to the argument case. Anyone have any suggestions? I will try to think about it and change it to something better... Cameron On Mar 16, 2011, at 5:17 PM, Evan Cheng wrote: > Thanks. But I am not crazy about getTypeForExtendedInteger(). Can you name it better so it's clear it's used for argument passing and return values? > > Evan > > On Mar 16, 2011, at 3:20 PM, Cameron Zwarich wrote: > >> Author: zwarich >> Date: Wed Mar 16 17:20:18 2011 >> New Revision: 127766 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127766&view=rev >> Log: >> The x86-64 ABI says that a bool is only guaranteed to be sign-extended to a byte >> rather than an int. Thankfully, this only causes LLVM to miss optimizations, not >> generate incorrect code. >> >> This just fixes the zext at the return. We still insert an i32 ZextAssert when >> reading a function's arguments, but it is followed by a truncate and another i8 >> ZextAssert so it is not optimized. >> >> Modified: >> llvm/trunk/docs/LangRef.html >> llvm/trunk/include/llvm/Target/TargetLowering.h >> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp >> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp >> llvm/trunk/lib/Target/X86/X86ISelLowering.h >> llvm/trunk/test/CodeGen/X86/bool-zext.ll >> >> Modified: llvm/trunk/docs/LangRef.html >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=127766&r1=127765&r2=127766&view=diff >> ============================================================================== >> --- llvm/trunk/docs/LangRef.html (original) >> +++ llvm/trunk/docs/LangRef.html Wed Mar 16 17:20:18 2011 >> @@ -1017,8 +1017,9 @@ >>
>>
zeroext
>>
This indicates to the code generator that the parameter or return value >> - should be zero-extended to a 32-bit value by the caller (for a parameter) >> - or the callee (for a return value).
>> + should be zero-extended to the extent required by the target's ABI (which >> + is usually 32-bits, but is 8-bits for a i1 on x86-64) by the caller (for a >> + parameter) or the callee (for a return value).
>> >>
signext
>>
This indicates to the code generator that the parameter or return value >> >> Modified: llvm/trunk/include/llvm/Target/TargetLowering.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127766&r1=127765&r2=127766&view=diff >> ============================================================================== >> --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) >> +++ llvm/trunk/include/llvm/Target/TargetLowering.h Wed Mar 16 17:20:18 2011 >> @@ -1287,6 +1287,17 @@ >> return false; >> } >> >> + /// getTypeForExtendedInteger - Return the type that should be used to zero or >> + /// sign extend a zeroext/signext integer argument or return value. >> + /// FIXME: Most C calling convention requires the return type to be promoted, >> + /// but this is not true all the time, e.g. i1 on x86-64. It is also not >> + /// necessary for non-C calling conventions. The frontend should handle this >> + /// and include all of the necessary information. >> + virtual MVT >> + getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const { >> + return MVT::i32; >> + } >> + >> /// LowerOperationWrapper - This callback is invoked by the type legalizer >> /// to legalize nodes with an illegal operand type but legal result types. >> /// It replaces the LowerOperation callback in the type Legalizer. >> >> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=127766&r1=127765&r2=127766&view=diff >> ============================================================================== >> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) >> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Mar 16 17:20:18 2011 >> @@ -1128,12 +1128,9 @@ >> else if (F->paramHasAttr(0, Attribute::ZExt)) >> ExtendKind = ISD::ZERO_EXTEND; >> >> - // FIXME: C calling convention requires the return type to be promoted >> - // to at least 32-bit. But this is not necessary for non-C calling >> - // conventions. The frontend should mark functions whose return values >> - // require promoting with signext or zeroext attributes. >> if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { >> - EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32); >> + MVT ReturnMVT = TLI.getTypeForExtendedInteger(VT, ExtendKind); >> + EVT MinVT = TLI.getRegisterType(*DAG.getContext(), ReturnMVT); >> if (VT.bitsLT(MinVT)) >> VT = MinVT; >> } >> >> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127766&r1=127765&r2=127766&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) >> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Mar 16 17:20:18 2011 >> @@ -1448,6 +1448,15 @@ >> return HasRet; >> } >> >> +MVT >> +X86TargetLowering::getTypeForExtendedInteger(EVT VT, >> + ISD::NodeType ExtendKind) const { >> + // TODO: Is this also valid on 32-bit? >> + if (Subtarget->is64Bit() && VT == MVT::i1 && ExtendKind == ISD::ZERO_EXTEND) >> + return MVT::i8; >> + return MVT::i32; >> +} >> + >> /// LowerCallResult - Lower the result values of a call into the >> /// appropriate copies out of appropriate physical registers. >> /// >> >> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127766&r1=127765&r2=127766&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) >> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Mar 16 17:20:18 2011 >> @@ -843,6 +843,9 @@ >> >> virtual bool isUsedByReturnOnly(SDNode *N) const; >> >> + virtual MVT >> + getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const; >> + >> virtual bool >> CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, >> const SmallVectorImpl &Outs, >> >> Modified: llvm/trunk/test/CodeGen/X86/bool-zext.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bool-zext.ll?rev=127766&r1=127765&r2=127766&view=diff >> ============================================================================== >> --- llvm/trunk/test/CodeGen/X86/bool-zext.ll (original) >> +++ llvm/trunk/test/CodeGen/X86/bool-zext.ll Wed Mar 16 17:20:18 2011 >> @@ -6,7 +6,7 @@ >> define void @bar1(i1 zeroext %v1) nounwind ssp { >> entry: >> %conv = zext i1 %v1 to i32 >> - %call = tail call i32 (...)* @foo(i32 %conv) nounwind >> + %call = tail call i32 (...)* @foo1(i32 %conv) nounwind >> ret void >> } >> >> @@ -16,8 +16,20 @@ >> define void @bar2(i8 zeroext %v1) nounwind ssp { >> entry: >> %conv = zext i8 %v1 to i32 >> - %call = tail call i32 (...)* @foo(i32 %conv) nounwind >> + %call = tail call i32 (...)* @foo1(i32 %conv) nounwind >> ret void >> } >> >> -declare i32 @foo(...) >> +; CHECK: @bar3 >> +; CHECK: callq >> +; CHECK-NOT: movzbl >> +; CHECK-NOT: and >> +; CHECK: ret >> +define zeroext i1 @bar3() nounwind ssp { >> +entry: >> + %call = call i1 @foo2() nounwind >> + ret i1 %call >> +} >> + >> +declare i32 @foo1(...) >> +declare zeroext i1 @foo2() >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From stoklund at 2pi.dk Wed Mar 16 19:23:46 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 17 Mar 2011 00:23:46 -0000 Subject: [llvm-commits] [llvm] r127779 - in /llvm/trunk: include/llvm/CodeGen/LiveInterval.h lib/CodeGen/LiveInterval.cpp lib/CodeGen/SplitKit.cpp lib/CodeGen/SplitKit.h Message-ID: <20110317002346.2132C2A6C12C@llvm.org> Author: stoklund Date: Wed Mar 16 19:23:45 2011 New Revision: 127779 URL: http://llvm.org/viewvc/llvm-project?rev=127779&view=rev Log: Rewrite instructions as part of ConnectedVNInfoEqClasses::Distribute. Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h llvm/trunk/lib/CodeGen/LiveInterval.cpp llvm/trunk/lib/CodeGen/SplitKit.cpp llvm/trunk/lib/CodeGen/SplitKit.h Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveInterval.h?rev=127779&r1=127778&r2=127779&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveInterval.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveInterval.h Wed Mar 16 19:23:45 2011 @@ -548,8 +548,8 @@ /// } class ConnectedVNInfoEqClasses { - LiveIntervals &lis_; - IntEqClasses eqClass_; + LiveIntervals &LIS; + IntEqClasses EqClass; // Note that values a and b are connected. void Connect(unsigned a, unsigned b); @@ -557,7 +557,7 @@ unsigned Renumber(); public: - explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : lis_(lis) {} + explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {} /// Classify - Classify the values in LI into connected components. /// Return the number of connected components. @@ -565,12 +565,13 @@ /// getEqClass - Classify creates equivalence classes numbered 0..N. Return /// the equivalence class assigned the VNI. - unsigned getEqClass(const VNInfo *VNI) const { return eqClass_[VNI->id]; } + unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; } /// Distribute - Distribute values in LIV[0] into a separate LiveInterval /// for each connected component. LIV must have a LiveInterval for each /// connected component. The LiveIntervals in Liv[1..] must be empty. - void Distribute(LiveInterval *LIV[]); + /// Instructions using LIV[0] are rewritten. + void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI); }; Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveInterval.cpp?rev=127779&r1=127778&r2=127779&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveInterval.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveInterval.cpp Wed Mar 16 19:23:45 2011 @@ -719,8 +719,8 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) { // Create initial equivalence classes. - eqClass_.clear(); - eqClass_.grow(LI->getNumValNums()); + EqClass.clear(); + EqClass.grow(LI->getNumValNums()); const VNInfo *used = 0, *unused = 0; @@ -731,48 +731,65 @@ // Group all unused values into one class. if (VNI->isUnused()) { if (unused) - eqClass_.join(unused->id, VNI->id); + EqClass.join(unused->id, VNI->id); unused = VNI; continue; } used = VNI; if (VNI->isPHIDef()) { - const MachineBasicBlock *MBB = lis_.getMBBFromIndex(VNI->def); + const MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def); assert(MBB && "Phi-def has no defining MBB"); // Connect to values live out of predecessors. for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) if (const VNInfo *PVNI = - LI->getVNInfoAt(lis_.getMBBEndIdx(*PI).getPrevSlot())) - eqClass_.join(VNI->id, PVNI->id); + LI->getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot())) + EqClass.join(VNI->id, PVNI->id); } else { // Normal value defined by an instruction. Check for two-addr redef. // FIXME: This could be coincidental. Should we really check for a tied // operand constraint? // Note that VNI->def may be a use slot for an early clobber def. if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getPrevSlot())) - eqClass_.join(VNI->id, UVNI->id); + EqClass.join(VNI->id, UVNI->id); } } // Lump all the unused values in with the last used value. if (used && unused) - eqClass_.join(used->id, unused->id); + EqClass.join(used->id, unused->id); - eqClass_.compress(); - return eqClass_.getNumClasses(); + EqClass.compress(); + return EqClass.getNumClasses(); } -void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) { +void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[], + MachineRegisterInfo &MRI) { assert(LIV[0] && "LIV[0] must be set"); LiveInterval &LI = *LIV[0]; - // First move runs to new intervals. + // Rewrite instructions. + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg), + RE = MRI.reg_end(); RI != RE;) { + MachineOperand &MO = RI.getOperand(); + MachineInstr *MI = MO.getParent(); + ++RI; + if (MO.isUse() && MO.isUndef()) + continue; + // DBG_VALUE instructions should have been eliminated earlier. + SlotIndex Idx = LIS.getInstructionIndex(MI); + Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex(); + const VNInfo *VNI = LI.getVNInfoAt(Idx); + assert(VNI && "Interval not live at use."); + MO.setReg(LIV[getEqClass(VNI)]->reg); + } + + // Move runs to new intervals. LiveInterval::iterator J = LI.begin(), E = LI.end(); - while (J != E && eqClass_[J->valno->id] == 0) + while (J != E && EqClass[J->valno->id] == 0) ++J; for (LiveInterval::iterator I = J; I != E; ++I) { - if (unsigned eq = eqClass_[I->valno->id]) { + if (unsigned eq = EqClass[I->valno->id]) { assert((LIV[eq]->empty() || LIV[eq]->expiredAt(I->start)) && "New intervals should be empty"); LIV[eq]->ranges.push_back(*I); @@ -783,11 +800,11 @@ // Transfer VNInfos to their new owners and renumber them. unsigned j = 0, e = LI.getNumValNums(); - while (j != e && eqClass_[j] == 0) + while (j != e && EqClass[j] == 0) ++j; for (unsigned i = j; i != e; ++i) { VNInfo *VNI = LI.getValNumInfo(i); - if (unsigned eq = eqClass_[i]) { + if (unsigned eq = EqClass[i]) { VNI->id = LIV[eq]->getNumValNums(); LIV[eq]->valnos.push_back(VNI); } else { Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=127779&r1=127778&r2=127779&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Wed Mar 16 19:23:45 2011 @@ -771,28 +771,6 @@ } } -/// rewriteSplit - Rewrite uses of Intvs[0] according to the ConEQ mapping. -void SplitEditor::rewriteComponents(const SmallVectorImpl &Intvs, - const ConnectedVNInfoEqClasses &ConEq) { - for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Intvs[0]->reg), - RE = MRI.reg_end(); RI != RE;) { - MachineOperand &MO = RI.getOperand(); - MachineInstr *MI = MO.getParent(); - ++RI; - if (MO.isUse() && MO.isUndef()) - continue; - // DBG_VALUE instructions should have been eliminated earlier. - SlotIndex Idx = LIS.getInstructionIndex(MI); - Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex(); - DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t' - << Idx << ':'); - const VNInfo *VNI = Intvs[0]->getVNInfoAt(Idx); - assert(VNI && "Interval not live at use."); - MO.setReg(Intvs[ConEq.getEqClass(VNI)]->reg); - DEBUG(dbgs() << VNI->id << '\t' << *MI); - } -} - void SplitEditor::deleteRematVictims() { SmallVector Dead; for (LiveInterval::const_vni_iterator I = Edit->getParent().vni_begin(), @@ -889,8 +867,7 @@ dups.push_back(li); for (unsigned i = 1; i != NumComp; ++i) dups.push_back(&Edit->create(MRI, LIS, VRM)); - rewriteComponents(dups, ConEQ); - ConEQ.Distribute(&dups[0]); + ConEQ.Distribute(&dups[0], MRI); } // Calculate spill weight and allocation hints for new intervals. Modified: llvm/trunk/lib/CodeGen/SplitKit.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.h?rev=127779&r1=127778&r2=127779&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.h (original) +++ llvm/trunk/lib/CodeGen/SplitKit.h Wed Mar 16 19:23:45 2011 @@ -265,13 +265,6 @@ /// rewriteAssigned - Rewrite all uses of Edit.getReg() to assigned registers. void rewriteAssigned(bool ExtendRanges); - /// rewriteComponents - Rewrite all uses of Intv[0] according to the eq - /// classes in ConEQ. - /// This must be done when Intvs[0] is styill live at all uses, before calling - /// ConEq.Distribute(). - void rewriteComponents(const SmallVectorImpl &Intvs, - const ConnectedVNInfoEqClasses &ConEq); - /// deleteRematVictims - Delete defs that are dead after rematerializing. void deleteRematVictims(); From joerg at bec.de Wed Mar 16 19:35:10 2011 From: joerg at bec.de (Joerg Sonnenberger) Date: Thu, 17 Mar 2011 00:35:10 -0000 Subject: [llvm-commits] [llvm] r127780 - in /llvm/trunk: lib/MC/MCELFStreamer.cpp test/MC/ELF/tls-i386.s Message-ID: <20110317003510.4074D2A6C12C@llvm.org> Author: joerg Date: Wed Mar 16 19:35:10 2011 New Revision: 127780 URL: http://llvm.org/viewvc/llvm-project?rev=127780&view=rev Log: Fix handling of @IDNTPOFF relocations, they need to get STT_TLS. While here, add VK_ARM_TPOFF and VK_ARM_GOTTPOFF, too. Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp llvm/trunk/test/MC/ELF/tls-i386.s Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=127780&r1=127779&r2=127780&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCELFStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCELFStreamer.cpp Wed Mar 16 19:35:10 2011 @@ -291,15 +291,18 @@ switch (symRef.getKind()) { default: return; + case MCSymbolRefExpr::VK_GOTTPOFF: + case MCSymbolRefExpr::VK_INDNTPOFF: case MCSymbolRefExpr::VK_NTPOFF: case MCSymbolRefExpr::VK_GOTNTPOFF: case MCSymbolRefExpr::VK_TLSGD: + case MCSymbolRefExpr::VK_TLSLD: case MCSymbolRefExpr::VK_TLSLDM: case MCSymbolRefExpr::VK_TPOFF: case MCSymbolRefExpr::VK_DTPOFF: - case MCSymbolRefExpr::VK_GOTTPOFF: - case MCSymbolRefExpr::VK_TLSLD: case MCSymbolRefExpr::VK_ARM_TLSGD: + case MCSymbolRefExpr::VK_ARM_TPOFF: + case MCSymbolRefExpr::VK_ARM_GOTTPOFF: break; } MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol()); Modified: llvm/trunk/test/MC/ELF/tls-i386.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/tls-i386.s?rev=127780&r1=127779&r2=127780&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/tls-i386.s (original) +++ llvm/trunk/test/MC/ELF/tls-i386.s Wed Mar 16 19:35:10 2011 @@ -8,6 +8,7 @@ movl foo4 at TLSLDM(%eax), %eax movl foo5 at TPOFF(%eax), %eax movl foo6 at DTPOFF(%eax), %eax + movl foo7 at INDNTPOFF, %eax // CHECK: (('st_name', 0x00000001) # 'foo1' // CHECK-NEXT: ('st_value', 0x00000000) @@ -62,3 +63,12 @@ // CHECK-NEXT: ('st_other', 0x00000000) // CHECK-NEXT: ('st_shndx', 0x00000000) // CHECK-NEXT: ), +// CHECK-NEXT: # Symbol 0x0000000b +// CHECK-NEXT: (('st_name', 0x0000001f) # 'foo7' +// CHECK-NEXT: ('st_value', 0x00000000) +// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000006) +// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ), From rafael.espindola at gmail.com Wed Mar 16 19:36:11 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 17 Mar 2011 00:36:11 -0000 Subject: [llvm-commits] [llvm] r127781 - in /llvm/trunk: include/llvm-c/lto.h tools/gold/gold-plugin.cpp tools/lto/LTOModule.cpp tools/lto/LTOModule.h tools/lto/lto.cpp tools/lto/lto.exports Message-ID: <20110317003612.04FE02A6C12C@llvm.org> Author: rafael Date: Wed Mar 16 19:36:11 2011 New Revision: 127781 URL: http://llvm.org/viewvc/llvm-project?rev=127781&view=rev Log: Add support in the LTO library for loading an object from the middle of an file. Modified: llvm/trunk/include/llvm-c/lto.h llvm/trunk/tools/gold/gold-plugin.cpp llvm/trunk/tools/lto/LTOModule.cpp llvm/trunk/tools/lto/LTOModule.h llvm/trunk/tools/lto/lto.cpp llvm/trunk/tools/lto/lto.exports Modified: llvm/trunk/include/llvm-c/lto.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/lto.h?rev=127781&r1=127780&r2=127781&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/lto.h (original) +++ llvm/trunk/include/llvm-c/lto.h Wed Mar 16 19:36:11 2011 @@ -127,7 +127,15 @@ * Returns NULL on error (check lto_get_error_message() for details). */ extern lto_module_t -lto_module_create_from_fd(int fd, const char *path, off_t size); +lto_module_create_from_fd(int fd, const char *path, size_t file_size); + +/** + * Loads an object file from disk. The seek point of fd is not preserved. + * Returns NULL on error (check lto_get_error_message() for details). + */ +extern lto_module_t +lto_module_create_from_fd_at_offset(int fd, const char *path, size_t file_size, + size_t map_size, off_t offset); /** Modified: llvm/trunk/tools/gold/gold-plugin.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=127781&r1=127780&r2=127781&view=diff ============================================================================== --- llvm/trunk/tools/gold/gold-plugin.cpp (original) +++ llvm/trunk/tools/gold/gold-plugin.cpp Wed Mar 16 19:36:11 2011 @@ -235,46 +235,13 @@ if (file->offset) { // Gold has found what might be IR part-way inside of a file, such as // an .a archive. - if (lseek(file->fd, file->offset, SEEK_SET) == -1) { - (*message)(LDPL_ERROR, - "Failed to seek to archive member of %s at offset %d: %s\n", - file->name, - file->offset, sys::StrError(errno).c_str()); - return LDPS_ERR; - } - void *buf = malloc(file->filesize); - if (!buf) { - (*message)(LDPL_ERROR, - "Failed to allocate buffer for archive member of size: %d\n", - file->filesize); - return LDPS_ERR; - } - if (read(file->fd, buf, file->filesize) != file->filesize) { - (*message)(LDPL_ERROR, - "Failed to read archive member of %s at offset %d: %s\n", - file->name, - file->offset, - sys::StrError(errno).c_str()); - free(buf); - return LDPS_ERR; - } - if (!lto_module_is_object_file_in_memory(buf, file->filesize)) { - free(buf); - return LDPS_OK; - } - M = lto_module_create_from_memory(buf, file->filesize); - if (!M) { - (*message)(LDPL_ERROR, "Failed to create LLVM module: %s", - lto_get_error_message()); - return LDPS_ERR; - } - free(buf); + M = lto_module_create_from_fd_at_offset(file->fd, file->name, -1, + file->filesize, file->offset); } else { - lseek(file->fd, 0, SEEK_SET); M = lto_module_create_from_fd(file->fd, file->name, file->filesize); - if (!M) - return LDPS_OK; } + if (!M) + return LDPS_OK; *claimed = 1; Modules.resize(Modules.size() + 1); Modified: llvm/trunk/tools/lto/LTOModule.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=127781&r1=127780&r2=127781&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOModule.cpp (original) +++ llvm/trunk/tools/lto/LTOModule.cpp Wed Mar 16 19:36:11 2011 @@ -95,10 +95,19 @@ } LTOModule *LTOModule::makeLTOModule(int fd, const char *path, - off_t size, + size_t size, + std::string &errMsg) { + return makeLTOModule(fd, path, size, size, 0, errMsg); +} + +LTOModule *LTOModule::makeLTOModule(int fd, const char *path, + size_t file_size, + size_t map_size, + off_t offset, std::string &errMsg) { OwningPtr buffer; - if (error_code ec = MemoryBuffer::getOpenFile(fd, path, buffer, size)) { + if (error_code ec = MemoryBuffer::getOpenFile(fd, path, buffer, file_size, + map_size, offset, false)) { errMsg = ec.message(); return NULL; } Modified: llvm/trunk/tools/lto/LTOModule.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.h?rev=127781&r1=127780&r2=127781&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOModule.h (original) +++ llvm/trunk/tools/lto/LTOModule.h Wed Mar 16 19:36:11 2011 @@ -52,7 +52,12 @@ static LTOModule* makeLTOModule(const char* path, std::string& errMsg); static LTOModule* makeLTOModule(int fd, const char *path, - off_t size, + size_t size, + std::string& errMsg); + static LTOModule* makeLTOModule(int fd, const char *path, + size_t file_size, + size_t map_size, + off_t offset, std::string& errMsg); static LTOModule* makeLTOModule(const void* mem, size_t length, std::string& errMsg); Modified: llvm/trunk/tools/lto/lto.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=127781&r1=127780&r2=127781&view=diff ============================================================================== --- llvm/trunk/tools/lto/lto.cpp (original) +++ llvm/trunk/tools/lto/lto.cpp Wed Mar 16 19:36:11 2011 @@ -95,12 +95,25 @@ // loads an object file from disk // returns NULL on error (check lto_get_error_message() for details) // -lto_module_t lto_module_create_from_fd(int fd, const char *path, off_t size) +lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) { return LTOModule::makeLTOModule(fd, path, size, sLastErrorString); } // +// loads an object file from disk +// returns NULL on error (check lto_get_error_message() for details) +// +lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path, + size_t file_size, + size_t map_size, + off_t offset) +{ + return LTOModule::makeLTOModule(fd, path, file_size, map_size, + offset, sLastErrorString); +} + +// // loads an object file from memory // returns NULL on error (check lto_get_error_message() for details) // Modified: llvm/trunk/tools/lto/lto.exports URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.exports?rev=127781&r1=127780&r2=127781&view=diff ============================================================================== --- llvm/trunk/tools/lto/lto.exports (original) +++ llvm/trunk/tools/lto/lto.exports Wed Mar 16 19:36:11 2011 @@ -2,6 +2,7 @@ lto_get_version lto_module_create lto_module_create_from_fd +lto_module_create_from_fd_at_offset lto_module_create_from_memory lto_module_get_num_symbols lto_module_get_symbol_attribute From kledzik at apple.com Wed Mar 16 19:51:27 2011 From: kledzik at apple.com (Nick Kledzik) Date: Thu, 17 Mar 2011 00:51:27 -0000 Subject: [llvm-commits] [compiler-rt] r127784 - /compiler-rt/tags/Apple/Libcompiler_rt-13/ Message-ID: <20110317005127.851F12A6C12C@llvm.org> Author: kledzik Date: Wed Mar 16 19:51:27 2011 New Revision: 127784 URL: http://llvm.org/viewvc/llvm-project?rev=127784&view=rev Log: Libcompiler_rt-13 Added: compiler-rt/tags/Apple/Libcompiler_rt-13/ - copied from r127783, compiler-rt/trunk/ From nlewycky at google.com Wed Mar 16 19:56:50 2011 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 16 Mar 2011 17:56:50 -0700 Subject: [llvm-commits] patch: the default argument to "dmb" is "sy" Message-ID: The attached patch changes ARM MC to accept "dmb" and assemble it as "dmb sy". According to this page: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGHHIE.html that's the right thing to do. Please review! Nick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110316/685e244d/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-dmb-sy.patch Type: text/x-patch Size: 800 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110316/685e244d/attachment.bin From eli.friedman at gmail.com Wed Mar 16 20:22:09 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Thu, 17 Mar 2011 01:22:09 -0000 Subject: [llvm-commits] [llvm] r127786 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <20110317012209.AD46C2A6C12C@llvm.org> Author: efriedma Date: Wed Mar 16 20:22:09 2011 New Revision: 127786 URL: http://llvm.org/viewvc/llvm-project?rev=127786&view=rev Log: A couple new README entries. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=127786&r1=127785&r2=127786&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Wed Mar 16 20:22:09 2011 @@ -1947,3 +1947,39 @@ //===---------------------------------------------------------------------===// +For the branch in the following code: +int a(); +int b(int x, int y) { + if (x & (1<<(y&7))) + return a(); + return y; +} + +We currently generate: + movb %sil, %al + andb $7, %al + movzbl %al, %eax + btl %eax, %edi + jae .LBB0_2 + +movl+andl would be shorter than the movb+andb+movzbl sequence. + +//===---------------------------------------------------------------------===// + +For the following: +struct u1 { + float x, y; +}; +float foo(struct u1 u) { + return u.x + u.y; +} + +We currently generate: + movdqa %xmm0, %xmm1 + pshufd $1, %xmm0, %xmm0 # xmm0 = xmm0[1,0,0,0] + addss %xmm1, %xmm0 + ret + +We could save an instruction here by commuting the addss. + +//===---------------------------------------------------------------------===// From nicholas at mxc.ca Wed Mar 16 20:46:15 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 17 Mar 2011 01:46:15 -0000 Subject: [llvm-commits] [llvm] r127788 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <20110317014615.1C41D2A6C12C@llvm.org> Author: nicholas Date: Wed Mar 16 20:46:14 2011 New Revision: 127788 URL: http://llvm.org/viewvc/llvm-project?rev=127788&view=rev Log: Add "swi" which is an obsolete mnemonic for "svc". Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=127788&r1=127787&r2=127788&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Mar 16 20:46:14 2011 @@ -1531,6 +1531,7 @@ let Inst{23-0} = svc; } } +def : MnemonicAlias<"swi", "svc">; // Store Return State is a system instruction -- for disassembly only let isCodeGenOnly = 1 in { // FIXME: This should not use submode! From geek4civic at gmail.com Wed Mar 16 23:24:40 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 17 Mar 2011 04:24:40 -0000 Subject: [llvm-commits] [llvm] r127800 - /llvm/trunk/test/CodeGen/X86/h-registers-1.ll Message-ID: <20110317042440.412D72A6C12C@llvm.org> Author: chapuni Date: Wed Mar 16 23:24:40 2011 New Revision: 127800 URL: http://llvm.org/viewvc/llvm-project?rev=127800&view=rev Log: test/CodeGen/X86/h-registers-1.ll: Add explicit -mtriple=x86_64-linux. It does not need to be checked on x86_64-win32 (aka Win64). Modified: llvm/trunk/test/CodeGen/X86/h-registers-1.ll Modified: llvm/trunk/test/CodeGen/X86/h-registers-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/h-registers-1.ll?rev=127800&r1=127799&r2=127800&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/h-registers-1.ll (original) +++ llvm/trunk/test/CodeGen/X86/h-registers-1.ll Wed Mar 16 23:24:40 2011 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86-64 > %t +; RUN: llc < %s -mtriple=x86_64-linux > %t ; RUN: grep {movzbl %\[abcd\]h,} %t | count 8 ; RUN: grep {%\[abcd\]h} %t | not grep {%r\[\[:digit:\]\]*d} From geek4civic at gmail.com Wed Mar 16 23:31:56 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 17 Mar 2011 13:31:56 +0900 Subject: [llvm-commits] [llvm] r127351 - in /llvm/trunk: lib/CodeGen/SimpleRegisterCoalescing.cpp test/CodeGen/X86/2011-03-09-Physreg-Coalescing.ll test/CodeGen/X86/fold-pcmpeqd-2.ll In-Reply-To: References: <20110309192706.B181C2A6C12D@llvm.org> Message-ID: >> We can add an -mtriple argument to the test to make sure the calling convention doesn't change. The test isn't trying to test register allocation or spilling anyway. > > Ok. I will do, thank you. Committed X86/h-registers-1.ll in r127800, thank you! ...Takumi From nicholas at mxc.ca Thu Mar 17 00:20:12 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 17 Mar 2011 05:20:12 -0000 Subject: [llvm-commits] [llvm] r127801 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Message-ID: <20110317052012.C4A6B2A6C12C@llvm.org> Author: nicholas Date: Thu Mar 17 00:20:12 2011 New Revision: 127801 URL: http://llvm.org/viewvc/llvm-project?rev=127801&view=rev Log: Add comments for the demanglings. Correct mangled form of operator delete! Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=127801&r1=127800&r2=127801&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Thu Mar 17 00:20:12 2011 @@ -38,8 +38,10 @@ if (Callee == 0 || !Callee->isDeclaration()) return false; if (Callee->getName() != "malloc" && - Callee->getName() != "_Znwj" && Callee->getName() != "_Znwm" && - Callee->getName() != "_Znaj" && Callee->getName() != "_Znam") + Callee->getName() != "_Znwj" && // operator new(unsigned int) + Callee->getName() != "_Znwm" && // operator new(unsigned long) + Callee->getName() != "_Znaj" && // operator new[](unsigned int) + Callee->getName() != "_Znam") // operator new[](unsigned long) return false; // Check malloc prototype. @@ -197,8 +199,8 @@ return 0; if (Callee->getName() != "free" && - Callee->getName() != "_Zdlj" && Callee->getName() != "_Zdlm" && - Callee->getName() != "_Zdaj" && Callee->getName() != "_Zdam") + Callee->getName() != "_ZdlPv" && // operator delete(void*) + Callee->getName() != "_ZdaPv") // operator delete[](void*) return 0; // Check free prototype. From nicholas at mxc.ca Thu Mar 17 00:24:43 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 16 Mar 2011 22:24:43 -0700 Subject: [llvm-commits] [llvm] r127673 - /llvm/trunk/lib/Analysis/MemoryBuiltins.cpp In-Reply-To: <9202B122-660C-4307-953F-266BF2CA2125@googlemail.com> References: <20110315073133.23F762A6C12D@llvm.org> <9202B122-660C-4307-953F-266BF2CA2125@googlemail.com> Message-ID: <4D819B1B.4040102@mxc.ca> Benjamin Kramer wrote: > > On 15.03.2011, at 08:31, Nick Lewycky wrote: > >> Author: nicholas >> Date: Tue Mar 15 02:31:32 2011 >> New Revision: 127673 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127673&view=rev >> Log: >> Add C++ global operator {new,new[],delete,delete[]}(unsigned {int,long}) to the >> memory builtins as equivalent to malloc/free. >> >> This is different from any attribute we have. For example, you can delete the >> allocators when their result is unused, but you can't collapse two calls to the >> same function, even if no global/memory state has changed in between. The >> noalias return states that the result does not alias any other pointer, but >> instcombine optimizes malloc() as though the result is non-null for the purpose >> of eliminating unused pointers. >> >> >> Modified: >> llvm/trunk/lib/Analysis/MemoryBuiltins.cpp >> >> Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=127673&r1=127672&r2=127673&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original) >> +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Tue Mar 15 02:31:32 2011 >> @@ -35,7 +35,11 @@ >> return false; >> >> Function *Callee = CI->getCalledFunction(); >> - if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "malloc") >> + if (Callee == 0 || !Callee->isDeclaration()) >> + return false; >> + if (Callee->getName() != "malloc"&& >> + Callee->getName() != "_Znwj"&& Callee->getName() != "_Znwm"&& >> + Callee->getName() != "_Znaj"&& Callee->getName() != "_Znam") >> return false; > > What about the nothrow versions of operator new/delete? Callers of isMallocCall expect that a true result means the Function* looks like malloc (ie., take one argument). I don't want to audit them right now, but it's a great idea TODO. >> // Check malloc prototype. >> @@ -189,7 +193,12 @@ >> if (!CI) >> return 0; >> Function *Callee = CI->getCalledFunction(); >> - if (Callee == 0 || !Callee->isDeclaration() || Callee->getName() != "free") >> + if (Callee == 0 || !Callee->isDeclaration()) >> + return 0; >> + >> + if (Callee->getName() != "free"&& >> + Callee->getName() != "_Zdlj"&& Callee->getName() != "_Zdlm"&& >> + Callee->getName() != "_Zdaj"&& Callee->getName() != "_Zdam") >> return 0; > > The signature of operator delete is "operator delete(void*)" aka _ZdlPv, not "operator delete(int)". > Comments with the demangled names would be helpful here. Doh, thanks!! I'm not sure how that got in. It looks like LLVM was optimizing delete statements in my simple test even without this, I'll have to see what more this does for me. My main motivation was "(void)new T". Nick From geek4civic at gmail.com Thu Mar 17 03:15:30 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 17 Mar 2011 17:15:30 +0900 Subject: [llvm-commits] [Review request] raw_ostream: [PR6745] Implement our floating point formatter. Message-ID: For now, it is dedicated to Win32. --- lib/Support/raw_ostream.cpp | 32 ++++++++++++++++++++++++++++++++ utils/lit/lit/TestingConfig.py | 1 - 2 files changed, 32 insertions(+), 1 deletions(-) --- I have not tested on msvc yet. Could anyone check this? ...Takumi -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-raw_ostream-PR6745-Implement-our-floating-point-.patch.txt Type: text/x-patch Size: 1944 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110317/6d3e01bf/attachment.bin From nadav.rotem at intel.com Thu Mar 17 03:38:17 2011 From: nadav.rotem at intel.com (Rotem, Nadav) Date: Thu, 17 Mar 2011 10:38:17 +0200 Subject: [llvm-commits] [PATCH] UINT_TO_FP of vectors In-Reply-To: References: <6594DDFF12B03D4E89690887C2486994027135B095@hasmsx504.ger.corp.intel.com> <4D812501.9020808@gmail.com> <1BC27846-E3EC-4EDA-AB97-D25D902C5C4C@apple.com> <4D8139E3.3010208@gmail.com> Message-ID: <6594DDFF12B03D4E89690887C2486994027135B310@hasmsx504.ger.corp.intel.com> Steve, Dirk, Thanks for the review of the patch. I have experimented with two types of conversions: 1. Conversion using two SINT_TO_FP on 16bit components [1]. 2. Conversion using a single SINT_TO_FP and adjustment of the sign bit [2]. In the patch I have implemented the first method. ICC and GCC use the second method. The second method is indeed faster, but I noticed that it is not accurate enough in some cases. I worked under the assumption that UINT_TO_FP needs to be IEEE-accurate. Nadav [1] - http://developer.apple.com/hardwaredrivers/ve/sse.html#Translation_Conv_F2I [2] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40811 -----Original Message----- From: Stephen Canon [mailto:scanon at apple.com] Sent: Thursday, March 17, 2011 00:41 To: Dirk Steinke Cc: Rotem, Nadav; llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] [PATCH] UINT_TO_FP of vectors On Mar 16, 2011, at 3:29 PM, Dirk Steinke wrote: [snip] > SINT_TO_FP(high 31 bits) * (2) + SINT_TO_FP(low 1 bit) This actually suffers from the same problem; 0x81000081 rounds to 0x81000000 instead of 0x81000100 as it should. In order to work properly, an int->float conversion needs to consist of a sum of two values, both of which are guaranteed to have been converted without rounding. There are tricks (sticky bits) that can be used to simplify this somewhat in more extreme cases (like uint64_t -> float), but generally you need each of the components to be built from fewer bits than the precision of the floating-point type. - Steve --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. From baldrick at free.fr Thu Mar 17 04:03:33 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 17 Mar 2011 09:03:33 -0000 Subject: [llvm-commits] [dragonegg] r127804 - in /dragonegg/trunk: Backend.cpp Constants.cpp Constants.h Convert.cpp Message-ID: <20110317090334.0B2992A6C12C@llvm.org> Author: baldrick Date: Thu Mar 17 04:03:33 2011 New Revision: 127804 URL: http://llvm.org/viewvc/llvm-project?rev=127804&view=rev Log: Rename ConvertConstant to ConvertInitializer and make sure that all users of this method outside of Constants.cpp make no assumptions about the type of the returned value. This gives a lot more freedom in how initializers are converted, which is needed to handle a bunch of nasty corner cases. Modified: dragonegg/trunk/Backend.cpp dragonegg/trunk/Constants.cpp dragonegg/trunk/Constants.h dragonegg/trunk/Convert.cpp Modified: dragonegg/trunk/Backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Backend.cpp?rev=127804&r1=127803&r2=127804&view=diff ============================================================================== --- dragonegg/trunk/Backend.cpp (original) +++ dragonegg/trunk/Backend.cpp Thu Mar 17 04:03:33 2011 @@ -1020,7 +1020,7 @@ // When constructing the initializer it might refer to itself. // This can happen for things like void *G = &G; GV->setInitializer(UndefValue::get(GV->getType()->getElementType())); - Init = ConvertConstant(DECL_INITIAL(decl)); + Init = ConvertInitializer(DECL_INITIAL(decl)); } // If we had a forward definition that has a type that disagrees with our Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=127804&r1=127803&r2=127804&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Thu Mar 17 04:03:33 2011 @@ -28,6 +28,7 @@ // LLVM headers #include "llvm/GlobalVariable.h" #include "llvm/LLVMContext.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Host.h" #include "llvm/Target/TargetData.h" @@ -51,6 +52,342 @@ static LLVMContext &Context = getGlobalContext(); +/// BitSlice - A contiguous range of bits held in memory. +class BitSlice { + int First, Last; // Range [First, Last) + Constant *Contents; // May be null for an empty range. + + /// ExtendRange - Extend the slice to a wider range. All added bits are zero. + BitSlice ExtendRange(int WideFirst, int WideLast) const { + // Quick exit if the range did not actually increase. + if (WideFirst == First && WideLast == Last) + return *this; + if (WideFirst > First || WideLast < Last || WideLast <= WideFirst) { + assert(empty() && WideLast <= WideFirst && "Not an extension!"); + // The trivial case of extending an empty range to an empty range. + return BitSlice(); + } + const Type *WideTy = IntegerType::get(Context, WideLast - WideFirst); + // If the slice contains no bits then every bit of the extension is zero. + if (empty()) + return BitSlice(WideFirst, WideLast, Constant::getNullValue(WideTy)); + // Zero extend the contents to the new type; + Constant *C = TheFolder->CreateZExtOrBitCast(Contents, WideTy); + // Position the old contents correctly inside the new contents. + if (BYTES_BIG_ENDIAN && WideLast > Last) { + Constant *ShiftAmt = ConstantInt::get(C->getType(), WideLast - Last); + C = TheFolder->CreateShl(C, ShiftAmt); + } else if (!BYTES_BIG_ENDIAN && WideFirst < First) { + Constant *ShiftAmt = ConstantInt::get(C->getType(), First - WideFirst); + C = TheFolder->CreateShl(C, ShiftAmt); + } + return BitSlice(WideFirst, WideLast, C); + } + + /// ReduceRange - Reduce the slice to a smaller range. + BitSlice ReduceRange(int NarrowFirst, int NarrowLast) const { + // Quick exit if the range did not actually decrease. + if (NarrowFirst == First && NarrowLast == Last) + return *this; + // The trivial case of reducing to an empty range. + if (NarrowLast <= NarrowFirst) + return BitSlice(); + assert(NarrowFirst >= First && NarrowLast <= Last && "Not a reduction!"); + // Move the least-significant bit to the correct position. + Constant *C = Contents; + if (BYTES_BIG_ENDIAN && NarrowLast < Last) { + Constant *ShiftAmt = ConstantInt::get(C->getType(), Last - NarrowLast); + C = TheFolder->CreateLShr(C, ShiftAmt); + } else if (!BYTES_BIG_ENDIAN && NarrowFirst > First) { + Constant *ShiftAmt = ConstantInt::get(C->getType(), NarrowFirst - First); + C = TheFolder->CreateLShr(C, ShiftAmt); + } + // Truncate to the new type. + const Type *NarrowTy = IntegerType::get(Context, NarrowLast - NarrowFirst); + C = TheFolder->CreateTruncOrBitCast(C, NarrowTy); + return BitSlice(NarrowFirst, NarrowLast, C); + } + +public: + /// BitSlice - Default constructor: empty bit range. + BitSlice() : First(0), Last(0), Contents(0) {} + + /// BitSlice - Constructor for the range of bits ['first', 'last'). The bits + /// themselves are supplied in 'contents' as a constant of integer type. On + /// little-endian machines the least significant bit of 'contents corresponds + /// to the first bit of the range (aka 'first'), while on big-endian machines + /// it corresponds to the last bit of the range (aka 'last'-1). + BitSlice(int first, int last, Constant *contents) + : First(first), Last(last), Contents(contents) { + assert((empty() || isa(Contents->getType())) && + "Not an integer type!"); + assert((empty() || getBitWidth() == + Contents->getType()->getPrimitiveSizeInBits()) && + "Bitwidth mismatch!"); + } + + /// empty - Return whether the range is empty. + bool empty() const { + return Last <= First; + } + + /// getBitWidth - Return the number of bits in the range. + unsigned getBitWidth() { + return empty() ? 0 : Last - First; + } + + /// Displace - Return the result of sliding all bits by the given offset. + BitSlice Displace(int Offset) const { + return BitSlice(First + Offset, Last + Offset, Contents); + } + + /// getBits - Return the bits in the range [first, last). This range need not + /// be contained in the range of the slice, but if not then the bits outside + /// the slice get an undefined value. The bits are returned as a constant of + /// integer type. On little-endian machine the least significant bit of the + /// returned value corresponds to the first bit of the range (aka 'first'), + /// while on big-endian machines it corresponds to the last bit of the range + /// (aka 'last'-1). + Constant *getBits(int first, int last) { + assert(first < last && "Bit range is empty!"); + // Quick exit if the desired range matches that of the slice. + if (First == first && Last == last) + return Contents; + const Type *RetTy = IntegerType::get(Context, last - first); + // If the slice contains no bits then every returned bit is undefined. + if (empty()) + return UndefValue::get(RetTy); + // Extend to the convex hull of the two ranges. + int WideFirst = first < First ? first : First; + int WideLast = last > Last ? last : Last; + BitSlice Slice = ExtendRange(WideFirst, WideLast); + // Chop the slice down to the requested range. + Slice = Slice.ReduceRange(first, last); + // Now we can just return the bits contained in the slice. + return Slice.Contents; + } + + /// Merge - Join the slice with another (which must be disjoint), forming the + /// convex hull of the ranges. The bits in the range of one of the slices are + /// those of that slice. Any other bits have an undefined value. + void Merge(const BitSlice &that) { + // If the other slice is empty, the result is this slice. + if (that.empty()) + return; + // If this slice is empty, the result is the other slice. + if (empty()) { + *this = that; + return; + } + assert((that.Last <= First || that.First >= Last) && "Slices overlap!"); + // Zero extend each slice to the convex hull of the ranges. + int JoinFirst = that.First < First ? that.First : First; + int JoinLast = that.Last > Last ? that.Last : Last; + BitSlice ThisExtended = ExtendRange(JoinFirst, JoinLast); + BitSlice ThatExtended = that.ExtendRange(JoinFirst, JoinLast); + // Since the slices are disjoint and all added bits are zero they can be + // joined via a simple 'or'. + Constant *Join = TheFolder->CreateOr(ThisExtended.Contents, + ThatExtended.Contents); + *this = BitSlice(JoinFirst, JoinLast, Join); + } +}; + +/// ViewAsBits - View the given constant as a bunch of bits, i.e. as one big +/// integer. Only the bits in the range [First, Last) are needed, so there +/// is no need to supply bits outside this range though it is harmless to do +/// so. There is also no need to supply undefined bits inside this range. +static BitSlice ViewAsBits(Constant *C, int First, int Last) { + assert(First < Last && "Empty range!"); + + // Sanitize the range to make life easier in what follows. + const Type *Ty = C->getType(); + int StoreSize = getTargetData().getTypeStoreSizeInBits(Ty); + First = First < 0 ? 0 : First; + Last = Last > StoreSize ? StoreSize : Last; + + // Quick exit if it is clear that there are no bits in the range. + if (Last <= 0 || First >= StoreSize) + return BitSlice(); + assert(StoreSize > 0 && "Empty range not eliminated?"); + + switch (Ty->getTypeID()) { + default: + llvm_unreachable("Unsupported type!"); + case Type::DoubleTyID: + case Type::FloatTyID: + case Type::FP128TyID: + case Type::IntegerTyID: + case Type::PointerTyID: + case Type::PPC_FP128TyID: + case Type::X86_FP80TyID: + case Type::X86_MMXTyID: { + // Bitcast to an integer with the same number of bits and return that. + unsigned Size = Ty->getPrimitiveSizeInBits(); + const IntegerType *IntTy = IntegerType::get(Context, Size); + C = isa(Ty) ? + TheFolder->CreatePtrToInt(C, IntTy) : TheFolder->CreateBitCast(C, IntTy); + // Be careful about where the bits are placed in case this is a funky type + // like i1. If the width is a multiple of the address unit then there is + // nothing to worry about: the bits occupy the range [0, StoreSize). But + // if not then endianness matters: on big-endian machines there are padding + // bits at the start, while on little-endian machines they are at the end. + return BYTES_BIG_ENDIAN ? + BitSlice(StoreSize - Size, StoreSize, C) : BitSlice(0, Size, C); + } + + case Type::ArrayTyID: { + const ArrayType *ATy = cast(Ty); + const Type *EltTy = ATy->getElementType(); + const unsigned NumElts = ATy->getNumElements(); + const unsigned Stride = getTargetData().getTypeAllocSizeInBits(EltTy); + assert(Stride > 0 && "Store size smaller than alloc size?"); + // Elements with indices in [FirstElt, LastElt) overlap the range. + unsigned FirstElt = First / Stride; + unsigned LastElt = (Last + Stride - 1) / Stride; + assert(LastElt <= NumElts && "Store size bigger than array?"); + // Visit all elements that overlap the requested range, accumulating their + // bits in Bits. + BitSlice Bits; + for (unsigned i = FirstElt; i < LastElt; ++i) { + // Extract the element. + Constant *Elt = TheFolder->CreateExtractValue(C, &i, 1); + // View it as a bunch of bits. + BitSlice EltBits = ViewAsBits(Elt, 0, Stride); + // Add to the already known bits. + Bits.Merge(EltBits.Displace(i * Stride)); + } + return Bits; + } + + case Type::StructTyID: { + const StructType *STy = cast(Ty); + const StructLayout *SL = getTargetData().getStructLayout(STy); + // Fields with indices in [FirstIdx, LastIdx) overlap the range. + unsigned FirstIdx = SL->getElementContainingOffset((First+7)/8); + unsigned LastIdx = 1 + SL->getElementContainingOffset((Last+6)/8); + // Visit all fields that overlap the requested range, accumulating their + // bits in Bits. + BitSlice Bits; + for (unsigned i = FirstIdx; i < LastIdx; ++i) { + // Extract the field. + Constant *Field = TheFolder->CreateExtractValue(C, &i, 1); + // View it as a bunch of bits. + const Type *FieldTy = Field->getType(); + unsigned FieldStoreSize = getTargetData().getTypeStoreSizeInBits(FieldTy); + BitSlice FieldBits = ViewAsBits(Field, 0, FieldStoreSize); + // Add to the already known bits. + Bits.Merge(FieldBits.Displace(SL->getElementOffset(i)*8)); + } + return Bits; + } + + case Type::VectorTyID: { + const VectorType *VTy = cast(Ty); + const Type *EltTy = VTy->getElementType(); + const unsigned NumElts = VTy->getNumElements(); + const unsigned Stride = getTargetData().getTypeAllocSizeInBits(EltTy); + assert(Stride > 0 && "Store size smaller than alloc size?"); + // Elements with indices in [FirstElt, LastElt) overlap the range. + unsigned FirstElt = First / Stride; + unsigned LastElt = (Last + Stride - 1) / Stride; + assert(LastElt <= NumElts && "Store size bigger than vector?"); + // Visit all elements that overlap the requested range, accumulating their + // bits in Bits. + BitSlice Bits; + for (unsigned i = FirstElt; i < LastElt; ++i) { + // Extract the element. + ConstantInt *Idx = ConstantInt::get(Type::getInt32Ty(Context), i); + Constant *Elt = TheFolder->CreateExtractElement(C, Idx); + // View it as a bunch of bits. + BitSlice EltBits = ViewAsBits(Elt, 0, Stride); + // Add to the already known bits. + Bits.Merge(EltBits.Displace(i * Stride)); + } + return Bits; + } + } +} + +/// InterpretAsType - Interpret the bits of the given constant (starting from +/// StartingBit) as representing a constant of type 'Ty'. This results in the +/// same constant as you would get by storing the bits of 'C' to memory (with +/// the first bit stored being 'StartingBit') and then loading out a (constant) +/// value of type 'Ty' from the stored to memory location. +Constant *InterpretAsType(Constant *C, const Type* Ty, unsigned StartingBit) { + switch (Ty->getTypeID()) { + default: + llvm_unreachable("Unsupported type!"); + case Type::IntegerTyID: { + unsigned BitWidth = Ty->getPrimitiveSizeInBits(); + unsigned StoreSize = getTargetData().getTypeStoreSizeInBits(Ty); + // Convert the constant into a bunch of bits. Only the bits to be "loaded" + // out are needed, so rather than converting the entire constant this only + // converts enough to get all of the required bits. + BitSlice Bits = ViewAsBits(C, StartingBit, StartingBit + StoreSize); + // Extract the bits used by the integer. If the integer width is a multiple + // of the address unit then the endianness of the target doesn't matter. If + // not then the padding bits come at the start on big-endian machines and at + // the end on little-endian machines. + Bits = Bits.Displace(-StartingBit); + return BYTES_BIG_ENDIAN ? + Bits.getBits(StoreSize - BitWidth, StoreSize) : Bits.getBits(0, BitWidth); + } + + case Type::DoubleTyID: + case Type::FloatTyID: + case Type::FP128TyID: + case Type::PointerTyID: + case Type::PPC_FP128TyID: + case Type::X86_FP80TyID: + case Type::X86_MMXTyID: { + // Interpret as an integer with the same number of bits then cast back to + // the original type. + unsigned BitWidth = Ty->getPrimitiveSizeInBits(); + const IntegerType *IntTy = IntegerType::get(Context, BitWidth); + C = InterpretAsType(C, IntTy, StartingBit); + return isa(Ty) ? + TheFolder->CreateIntToPtr(C, Ty) : TheFolder->CreateBitCast(C, Ty); + } + + case Type::ArrayTyID: { + // Interpret each array element in turn. + const ArrayType *ATy = cast(Ty); + const Type *EltTy = ATy->getElementType(); + const unsigned Stride = getTargetData().getTypeAllocSizeInBits(EltTy); + const unsigned NumElts = ATy->getNumElements(); + std::vector Vals(NumElts); + for (unsigned i = 0; i != NumElts; ++i) + Vals[i] = InterpretAsType(C, EltTy, StartingBit + i*Stride); + return ConstantArray::get(ATy, Vals); // TODO: Use ArrayRef constructor. + } + + case Type::StructTyID: { + // Interpret each struct field in turn. + const StructType *STy = cast(Ty); + const StructLayout *SL = getTargetData().getStructLayout(STy); + unsigned NumElts = STy->getNumElements(); + std::vector Vals(NumElts); + for (unsigned i = 0; i != NumElts; ++i) + Vals[i] = InterpretAsType(C, STy->getElementType(i), + StartingBit + SL->getElementOffsetInBits(i)); + return ConstantStruct::get(STy, Vals); // TODO: Use ArrayRef constructor. + } + + case Type::VectorTyID: { + // Interpret each vector element in turn. + const VectorType *VTy = cast(Ty); + const Type *EltTy = VTy->getElementType(); + const unsigned Stride = getTargetData().getTypeAllocSizeInBits(EltTy); + const unsigned NumElts = VTy->getNumElements(); + SmallVector Vals(NumElts); + for (unsigned i = 0; i != NumElts; ++i) + Vals[i] = InterpretAsType(C, EltTy, StartingBit + i*Stride); + return ConstantVector::get(Vals); + } + } +} + /// EncodeExpr - Write the given expression into Buffer as it would appear in /// memory on the target (the buffer is resized to contain exactly the bytes /// written). Return the number of bytes written; this can also be obtained @@ -140,7 +477,7 @@ std::vector Elts; for (tree elt = TREE_VECTOR_CST_ELTS(exp); elt; elt = TREE_CHAIN(elt)) - Elts.push_back(ConvertConstant(TREE_VALUE(elt))); + Elts.push_back(ConvertInitializer(TREE_VALUE(elt))); // The vector should be zero filled if insufficient elements are provided. if (Elts.size() < TYPE_VECTOR_SUBPARTS(TREE_TYPE(exp))) { @@ -226,14 +563,14 @@ static Constant *ConvertCOMPLEX_CST(tree exp) { Constant *Elts[2] = { - ConvertConstant(TREE_REALPART(exp)), - ConvertConstant(TREE_IMAGPART(exp)) + ConvertInitializer(TREE_REALPART(exp)), + ConvertInitializer(TREE_IMAGPART(exp)) }; return ConstantStruct::get(Context, Elts, 2, false); } static Constant *ConvertNOP_EXPR(tree exp) { - Constant *Elt = ConvertConstant(TREE_OPERAND(exp, 0)); + Constant *Elt = ConvertInitializer(TREE_OPERAND(exp, 0)); const Type *Ty = ConvertType(TREE_TYPE(exp)); bool EltIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); bool TyIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); @@ -249,7 +586,7 @@ } static Constant *ConvertCONVERT_EXPR(tree exp) { - Constant *Elt = ConvertConstant(TREE_OPERAND(exp, 0)); + Constant *Elt = ConvertInitializer(TREE_OPERAND(exp, 0)); bool EltIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0))); const Type *Ty = ConvertType(TREE_TYPE(exp)); bool TyIsSigned = !TYPE_UNSIGNED(TREE_TYPE(exp)); @@ -259,8 +596,8 @@ } static Constant *ConvertPOINTER_PLUS_EXPR(tree exp) { - Constant *Ptr = ConvertConstant(TREE_OPERAND(exp, 0)); // The pointer. - Constant *Idx = ConvertConstant(TREE_OPERAND(exp, 1)); // The offset in bytes. + Constant *Ptr = ConvertInitializer(TREE_OPERAND(exp, 0)); // The pointer. + Constant *Idx = ConvertInitializer(TREE_OPERAND(exp, 1)); // Offset in bytes. // Convert the pointer into an i8* and add the offset to it. Ptr = TheFolder->CreateBitCast(Ptr, Type::getInt8PtrTy(Context)); @@ -273,9 +610,9 @@ } static Constant *ConvertBinOp_CST(tree exp) { - Constant *LHS = ConvertConstant(TREE_OPERAND(exp, 0)); + Constant *LHS = ConvertInitializer(TREE_OPERAND(exp, 0)); bool LHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp,0))); - Constant *RHS = ConvertConstant(TREE_OPERAND(exp, 1)); + Constant *RHS = ConvertInitializer(TREE_OPERAND(exp, 1)); bool RHSIsSigned = !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp,1))); Instruction::CastOps opcode; if (LHS->getType()->isPointerTy()) { @@ -332,7 +669,7 @@ Constant *SomeVal = 0; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), ix, elt_index, elt_value) { // Find and decode the constructor's value. - Constant *Val = ConvertConstant(elt_value); + Constant *Val = ConvertInitializer(elt_value); SomeVal = Val; // Get the index position of the element within the array. Note that this @@ -798,7 +1135,7 @@ } // Decode the field's value. - Constant *Val = ConvertConstant(FieldValue); + Constant *Val = ConvertInitializer(FieldValue); // GCCFieldOffsetInBits is where GCC is telling us to put the current field. uint64_t GCCFieldOffsetInBits = getFieldOffsetInBits(Field); @@ -870,7 +1207,7 @@ ConstantLayoutInfo LayoutInfo(getTargetData()); // Convert the constant itself. - Constant *Val = ConvertConstant(VEC_index(constructor_elt, elt, 0)->value); + Constant *Val = ConvertInitializer(VEC_index(constructor_elt, elt, 0)->value); // Unions are initialized using the first member field. Find it. tree Field = TYPE_FIELDS(TREE_TYPE(exp)); @@ -934,7 +1271,7 @@ } } -Constant *ConvertConstant(tree exp) { +Constant *ConvertInitializer(tree exp) { assert(TREE_CONSTANT(exp) && "Isn't a constant!"); switch (TREE_CODE(exp)) { case FDESC_EXPR: // Needed on itanium @@ -952,7 +1289,7 @@ case PLUS_EXPR: case MINUS_EXPR: return ConvertBinOp_CST(exp); case CONSTRUCTOR: return ConvertCONSTRUCTOR(exp); - case VIEW_CONVERT_EXPR: return ConvertConstant(TREE_OPERAND(exp, 0)); + case VIEW_CONVERT_EXPR: return ConvertInitializer(TREE_OPERAND(exp, 0)); case POINTER_PLUS_EXPR: return ConvertPOINTER_PLUS_EXPR(exp); case ADDR_EXPR: return TheFolder->CreateBitCast(AddressOf(TREE_OPERAND(exp, 0)), @@ -1070,10 +1407,10 @@ "Global with variable size?"); // First subtract the lower bound, if any, in the type of the index. - Constant *IndexVal = ConvertConstant(Index); + Constant *IndexVal = ConvertInitializer(Index); tree LowerBound = array_ref_low_bound(exp); if (!integer_zerop(LowerBound)) - IndexVal = TheFolder->CreateSub(IndexVal, ConvertConstant(LowerBound), + IndexVal = TheFolder->CreateSub(IndexVal, ConvertInitializer(LowerBound), hasNUW(TREE_TYPE(Index)), hasNSW(TREE_TYPE(Index))); @@ -1125,7 +1462,7 @@ assert(!(BITS_PER_UNIT & 7) && "Unit size not a multiple of 8 bits!"); if (TREE_OPERAND(exp, 2)) { - Offset = ConvertConstant(TREE_OPERAND(exp, 2)); + Offset = ConvertInitializer(TREE_OPERAND(exp, 2)); // At this point the offset is measured in units divided by (exactly) // (DECL_OFFSET_ALIGN / BITS_PER_UNIT). Convert to octets. unsigned factor = DECL_OFFSET_ALIGN(FieldDecl) / 8; @@ -1135,7 +1472,7 @@ factor)); } else { assert(DECL_FIELD_OFFSET(FieldDecl) && "Field offset not available!"); - Offset = ConvertConstant(DECL_FIELD_OFFSET(FieldDecl)); + Offset = ConvertInitializer(DECL_FIELD_OFFSET(FieldDecl)); // At this point the offset is measured in units. Convert to octets. unsigned factor = BITS_PER_UNIT / 8; if (factor != 1) @@ -1204,7 +1541,7 @@ break; case INDIRECT_REF: // The lvalue is just the address. - LV = ConvertConstant(TREE_OPERAND(exp, 0)); + LV = ConvertInitializer(TREE_OPERAND(exp, 0)); break; case COMPOUND_LITERAL_EXPR: // FIXME: not gimple - defined by C front-end /* This used to read Modified: dragonegg/trunk/Constants.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.h?rev=127804&r1=127803&r2=127804&view=diff ============================================================================== --- dragonegg/trunk/Constants.h (original) +++ dragonegg/trunk/Constants.h Thu Mar 17 04:03:33 2011 @@ -24,14 +24,12 @@ #ifndef DRAGONEGG_CONSTANTS_H #define DRAGONEGG_CONSTANTS_H -union tree_node; - +// Forward declarations. namespace llvm { class Constant; + class Type; } - -// Constant Expressions -extern llvm::Constant *ConvertConstant(tree_node *exp); +union tree_node; /// AddressOf - Given an expression with a constant address such as a constant, /// a global variable or a label, returns the address. The type of the returned @@ -40,4 +38,19 @@ /// (see ConvertType). extern llvm::Constant *AddressOf(tree_node *exp); +/// ConvertInitializer - Convert the initial value for a global variable to an +/// equivalent LLVM constant. Also handles constant constructors. The type of +/// the returned value may be pretty much anything. All that is guaranteed is +/// that it has the same alloc size as the original expression and has alignment +/// equal to or less than that of the original expression. +extern llvm::Constant *ConvertInitializer(tree_node *exp); + +/// InterpretAsType - Interpret the bits of the given constant (starting from +/// StartingBit) as representing a constant of type 'Ty'. This results in the +/// same constant as you would get by storing the bits of 'C' to memory (with +/// the first bit stored being 'StartingBit') and then loading out a (constant) +/// value of type 'Ty' from the stored to memory location. +extern llvm::Constant *InterpretAsType(llvm::Constant *C, const llvm::Type* Ty, + unsigned StartingBit); + #endif /* DRAGONEGG_CONSTANTS_H */ Modified: dragonegg/trunk/Convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Convert.cpp?rev=127804&r1=127803&r2=127804&view=diff ============================================================================== --- dragonegg/trunk/Convert.cpp (original) +++ dragonegg/trunk/Convert.cpp Thu Mar 17 04:03:33 2011 @@ -6005,8 +6005,20 @@ /// EmitConstantVectorConstructor - Turn the given constant CONSTRUCTOR into /// an LLVM constant of the corresponding vector register type. Constant *TreeToLLVM::EmitConstantVectorConstructor(tree reg) { - Constant *C = ConvertConstant(reg); - return Mem2Reg(C, TREE_TYPE(reg), *TheFolder); + // Get the constructor as an LLVM constant. + Constant *C = ConvertInitializer(reg); + // The constant may have pretty much any type, for example it could be a bunch + // of bytes. Extract the vector elements from the constant. + tree elt_type = TREE_TYPE (TREE_TYPE (reg)); + const Type *EltTy = GetRegType(elt_type); + unsigned NumElts = TYPE_VECTOR_SUBPARTS(TREE_TYPE(reg)); + // Get the spacing between consecutive vector elements. Obtain this from the + // GCC type in case the LLVM type is something funky like i1. + unsigned Stride = GET_MODE_BITSIZE (TYPE_MODE (elt_type)); + SmallVector Vals(NumElts); + for (unsigned i = 0; i != NumElts; ++i) + Vals[i] = InterpretAsType(C, EltTy, i*Stride); + return ConstantVector::get(Vals); } /// EmitVectorRegisterConstant - Turn the given VECTOR_CST into an LLVM constant From fvbommel at gmail.com Thu Mar 17 04:22:49 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Thu, 17 Mar 2011 10:22:49 +0100 Subject: [llvm-commits] [llvm] r127766 - in /llvm/trunk: docs/LangRef.html include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/bool-zext Message-ID: On Wed, Mar 16, 2011 at 11:20 PM, Cameron Zwarich wrote: > + ?/// getTypeForExtendedInteger - Return the type that should be used to zero or > + ?/// sign extend a zeroext/signext integer argument or return value. > + ?/// FIXME: Most C calling convention requires the return type to be promoted, > + ?/// but this is not true all the time, e.g. i1 on x86-64. It is also not > + ?/// necessary for non-C calling conventions. The frontend should handle this > + ?/// and include all of the necessary information. > + ?virtual MVT > + ?getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const { > + ? ?return MVT::i32; > + ?} Can this only ever get called for integers with <= 32 bits? If so, it'd be nice to assert() that to make sure it doesn't ever try to e.g. "extend" an i64 to i32 in the future. If not, it should probably return VT if it's > 32 bits. P.S. In the future, please try to spell my name right (you misspelled it in the commit message for r127684). From Renato.Golin at arm.com Thu Mar 17 05:01:17 2011 From: Renato.Golin at arm.com (Renato Golin) Date: Thu, 17 Mar 2011 10:01:17 +0000 Subject: [llvm-commits] [llvm] r127757 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/CodeGen/ARM/dwarf-relocation.ll In-Reply-To: References: <20110316210552.3BA5F2A6C12C@llvm.org> Message-ID: <4D81DBED.7080809@arm.com> On 16/03/11 22:17, Daniel Dunbar wrote: > Hi Renato, > > This broke a Debug+Asserts self-host build of Clang, at least on > Darwin, I'm reverting it for now. Can you take a look? Yup, I'm already owner of the bug Rafael created. I'll have a look. cheers, --renato -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. From baldrick at free.fr Thu Mar 17 05:41:39 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 17 Mar 2011 10:41:39 -0000 Subject: [llvm-commits] [dragonegg] r127805 - /dragonegg/trunk/Constants.cpp Message-ID: <20110317104139.377272A6C12C@llvm.org> Author: baldrick Date: Thu Mar 17 05:41:39 2011 New Revision: 127805 URL: http://llvm.org/viewvc/llvm-project?rev=127805&view=rev Log: Factorize code for getting the address of a simple constant. While there add a few missing simple constant types. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=127805&r1=127804&r2=127805&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Thu Mar 17 05:41:39 2011 @@ -1297,15 +1297,27 @@ } } -/// get_constant_alignment - Return the alignment of constant EXP in bits. -static unsigned int -get_constant_alignment (tree exp) -{ - unsigned int align = TYPE_ALIGN (TREE_TYPE (exp)); +static Constant *AddressOfCST(tree exp) { + Constant *Init = ConvertInitializer(exp); + + // Cache the constants to avoid making obvious duplicates that have to be + // folded by the optimizer. + static std::map CSTCache; + GlobalVariable *&Slot = CSTCache[Init]; + if (!Slot) { + // Create a new global variable. + Slot = new GlobalVariable(*TheModule, Init->getType(), true, + GlobalVariable::PrivateLinkage, Init, ".cst"); + unsigned align = TYPE_ALIGN (TREE_TYPE (exp)); #ifdef CONSTANT_ALIGNMENT - align = CONSTANT_ALIGNMENT (exp, align); + align = CONSTANT_ALIGNMENT (exp, align); #endif - return align; + Slot->setAlignment(align); + } + + // The initializer may have any type. Return a pointer of the expected type. + const Type *Ty = ConvertType(TREE_TYPE(exp)); + return TheFolder->CreateBitCast(Slot, Ty->getPointerTo()); } static Constant *AddressOfDecl(tree exp) { @@ -1339,62 +1351,6 @@ return TheTreeToLLVM->AddressOfLABEL_DECL(exp); } -static Constant *AddressOfCOMPLEX_CST(tree exp) { - Constant *Init = ConvertCOMPLEX_CST(exp); - - // Cache the constants to avoid making obvious duplicates that have to be - // folded by the optimizer. - static std::map ComplexCSTCache; - GlobalVariable *&Slot = ComplexCSTCache[Init]; - if (Slot) return Slot; - - // Create a new complex global. - Slot = new GlobalVariable(*TheModule, Init->getType(), true, - GlobalVariable::PrivateLinkage, Init, ".cpx"); - Slot->setAlignment(get_constant_alignment(exp) / 8); - - return Slot; -} - -static Constant *AddressOfREAL_CST(tree exp) { - Constant *Init = ConvertREAL_CST(exp); - - // Cache the constants to avoid making obvious duplicates that have to be - // folded by the optimizer. - static std::map RealCSTCache; - GlobalVariable *&Slot = RealCSTCache[Init]; - if (Slot) return Slot; - - // Create a new real global. - Slot = new GlobalVariable(*TheModule, Init->getType(), true, - GlobalVariable::PrivateLinkage, Init, ".rl"); - Slot->setAlignment(get_constant_alignment(exp) / 8); - - return Slot; -} - -static Constant *AddressOfSTRING_CST(tree exp) { - Constant *Init = ConvertSTRING_CST(exp); - - GlobalVariable **SlotP = 0; - - // Cache the string constants to avoid making obvious duplicate strings that - // have to be folded by the optimizer. - static std::map StringCSTCache; - GlobalVariable *&Slot = StringCSTCache[Init]; - if (Slot) return Slot; - SlotP = &Slot; - - // Create a new string global. - GlobalVariable *GV = new GlobalVariable(*TheModule, Init->getType(), true, - GlobalVariable::PrivateLinkage, Init, - ".str"); - GV->setAlignment(get_constant_alignment(exp) / 8); - - if (SlotP) *SlotP = GV; - return GV; -} - static Constant *AddressOfARRAY_REF(tree exp) { tree Array = TREE_OPERAND(exp, 0); tree Index = TREE_OPERAND(exp, 1); @@ -1515,6 +1471,14 @@ debug_tree(exp); assert(0 && "Unknown constant lvalue to convert!"); abort(); + case COMPLEX_CST: + case FIXED_CST: + case INTEGER_CST: + case REAL_CST: + case STRING_CST: + case VECTOR_CST: + LV = AddressOfCST(exp); + break; case FUNCTION_DECL: case CONST_DECL: case VAR_DECL: @@ -1523,15 +1487,6 @@ case LABEL_DECL: LV = AddressOfLABEL_DECL(exp); break; - case COMPLEX_CST: - LV = AddressOfCOMPLEX_CST(exp); - break; - case REAL_CST: - LV = AddressOfREAL_CST(exp); - break; - case STRING_CST: - LV = AddressOfSTRING_CST(exp); - break; case COMPONENT_REF: LV = AddressOfCOMPONENT_REF(exp); break; From kd at kendyck.com Thu Mar 17 06:30:18 2011 From: kd at kendyck.com (Ken Dyck) Date: Thu, 17 Mar 2011 07:30:18 -0400 Subject: [llvm-commits] [llvm] r127766 - in /llvm/trunk: docs/LangRef.html include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/bool-zext Message-ID: On Wed, Mar 16, 2011 at 6:20 PM, Cameron Zwarich wrote: > --- llvm/trunk/docs/LangRef.html (original) > +++ llvm/trunk/docs/LangRef.html Wed Mar 16 17:20:18 2011 > @@ -1017,8 +1017,9 @@ > ?
> ?
zeroext
> ?
This indicates to the code generator that the parameter or return value > - ? ? ?should be zero-extended to a 32-bit value by the caller (for a parameter) > - ? ? ?or the callee (for a return value).
> + ? ? ?should be zero-extended to the extent required by the target's ABI (which > + ? ? ?is usually 32-bits, but is 8-bits for a i1 on x86-64) by the caller (for a > + ? ? ?parameter) or the callee (for a return value).
> > ?
signext
> ?
This indicates to the code generator that the parameter or return value Shouldn't the description of signext get similar modifications? -Ken From kd at kendyck.com Thu Mar 17 06:38:24 2011 From: kd at kendyck.com (Ken Dyck) Date: Thu, 17 Mar 2011 07:38:24 -0400 Subject: [llvm-commits] [llvm] r127766 - in /llvm/trunk: docs/LangRef.html include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/bool-zext Message-ID: On Wed, Mar 16, 2011 at 8:26 PM, Cameron Zwarich wrote: > On Mar 16, 2011, at 5:17 PM, Evan Cheng wrote: > >> Thanks. But I am not crazy about getTypeForExtendedInteger(). Can you name it better so it's clear it's used for argument passing and return values? >> > I am not too crazy about the name either. I originally had it named something > return-specific (since my patch is return-specific), but remembered it also applies > to the argument case. Anyone have any suggestions? I will try to think about it > and change it to something better... The LangRef refers to signext and zeroext as parameter attributes, so how about getTypeForExtendedIntegerParameter()? Or getTypeForIntegerParameterExtension(). -Ken From zwarich at apple.com Thu Mar 17 08:57:18 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 17 Mar 2011 06:57:18 -0700 Subject: [llvm-commits] [llvm] r127766 - in /llvm/trunk: docs/LangRef.html include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/bool-zext In-Reply-To: References: Message-ID: <9BE32038-1167-4F18-9572-807EC4C7B74E@apple.com> On Mar 17, 2011, at 2:22 AM, Frits van Bommel wrote: > On Wed, Mar 16, 2011 at 11:20 PM, Cameron Zwarich wrote: >> + /// getTypeForExtendedInteger - Return the type that should be used to zero or >> + /// sign extend a zeroext/signext integer argument or return value. >> + /// FIXME: Most C calling convention requires the return type to be promoted, >> + /// but this is not true all the time, e.g. i1 on x86-64. It is also not >> + /// necessary for non-C calling conventions. The frontend should handle this >> + /// and include all of the necessary information. >> + virtual MVT >> + getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const { >> + return MVT::i32; >> + } > > Can this only ever get called for integers with <= 32 bits? > If so, it'd be nice to assert() that to make sure it doesn't ever try > to e.g. "extend" an i64 to i32 in the future. If not, it should > probably return VT if it's > 32 bits. The only caller has some logic that should really be moved into this function: if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { MVT ReturnMVT = getTypeForExtendedInteger(VT, ExtendKind); EVT MinVT = TLI.getRegisterType(*DAG.getContext(), ReturnMVT); if (VT.bitsLT(MinVT)) VT = MinVT; } It gets called in the 64-bit case, but then gets ignored. > P.S. In the future, please try to spell my name right (you misspelled > it in the commit message for r127684). Sorry about that. I will try to get it right in the future. Cameron From zwarich at apple.com Thu Mar 17 09:21:56 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 17 Mar 2011 14:21:56 -0000 Subject: [llvm-commits] [llvm] r127807 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h Message-ID: <20110317142156.A91BE2A6C12C@llvm.org> Author: zwarich Date: Thu Mar 17 09:21:56 2011 New Revision: 127807 URL: http://llvm.org/viewvc/llvm-project?rev=127807&view=rev Log: Rename getTypeForExtendedInteger() to getTypeForExtArgOrReturn(). Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127807&r1=127806&r2=127807&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Mar 17 09:21:56 2011 @@ -1287,14 +1287,14 @@ return false; } - /// getTypeForExtendedInteger - Return the type that should be used to zero or + /// getTypeForExtArgOrReturn - Return the type that should be used to zero or /// sign extend a zeroext/signext integer argument or return value. /// FIXME: Most C calling convention requires the return type to be promoted, /// but this is not true all the time, e.g. i1 on x86-64. It is also not /// necessary for non-C calling conventions. The frontend should handle this /// and include all of the necessary information. virtual MVT - getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const { + getTypeForExtArgOrReturn(EVT VT, ISD::NodeType ExtendKind) const { return MVT::i32; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=127807&r1=127806&r2=127807&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Mar 17 09:21:56 2011 @@ -1129,7 +1129,7 @@ ExtendKind = ISD::ZERO_EXTEND; if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { - MVT ReturnMVT = TLI.getTypeForExtendedInteger(VT, ExtendKind); + MVT ReturnMVT = TLI.getTypeForExtArgOrReturn(VT, ExtendKind); EVT MinVT = TLI.getRegisterType(*DAG.getContext(), ReturnMVT); if (VT.bitsLT(MinVT)) VT = MinVT; Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127807&r1=127806&r2=127807&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Mar 17 09:21:56 2011 @@ -1449,8 +1449,8 @@ } MVT -X86TargetLowering::getTypeForExtendedInteger(EVT VT, - ISD::NodeType ExtendKind) const { +X86TargetLowering::getTypeForExtArgOrReturn(EVT VT, + ISD::NodeType ExtendKind) const { // TODO: Is this also valid on 32-bit? if (Subtarget->is64Bit() && VT == MVT::i1 && ExtendKind == ISD::ZERO_EXTEND) return MVT::i8; Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127807&r1=127806&r2=127807&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Thu Mar 17 09:21:56 2011 @@ -844,7 +844,7 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; virtual MVT - getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const; + getTypeForExtArgOrReturn(EVT VT, ISD::NodeType ExtendKind) const; virtual bool CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, From zwarich at apple.com Thu Mar 17 09:21:59 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 17 Mar 2011 14:21:59 -0000 Subject: [llvm-commits] [llvm] r127808 - /llvm/trunk/docs/LangRef.html Message-ID: <20110317142159.7F34B2A6C12D@llvm.org> Author: zwarich Date: Thu Mar 17 09:21:58 2011 New Revision: 127808 URL: http://llvm.org/viewvc/llvm-project?rev=127808&view=rev Log: Change the signext language in LangRef to closer match zeroext. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=127808&r1=127807&r2=127808&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Thu Mar 17 09:21:58 2011 @@ -1023,8 +1023,9 @@
signext
This indicates to the code generator that the parameter or return value - should be sign-extended to a 32-bit value by the caller (for a parameter) - or the callee (for a return value).
+ should be sign-extended to the extent required by the target's ABI (which + is usually 32-bits) by the caller (for a parameter) or the callee (for a + return value).
inreg
This indicates that this parameter or return value should be treated in a From zwarich at apple.com Thu Mar 17 09:53:37 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Thu, 17 Mar 2011 14:53:37 -0000 Subject: [llvm-commits] [llvm] r127809 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h Message-ID: <20110317145337.89BD32A6C12C@llvm.org> Author: zwarich Date: Thu Mar 17 09:53:37 2011 New Revision: 127809 URL: http://llvm.org/viewvc/llvm-project?rev=127809&view=rev Log: Move more logic into getTypeForExtArgOrReturn. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127809&r1=127808&r2=127809&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Mar 17 09:53:37 2011 @@ -1293,9 +1293,10 @@ /// but this is not true all the time, e.g. i1 on x86-64. It is also not /// necessary for non-C calling conventions. The frontend should handle this /// and include all of the necessary information. - virtual MVT - getTypeForExtArgOrReturn(EVT VT, ISD::NodeType ExtendKind) const { - return MVT::i32; + virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, + ISD::NodeType ExtendKind) const { + EVT MinVT = getRegisterType(Context, MVT::i32); + return VT.bitsLT(MinVT) ? MinVT : VT; } /// LowerOperationWrapper - This callback is invoked by the type legalizer Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=127809&r1=127808&r2=127809&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Mar 17 09:53:37 2011 @@ -1128,12 +1128,8 @@ else if (F->paramHasAttr(0, Attribute::ZExt)) ExtendKind = ISD::ZERO_EXTEND; - if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { - MVT ReturnMVT = TLI.getTypeForExtArgOrReturn(VT, ExtendKind); - EVT MinVT = TLI.getRegisterType(*DAG.getContext(), ReturnMVT); - if (VT.bitsLT(MinVT)) - VT = MinVT; - } + if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) + VT = TLI.getTypeForExtArgOrReturn(*DAG.getContext(), VT, ExtendKind); unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), VT); EVT PartVT = TLI.getRegisterType(*DAG.getContext(), VT); Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127809&r1=127808&r2=127809&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Mar 17 09:53:37 2011 @@ -1448,13 +1448,18 @@ return HasRet; } -MVT -X86TargetLowering::getTypeForExtArgOrReturn(EVT VT, +EVT +X86TargetLowering::getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, ISD::NodeType ExtendKind) const { + MVT ReturnMVT; // TODO: Is this also valid on 32-bit? if (Subtarget->is64Bit() && VT == MVT::i1 && ExtendKind == ISD::ZERO_EXTEND) - return MVT::i8; - return MVT::i32; + ReturnMVT = MVT::i8; + else + ReturnMVT = MVT::i32; + + EVT MinVT = getRegisterType(Context, ReturnMVT); + return VT.bitsLT(MinVT) ? MinVT : VT; } /// LowerCallResult - Lower the result values of a call into the Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127809&r1=127808&r2=127809&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Thu Mar 17 09:53:37 2011 @@ -843,8 +843,9 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; - virtual MVT - getTypeForExtArgOrReturn(EVT VT, ISD::NodeType ExtendKind) const; + virtual EVT + getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, + ISD::NodeType ExtendKind) const; virtual bool CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, From baldrick at free.fr Thu Mar 17 10:24:17 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 17 Mar 2011 15:24:17 -0000 Subject: [llvm-commits] [dragonegg] r127810 - /dragonegg/trunk/Constants.cpp Message-ID: <20110317152417.91FE42A6C12C@llvm.org> Author: baldrick Date: Thu Mar 17 10:24:17 2011 New Revision: 127810 URL: http://llvm.org/viewvc/llvm-project?rev=127810&view=rev Log: AddressOf makes some guarantees about the type of the returned pointer. Put code to ensure the type is correct in one place rather than duplicated in many places. Also, fix some places that made assumptions about the type of the constants returned by ConvertInitializer. While there, don't bother changing the array index type to intptrty - nowadays GEP can handle indices of any integer type. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=127810&r1=127809&r2=127810&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Thu Mar 17 10:24:17 2011 @@ -1297,6 +1297,11 @@ } } +//===----------------------------------------------------------------------===// +// ... AddressOf ... +//===----------------------------------------------------------------------===// + +/// AddressOfCST - Return the address of a simple constant, eg a of number. static Constant *AddressOfCST(tree exp) { Constant *Init = ConvertInitializer(exp); @@ -1304,36 +1309,27 @@ // folded by the optimizer. static std::map CSTCache; GlobalVariable *&Slot = CSTCache[Init]; - if (!Slot) { - // Create a new global variable. - Slot = new GlobalVariable(*TheModule, Init->getType(), true, - GlobalVariable::PrivateLinkage, Init, ".cst"); - unsigned align = TYPE_ALIGN (TREE_TYPE (exp)); + if (Slot) + return Slot; + + // Create a new global variable. + Slot = new GlobalVariable(*TheModule, Init->getType(), true, + GlobalVariable::PrivateLinkage, Init, ".cst"); + unsigned align = TYPE_ALIGN (TREE_TYPE (exp)); #ifdef CONSTANT_ALIGNMENT - align = CONSTANT_ALIGNMENT (exp, align); + align = CONSTANT_ALIGNMENT (exp, align); #endif - Slot->setAlignment(align); - } + Slot->setAlignment(align); - // The initializer may have any type. Return a pointer of the expected type. - const Type *Ty = ConvertType(TREE_TYPE(exp)); - return TheFolder->CreateBitCast(Slot, Ty->getPointerTo()); + return Slot; } +/// AddressOfDecl - Return the address of a global. static Constant *AddressOfDecl(tree exp) { - GlobalValue *Val = cast(DEFINITION_LLVM(exp)); - - // The type of the global value output for exp need not match that of exp. - // For example if the global's initializer has a different type to the global - // itself (allowed in GCC but not in LLVM) then the global is changed to have - // the type of the initializer. Correct for this now. - const Type *Ty = ConvertType(TREE_TYPE(exp)); - if (Ty->isVoidTy()) Ty = Type::getInt8Ty(Context); // void* -> i8*. - - return TheFolder->CreateBitCast(Val, Ty->getPointerTo()); + return cast(DEFINITION_LLVM(exp)); } -/// AddressOfLABEL_DECL - Someone took the address of a label. +/// AddressOfLABEL_DECL - Return the address of a label. static Constant *AddressOfLABEL_DECL(tree exp) { extern TreeToLLVM *TheTreeToLLVM; @@ -1351,33 +1347,38 @@ return TheTreeToLLVM->AddressOfLABEL_DECL(exp); } +/// AddressOfARRAY_REF - Return the address of an array element or slice. static Constant *AddressOfARRAY_REF(tree exp) { - tree Array = TREE_OPERAND(exp, 0); - tree Index = TREE_OPERAND(exp, 1); - tree IndexType = TREE_TYPE(Index); - assert(TREE_CODE(TREE_TYPE(Array)) == ARRAY_TYPE && "Unknown ARRAY_REF!"); + tree array = TREE_OPERAND(exp, 0); + tree index = TREE_OPERAND(exp, 1); + tree index_type = TREE_TYPE(index); + assert(TREE_CODE(TREE_TYPE(array)) == ARRAY_TYPE && "Unknown ARRAY_REF!"); // Check for variable sized reference. // FIXME: add support for array types where the size doesn't fit into 64 bits - assert(isSequentialCompatible(TREE_TYPE(Array)) && + assert(isSequentialCompatible(TREE_TYPE(array)) && "Global with variable size?"); + // Get the index into the array as an LLVM constant. The type of the constant + // returned by ConvertInitializer could be anything; turn it into an integer. + Constant *IndexVal = ConvertInitializer(index); + const Type *IndexTy = IntegerType::get(Context, TYPE_PRECISION(index_type)); + IndexVal = InterpretAsType(IndexVal, IndexTy, 0); + // First subtract the lower bound, if any, in the type of the index. - Constant *IndexVal = ConvertInitializer(Index); tree LowerBound = array_ref_low_bound(exp); - if (!integer_zerop(LowerBound)) - IndexVal = TheFolder->CreateSub(IndexVal, ConvertInitializer(LowerBound), - hasNUW(TREE_TYPE(Index)), - hasNSW(TREE_TYPE(Index))); - - const Type *IntPtrTy = getTargetData().getIntPtrType(Context); - IndexVal = TheFolder->CreateIntCast(IndexVal, IntPtrTy, - /*isSigned*/!TYPE_UNSIGNED(IndexType)); + if (!integer_zerop(LowerBound)) { + // Get the lower bound as an integer LLVM constant. + Constant *LowerBoundVal = ConvertInitializer(LowerBound); + LowerBoundVal = InterpretAsType(LowerBoundVal, IndexTy, 0); + IndexVal = TheFolder->CreateSub(IndexVal, LowerBoundVal, hasNUW(index_type), + hasNSW(index_type)); + } // Avoid any assumptions about how the array type is represented in LLVM by // doing the GEP on a pointer to the first array element. - Constant *ArrayAddr = AddressOf(Array); - const Type *EltTy = ConvertType(TREE_TYPE(TREE_TYPE(Array))); + Constant *ArrayAddr = AddressOf(array); + const Type *EltTy = ConvertType(TREE_TYPE(TREE_TYPE(array))); ArrayAddr = TheFolder->CreateBitCast(ArrayAddr, EltTy->getPointerTo()); return POINTER_TYPE_OVERFLOW_UNDEFINED ? @@ -1479,43 +1480,36 @@ case VECTOR_CST: LV = AddressOfCST(exp); break; - case FUNCTION_DECL: + case ARRAY_RANGE_REF: + case ARRAY_REF: + LV = AddressOfARRAY_REF(exp); + break; + case COMPONENT_REF: + LV = AddressOfCOMPONENT_REF(exp); + break; case CONST_DECL: + case FUNCTION_DECL: case VAR_DECL: LV = AddressOfDecl(exp); break; case LABEL_DECL: LV = AddressOfLABEL_DECL(exp); break; - case COMPONENT_REF: - LV = AddressOfCOMPONENT_REF(exp); - break; - case ARRAY_RANGE_REF: - case ARRAY_REF: - LV = AddressOfARRAY_REF(exp); - break; case INDIRECT_REF: // The lvalue is just the address. LV = ConvertInitializer(TREE_OPERAND(exp, 0)); break; case COMPOUND_LITERAL_EXPR: // FIXME: not gimple - defined by C front-end - /* This used to read - return AddressOf(COMPOUND_LITERAL_EXPR_DECL(exp)); - but gcc warns about that and there doesn't seem to be any way to stop it - with casts or the like. The following is equivalent with no checking - (since we know TREE_CODE(exp) is COMPOUND_LITERAL_EXPR the checking - doesn't accomplish anything anyway). */ LV = AddressOf(DECL_EXPR_DECL (TREE_OPERAND (exp, 0))); break; } - // Check that the type of the lvalue is indeed that of a pointer to the tree - // node. Since LLVM has no void* type, don't insist that void* be converted - // to a specific LLVM type. - assert(isa(LV->getType()) && - (VOID_TYPE_P(TREE_TYPE(exp)) || - cast(LV->getType())->getElementType() == - ConvertType(TREE_TYPE(exp))) && "Constant LValue has wrong type!"); - - return LV; + // Ensure that the address has the expected type. It is simpler to do this + // once here rather than in every AddressOf helper. + const Type *Ty; + if (VOID_TYPE_P(TREE_TYPE(exp))) + Ty = Type::getInt8Ty(Context); // void* -> i8*. + else + Ty = ConvertType(TREE_TYPE(exp)); + return TheFolder->CreateBitCast(LV, Ty->getPointerTo()); } From daniel at zuster.org Thu Mar 17 11:25:24 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 17 Mar 2011 16:25:24 -0000 Subject: [llvm-commits] [llvm] r127812 - in /llvm/trunk: lib/MC/MCParser/DarwinAsmParser.cpp test/MC/MachO/section-attributes.s Message-ID: <20110317162524.E41352A6C12C@llvm.org> Author: ddunbar Date: Thu Mar 17 11:25:24 2011 New Revision: 127812 URL: http://llvm.org/viewvc/llvm-project?rev=127812&view=rev Log: MC/Mach-O: Fix regression introduced in r126127, this assignment shouldn't have been removed. Added: llvm/trunk/test/MC/MachO/section-attributes.s Modified: llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp Modified: llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp?rev=127812&r1=127811&r2=127812&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp Thu Mar 17 11:25:24 2011 @@ -434,7 +434,8 @@ StringRef Segment, Section; - unsigned TAA, StubSize; + unsigned StubSize; + unsigned TAA = 0; std::string ErrorStr = MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, TAA, StubSize); Added: llvm/trunk/test/MC/MachO/section-attributes.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/section-attributes.s?rev=127812&view=auto ============================================================================== --- llvm/trunk/test/MC/MachO/section-attributes.s (added) +++ llvm/trunk/test/MC/MachO/section-attributes.s Thu Mar 17 11:25:24 2011 @@ -0,0 +1,7 @@ +// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o %t +// RUN: macho-dump %t | FileCheck %s + +// CHECK: # Section 1 +// CHECK: ('flags', 0x0) +.section __TEXT,__objc_opt_ro +.long 0 From stuart at apple.com Thu Mar 17 11:30:14 2011 From: stuart at apple.com (Stuart Hastings) Date: Thu, 17 Mar 2011 16:30:14 -0000 Subject: [llvm-commits] [llvm] r127813 - /llvm/trunk/tools/llvm-dis/llvm-dis.cpp Message-ID: <20110317163014.9B3142A6C12C@llvm.org> Author: stuart Date: Thu Mar 17 11:30:14 2011 New Revision: 127813 URL: http://llvm.org/viewvc/llvm-project?rev=127813&view=rev Log: Add type output to llvm-dis. Patch by Yuri! Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=127813&r1=127812&r2=127813&view=diff ============================================================================== --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Thu Mar 17 11:30:14 2011 @@ -74,7 +74,7 @@ if (!V.getType()->isVoidTy()) { OS.PadToColumn(50); Padded = true; - OS << "; [#uses=" << V.getNumUses() << ']'; // Output # uses + OS << "; [#uses=" << V.getNumUses() << " type=" << V.getType()->getDescription() << "]"; // Output # uses and type } if (const Instruction *I = dyn_cast(&V)) { const DebugLoc &DL = I->getDebugLoc(); From stuart at apple.com Thu Mar 17 11:35:12 2011 From: stuart at apple.com (Stuart Hastings) Date: Thu, 17 Mar 2011 09:35:12 -0700 Subject: [llvm-commits] [patch] Improvement of value printout in disassembler: adding value type In-Reply-To: <4D804026.1060007@rawbw.com> References: <4D804026.1060007@rawbw.com> Message-ID: On Mar 15, 2011, at 9:44 PM, Yuri wrote: > Please check this simple patch in. r127813 > Thanks, > Yuri stuart From stuart at apple.com Thu Mar 17 11:54:27 2011 From: stuart at apple.com (Stuart Hastings) Date: Thu, 17 Mar 2011 16:54:27 -0000 Subject: [llvm-commits] [llvm] r127814 - /llvm/trunk/tools/llvm-dis/llvm-dis.cpp Message-ID: <20110317165428.062622A6C12C@llvm.org> Author: stuart Date: Thu Mar 17 11:54:27 2011 New Revision: 127814 URL: http://llvm.org/viewvc/llvm-project?rev=127814&view=rev Log: Revert 127813 while fixing broken test. Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=127814&r1=127813&r2=127814&view=diff ============================================================================== --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Thu Mar 17 11:54:27 2011 @@ -74,7 +74,7 @@ if (!V.getType()->isVoidTy()) { OS.PadToColumn(50); Padded = true; - OS << "; [#uses=" << V.getNumUses() << " type=" << V.getType()->getDescription() << "]"; // Output # uses and type + OS << "; [#uses=" << V.getNumUses() << ']'; // Output # uses } if (const Instruction *I = dyn_cast(&V)) { const DebugLoc &DL = I->getDebugLoc(); From daniel at zuster.org Thu Mar 17 12:33:35 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 17 Mar 2011 17:33:35 -0000 Subject: [llvm-commits] [zorg] r127816 - /zorg/trunk/lnt/lnt/viewer/simple.ptl Message-ID: <20110317173335.B70512A6C12C@llvm.org> Author: ddunbar Date: Thu Mar 17 12:33:35 2011 New Revision: 127816 URL: http://llvm.org/viewvc/llvm-project?rev=127816&view=rev Log: LNT: Enable graph of all parameter sets by default. Modified: zorg/trunk/lnt/lnt/viewer/simple.ptl Modified: zorg/trunk/lnt/lnt/viewer/simple.ptl URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/simple.ptl?rev=127816&r1=127815&r2=127816&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/viewer/simple.ptl (original) +++ zorg/trunk/lnt/lnt/viewer/simple.ptl Thu Mar 17 12:33:35 2011 @@ -649,7 +649,7 @@ """ for i in range(len(ts_summary.parameter_sets)): """ - + %%""" % i if show_delta: """ From daniel at zuster.org Thu Mar 17 12:33:38 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 17 Mar 2011 17:33:38 -0000 Subject: [llvm-commits] [zorg] r127817 - /zorg/trunk/zorg/buildbot/commands/StandardizedTest.py Message-ID: <20110317173338.346542A6C12D@llvm.org> Author: ddunbar Date: Thu Mar 17 12:33:38 2011 New Revision: 127817 URL: http://llvm.org/viewvc/llvm-project?rev=127817&view=rev Log: buildbot: Workaround buildbot 0.8+ bug where slashes in log names aren't properly quoted. Modified: zorg/trunk/zorg/buildbot/commands/StandardizedTest.py Modified: zorg/trunk/zorg/buildbot/commands/StandardizedTest.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/zorg/buildbot/commands/StandardizedTest.py?rev=127817&r1=127816&r2=127817&view=diff ============================================================================== --- zorg/trunk/zorg/buildbot/commands/StandardizedTest.py (original) +++ zorg/trunk/zorg/buildbot/commands/StandardizedTest.py Thu Mar 17 12:33:38 2011 @@ -1,4 +1,5 @@ import re +import urllib import buildbot import buildbot.status.builder import buildbot.steps.shell @@ -59,6 +60,8 @@ # Add logs for failures. if result in self.failingCodes and len(logs) < self.maxLogs: if log is not None and log.strip(): + # Buildbot 0.8 doesn't properly quote slashes, replace them. + test = test.replace("/", "___") logs.append((test, log)) # Explicitly remove any ignored warnings for tests which are From daniel at zuster.org Thu Mar 17 12:36:48 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 17 Mar 2011 17:36:48 -0000 Subject: [llvm-commits] [zorg] r127818 - /zorg/trunk/lnt/lnt/viewer/GraphUtil.py Message-ID: <20110317173648.7094D2A6C12C@llvm.org> Author: ddunbar Date: Thu Mar 17 12:36:48 2011 New Revision: 127818 URL: http://llvm.org/viewvc/llvm-project?rev=127818&view=rev Log: lnt.viewer.GraphUtil: Don't crash if linregress blows up. Modified: zorg/trunk/lnt/lnt/viewer/GraphUtil.py Modified: zorg/trunk/lnt/lnt/viewer/GraphUtil.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/viewer/GraphUtil.py?rev=127818&r1=127817&r2=127818&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/viewer/GraphUtil.py (original) +++ zorg/trunk/lnt/lnt/viewer/GraphUtil.py Thu Mar 17 12:36:48 2011 @@ -88,11 +88,12 @@ norm_xs = [(x - x_min) / (x_max - x_min) for x in xs] - # FIXME: When can this raise ZeroDivisionError? try: info = ext_stats.linregress(norm_xs, ys) except ZeroDivisionError: info = None + except ValueError: + info = None if info is not None: slope, intercept,_,_,_ = info From daniel at zuster.org Thu Mar 17 13:09:01 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 17 Mar 2011 11:09:01 -0700 Subject: [llvm-commits] [llvm] r126127 - in /llvm/trunk/lib: CodeGen/TargetLoweringObjectFileImpl.cpp MC/MCSectionMachO.cpp In-Reply-To: <20110221172717.C79962A6C12C@llvm.org> References: <20110221172717.C79962A6C12C@llvm.org> Message-ID: Hi Stuart, On Mon, Feb 21, 2011 at 9:27 AM, Stuart Hastings wrote: > Author: stuart > Date: Mon Feb 21 11:27:17 2011 > New Revision: 126127 > > URL: http://llvm.org/viewvc/llvm-project?rev=126127&view=rev > Log: > Fix to correctly support attribute((section("__DATA, __common"))). > Radar 9012638. > > Modified: > ? ?llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp > ? ?llvm/trunk/lib/MC/MCSectionMachO.cpp > > Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=126127&r1=126126&r2=126127&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original) > +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Mon Feb 21 11:27:17 2011 > @@ -630,7 +630,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ?Mangler *Mang, const TargetMachine &TM) const { > ? // Parse the section specifier and create it if valid. > ? StringRef Segment, Section; > - ?unsigned TAA, StubSize; > + ?unsigned TAA = (unsigned)MCSectionMachO::SECTION_ATTRIBUTES, StubSize = 0; > ? std::string ErrorCode = > ? ? MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TAA, StubSize); > @@ -643,10 +643,19 @@ > ? ? return DataSection; > ? } > > + ?bool TAAWasSet = (TAA != MCSectionMachO::SECTION_ATTRIBUTES); > + ?if (!TAAWasSet) > + ? ?TAA = 0; ? ? ?// Sensible default if this is a new section. > + > ? // Get the section. > ? const MCSectionMachO *S = > ? ? getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); > > + ?// If TAA wasn't set by ParseSectionSpecifier() above, > + ?// use the value returned by getMachOSection() as a default. > + ?if (!TAAWasSet) > + ? ?TAA = S->getTypeAndAttributes(); > + > ? // Okay, now that we got the section, verify that the TAA & StubSize agree. > ? // If the user declared multiple globals with different section flags, we need > ? // to reject it here. > > Modified: llvm/trunk/lib/MC/MCSectionMachO.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionMachO.cpp?rev=126127&r1=126126&r2=126127&view=diff > ============================================================================== > --- llvm/trunk/lib/MC/MCSectionMachO.cpp (original) > +++ llvm/trunk/lib/MC/MCSectionMachO.cpp Mon Feb 21 11:27:17 2011 > @@ -101,16 +101,16 @@ > ? ? return; > ? } > > - ?OS << ','; > - > ? unsigned SectionType = TAA & MCSectionMachO::SECTION_TYPE; > ? assert(SectionType <= MCSectionMachO::LAST_KNOWN_SECTION_TYPE && > ? ? ? ? ?"Invalid SectionType specified!"); > > - ?if (SectionTypeDescriptors[SectionType].AssemblerName) > + ?if (SectionTypeDescriptors[SectionType].AssemblerName) { > + ? ?OS << ','; > ? ? OS << SectionTypeDescriptors[SectionType].AssemblerName; > - ?else > - ? ?OS << "<<" << SectionTypeDescriptors[SectionType].EnumName << ">>"; > + ?} else > + ? ?// If we have no name for the attribute, stop here. > + ? ?return; > > ? // If we don't have any attributes, we're done. > ? unsigned SectionAttrs = TAA & MCSectionMachO::SECTION_ATTRIBUTES; > @@ -125,7 +125,9 @@ > > ? // Check each attribute to see if we have it. > ? char Separator = ','; > - ?for (unsigned i = 0; SectionAttrDescriptors[i].AttrFlag; ++i) { > + ?for (unsigned i = 0; > + ? ? ? SectionAttrs != 0 && SectionAttrDescriptors[i].AttrFlag; > + ? ? ? ++i) { > ? ? // Check to see if we have this attribute. > ? ? if ((SectionAttrDescriptors[i].AttrFlag & SectionAttrs) == 0) > ? ? ? continue; > @@ -207,7 +209,6 @@ > ? ? ? ? ? ?"between 1 and 16 characters"; > > ? // If there is no comma after the section, we're done. > - ?TAA = 0; It looks like you changed the semantics of ParseSectionSpecifier, but didn't update all callers. The side effect is that this ends up allowing MC to emit sections with bogus flags. I added a minimal fix in r127812, but I find the code in TargetLoweringObjectFileImpl a bit gross. Is it just using MCSectionMachO::SECTION_ATTRIBUTES as a sentinel value? I think it would be better to have ParseSectionSpecifier explicitly return a bool indicating whether the TAA was parsed or not, instead of using a sentinel. Or at a minimum, it would be good to comment what TargetLoweringObjectFileMachO::getExplicitSectionGlobal is doing. Thanks, - Daniel > ? StubSize = 0; > ? if (Comma.second.empty()) > ? ? return ""; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From kd at kendyck.com Thu Mar 17 13:15:12 2011 From: kd at kendyck.com (Ken Dyck) Date: Thu, 17 Mar 2011 14:15:12 -0400 Subject: [llvm-commits] [llvm] r127809 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h In-Reply-To: <20110317145337.89BD32A6C12C@llvm.org> References: <20110317145337.89BD32A6C12C@llvm.org> Message-ID: On Thu, Mar 17, 2011 at 10:53 AM, Cameron Zwarich wrote: > --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) > +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Mar 17 09:53:37 2011 > @@ -1293,9 +1293,10 @@ > ? /// but this is not true all the time, e.g. i1 on x86-64. It is also not > ? /// necessary for non-C calling conventions. The frontend should handle this > ? /// and include all of the necessary information. > - ?virtual MVT > - ?getTypeForExtArgOrReturn(EVT VT, ISD::NodeType ExtendKind) const { > - ? ?return MVT::i32; > + ?virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ISD::NodeType ExtendKind) const { > + ? ?EVT MinVT = getRegisterType(Context, MVT::i32); > + ? ?return VT.bitsLT(MinVT) ? MinVT : VT; > ? } Is this really an improvement? From where I sit, it seems to tightly couple the method to its call site, reducing its potential to be called from elsewhere[1]. And it requires every implementation to duplicate the size-checking logic, which multiplies the number of places that need to be updated should there ever be a need to change it. -Ken [1] For instance, http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-March/038815.html From grosbach at apple.com Thu Mar 17 13:17:16 2011 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 17 Mar 2011 11:17:16 -0700 Subject: [llvm-commits] patch: the default argument to "dmb" is "sy" In-Reply-To: References: Message-ID: <67EE14B6-5F3F-451E-8BB0-D247A74E65C2@apple.com> Hi Nick, How would an absent operand get to that default? I would expect the lexer to have returned EndOfStatement there, and there's an assert above it that there exists an operand and that it's an identifier value. That switch then checks for the identifier being a legal value. Perhaps instead add an explicit case to check for EndOfStatement and add the default value if that's the case? -Jim On Mar 16, 2011, at 5:56 PM, Nick Lewycky wrote: > The attached patch changes ARM MC to accept "dmb" and assemble it as "dmb sy". According to this page: > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGHHIE.html > that's the right thing to do. > > Please review! > > Nick > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From richard at xmos.com Thu Mar 17 13:42:05 2011 From: richard at xmos.com (Richard Osborne) Date: Thu, 17 Mar 2011 18:42:05 -0000 Subject: [llvm-commits] [llvm] r127821 - in /llvm/trunk: include/llvm/IntrinsicsXCore.td lib/Target/XCore/XCoreInstrInfo.td test/CodeGen/XCore/resources.ll Message-ID: <20110317184205.888AF2A6C12C@llvm.org> Author: friedgold Date: Thu Mar 17 13:42:05 2011 New Revision: 127821 URL: http://llvm.org/viewvc/llvm-project?rev=127821&view=rev Log: Add XCore intrinsic for setpsc. Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td llvm/trunk/test/CodeGen/XCore/resources.ll Modified: llvm/trunk/include/llvm/IntrinsicsXCore.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsXCore.td?rev=127821&r1=127820&r2=127821&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsXCore.td (original) +++ llvm/trunk/include/llvm/IntrinsicsXCore.td Thu Mar 17 13:42:05 2011 @@ -57,6 +57,8 @@ [NoCapture<0>, NoCapture<1>]>; def int_xcore_setrdy : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty], [NoCapture<0>, NoCapture<1>]>; + def int_xcore_setpsc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty], + [NoCapture<0>]>; // Intrinsics for events. def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>; Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=127821&r1=127820&r2=127821&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Thu Mar 17 13:42:05 2011 @@ -838,7 +838,7 @@ [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>; // Two operand long -// TODO setpsc, endin, peek, +// TODO endin, peek, // getd, testlcl, tinitlr def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), "bitrev $dst, $src", @@ -876,6 +876,10 @@ "setrdy res[$src1], $src2", [(int_xcore_setrdy GRRegs:$src1, GRRegs:$src2)]>; +def SETPSC_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), + "setpsc res[$src1], $src2", + [(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>; + // One operand short // TODO edu, eeu, waitet, waitef, tstart, msync, mjoin, clrtp // setdp, setcp, setev, kcall Modified: llvm/trunk/test/CodeGen/XCore/resources.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/resources.ll?rev=127821&r1=127820&r2=127821&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/XCore/resources.ll (original) +++ llvm/trunk/test/CodeGen/XCore/resources.ll Thu Mar 17 13:42:05 2011 @@ -21,6 +21,7 @@ declare void @llvm.xcore.eeu.p1i8(i8 addrspace(1)* %r) declare void @llvm.xcore.setclk.p1i8.p1i8(i8 addrspace(1)* %a, i8 addrspace(1)* %b) declare void @llvm.xcore.setrdy.p1i8.p1i8(i8 addrspace(1)* %a, i8 addrspace(1)* %b) +declare void @llvm.xcore.setpsc.p1i8(i8 addrspace(1)* %r, i32 %value) define i8 addrspace(1)* @getr() { ; CHECK: getr: @@ -190,3 +191,10 @@ call void @llvm.xcore.setrdy.p1i8.p1i8(i8 addrspace(1)* %a, i8 addrspace(1)* %b) ret void } + +define void @setpsc(i8 addrspace(1)* %r, i32 %value) { +; CHECK: setpsc +; CHECK: setpsc res[r0], r1 + call void @llvm.xcore.setpsc.p1i8(i8 addrspace(1)* %r, i32 %value) + ret void +} From bruno.cardoso at gmail.com Thu Mar 17 14:22:03 2011 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Thu, 17 Mar 2011 16:22:03 -0300 Subject: [llvm-commits] patch: the default argument to "dmb" is "sy" In-Reply-To: <67EE14B6-5F3F-451E-8BB0-D247A74E65C2@apple.com> References: <67EE14B6-5F3F-451E-8BB0-D247A74E65C2@apple.com> Message-ID: Hi Nick, I agree with Jim, and besides that, could you add the test together with the other "dmb" checks (and also check for the encoding)? On Thu, Mar 17, 2011 at 3:17 PM, Jim Grosbach wrote: > Hi Nick, > > How would an absent operand get to that default? I would expect the lexer to have returned EndOfStatement there, and there's an assert above it that there exists an operand and that it's an identifier value. That switch then checks for the identifier being a legal value. > > Perhaps instead add an explicit case to check for EndOfStatement and add the default value if that's the case? > > -Jim > > On Mar 16, 2011, at 5:56 PM, Nick Lewycky wrote: > >> The attached patch changes ARM MC to accept "dmb" and assemble it as "dmb sy". According to this page: >> ? http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHGHHIE.html >> that's the right thing to do. >> >> Please review! >> >> Nick >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -- Bruno Cardoso Lopes http://www.brunocardoso.cc From stuart at apple.com Thu Mar 17 14:50:04 2011 From: stuart at apple.com (Stuart Hastings) Date: Thu, 17 Mar 2011 19:50:04 -0000 Subject: [llvm-commits] [llvm] r127824 - in /llvm/trunk: test/Assembler/comment.ll tools/llvm-dis/llvm-dis.cpp Message-ID: <20110317195004.A4D632A6C12C@llvm.org> Author: stuart Date: Thu Mar 17 14:50:04 2011 New Revision: 127824 URL: http://llvm.org/viewvc/llvm-project?rev=127824&view=rev Log: Reapply: Add type output to llvm-dis annotations. Patch by Yuri! Modified: llvm/trunk/test/Assembler/comment.ll llvm/trunk/tools/llvm-dis/llvm-dis.cpp Modified: llvm/trunk/test/Assembler/comment.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/comment.ll?rev=127824&r1=127823&r2=127824&view=diff ============================================================================== --- llvm/trunk/test/Assembler/comment.ll (original) +++ llvm/trunk/test/Assembler/comment.ll Thu Mar 17 14:50:04 2011 @@ -7,7 +7,7 @@ ; BARE: } @B = external global i32 -; ANNOT: @B = external global i32 ; [#uses=0] +; ANNOT: @B = external global i32 ; [#uses=0 type=i32*] define <4 x i1> @foo(<4 x float> %a, <4 x float> %b) nounwind { entry: @@ -15,6 +15,5 @@ ret <4 x i1> %cmp } -; ANNOT: %cmp = fcmp olt <4 x float> %a, %b ; [#uses=1] - +; ANNOT: %cmp = fcmp olt <4 x float> %a, %b ; [#uses=1 type=<4 x i1>] Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=127824&r1=127823&r2=127824&view=diff ============================================================================== --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Thu Mar 17 14:50:04 2011 @@ -74,7 +74,7 @@ if (!V.getType()->isVoidTy()) { OS.PadToColumn(50); Padded = true; - OS << "; [#uses=" << V.getNumUses() << ']'; // Output # uses + OS << "; [#uses=" << V.getNumUses() << " type=" << V.getType()->getDescription() << "]"; // Output # uses and type } if (const Instruction *I = dyn_cast(&V)) { const DebugLoc &DL = I->getDebugLoc(); From jan_sjodin at yahoo.com Thu Mar 17 14:57:29 2011 From: jan_sjodin at yahoo.com (Jan Sjodin) Date: Thu, 17 Mar 2011 12:57:29 -0700 (PDT) Subject: [llvm-commits] [llvm] r127540 - in /llvm/trunk: include/llvm/MC/MCSection.h include/llvm/MC/MCSectionELF.h lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp In-Reply-To: <20110312130737.62D8C2A6C12C@llvm.org> References: <20110312130737.62D8C2A6C12C@llvm.org> Message-ID: <517378.41476.qm@web55607.mail.re4.yahoo.com> I have been investigating this failure for the past couple of days. There is something wrong with the linker on the test machine. If i take the generated asm file (.s) and assemble and link on my own machine it works fine. If i assemble on the test machine and link on my machine it works fine, but if I link on the test machine the ELF format becomes corrupted somehow. This shows up e.g. with readelf -a, where the object file is okay, but the binary does not list the symbol table (it is there and can be listed with readelf -s) The patch should be good otherwise, the object file is smaller with the patch than without. - Jan ________________________________ From: Duncan Sands To: llvm-commits at cs.uiuc.edu Sent: Sat, March 12, 2011 8:07:37 AM Subject: [llvm-commits] [llvm] r127540 - in /llvm/trunk: include/llvm/MC/MCSection.h include/llvm/MC/MCSectionELF.h lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp Author: baldrick Date: Sat Mar 12 07:07:37 2011 New Revision: 127540 URL: http://llvm.org/viewvc/llvm-project?rev=127540&view=rev Log: Speculatively revert commit 127478 (jsjodin) in an attempt to fix the llvm-gcc-i386-linux-selfhost and llvm-x86_64-linux-checks buildbots. The original log entry: Remove optimization emitting a reference insted of label difference, since it can create more relocations. Removed isBaseAddressKnownZero method, because it is no longer used. Modified: llvm/trunk/include/llvm/MC/MCSection.h llvm/trunk/include/llvm/MC/MCSectionELF.h llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp Modified: llvm/trunk/include/llvm/MC/MCSection.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSection.h?rev=127540&r1=127539&r2=127540&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCSection.h (original) +++ llvm/trunk/include/llvm/MC/MCSection.h Sat Mar 12 07:07:37 2011 @@ -52,6 +52,14 @@ virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const = 0; + /// isBaseAddressKnownZero - Return true if we know that this section will + /// get a base address of zero. In cases where we know that this is true we + /// can emit section offsets as direct references to avoid a subtraction + /// from the base of the section, saving a relocation. + virtual bool isBaseAddressKnownZero() const { + return false; + } + // UseCodeAlign - Return true if a .align directive should use // "optimized nops" to fill instead of 0s. virtual bool UseCodeAlign() const = 0; Modified: llvm/trunk/include/llvm/MC/MCSectionELF.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSectionELF.h?rev=127540&r1=127539&r2=127540&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCSectionELF.h (original) +++ llvm/trunk/include/llvm/MC/MCSectionELF.h Sat Mar 12 07:07:37 2011 @@ -66,6 +66,12 @@ virtual bool UseCodeAlign() const; virtual bool isVirtualSection() const; + /// isBaseAddressKnownZero - We know that non-allocatable sections (like + /// debug info) have a base of zero. + virtual bool isBaseAddressKnownZero() const { + return (getFlags() & ELF::SHF_ALLOC) == 0; + } + static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp?rev=127540&r1=127539&r2=127540&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp Sat Mar 12 07:07:37 2011 @@ -191,6 +191,13 @@ assert((!Label->isInSection() || &Label->getSection() == &Section) && "Section offset using wrong section base for label"); + // If the section in question will end up with an address of 0 anyway, we can + // just emit an absolute reference to save a relocation. + if (Section.isBaseAddressKnownZero()) { + OutStreamer.EmitSymbolValue(Label, 4, 0/*AddrSpace*/); + return; + } + // Otherwise, emit it as a label difference from the start of the section. EmitLabelDifference(Label, SectionLabel, 4); } _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110317/c779b8f3/attachment.html From jan_sjodin at yahoo.com Thu Mar 17 14:59:29 2011 From: jan_sjodin at yahoo.com (Jan Sjodin) Date: Thu, 17 Mar 2011 12:59:29 -0700 (PDT) Subject: [llvm-commits] Change DwarfUsesAbsoluteLabelForStmtList to false for X86ELFMCAsmInfo. Message-ID: <412579.37863.qm@web55604.mail.re4.yahoo.com> Re-ping! If we plan to use dwarfdump in the tests in the future this needs to be fixed one way or another. - Jan ________________________________ From: Jan Sjodin To: Anton Korobeynikov Cc: llvm-commits at cs.uiuc.edu Sent: Tue, March 8, 2011 11:46:52 AM Subject: Re: [llvm-commits] Change DwarfUsesAbsoluteLabelForStmtList to false for X86ELFMCAsmInfo. Ping! - Jan ----- Original Message ---- > From: Jan Sjodin > To: Anton Korobeynikov > Cc: llvm-commits at cs.uiuc.edu > Sent: Sat, February 26, 2011 9:40:31 AM > Subject: Re: [llvm-commits] Change DwarfUsesAbsoluteLabelForStmtList to false >for X86ELFMCAsmInfo. > > > > > ----- Original Message ---- > > From: Anton Korobeynikov > > To: Jan Sjodin > > Cc: llvm-commits at cs.uiuc.edu > > Sent: Sat, February 26, 2011 7:36:00 AM > > Subject: Re: [llvm-commits] Change DwarfUsesAbsoluteLabelForStmtList to >false > > >for X86ELFMCAsmInfo. > > > > Hello Jan, > > > > > Dwarfdump gives an error and gdb fails when generating code in memory >(but > > > happens to accept it in a .o file) in Linux when > > > DwarfUsesAbsoluteLabelForStmtList = true, this patch sets it to false to > fix > > > this issue. I don't know if this is true for other targets, but the >change > > >is > > > limited to X86ELFMCAsmInfo. > > How the patch was tested? How we might be sure this won't break non JIT >case? > > > > -- > > With best regards, Anton Korobeynikov > > Faculty of Mathematics and Mechanics, Saint Petersburg State University > > > > The question you are really asking is if there is a bug in dwarfdump or a bug >in > > llvm, because dwarfdump always complains. I tried this on Linux 64-bit with > clang and llvm trunk: > > file empty.c: > --------------------------------------------------------------- > > int main() > { > return 42; > } > --------------------------------------------------------------- > > Compile and run dwarfdump: > --------------------------------------------------------------- > > clang -c -g -emit-llvm -o empty.bc empty.c > > llc -filetype=obj empty.bc > > dwarfdump empty.o > > .debug_info > > COMPILE_UNIT
: > <0>< 11> DW_TAG_compile_unit > DW_AT_producer clang version 2.9 (trunk 126545) > DW_AT_language DW_LANG_C99 > DW_AT_name empty.c > DW_AT_entry_pc 0x0 > DW_AT_stmt_list 0x0 > DW_AT_comp_dir >/home/jsjodin/Work/LLVM/Sandboxes/TOT/test > > LOCAL_SYMBOLS: > <1>< 114> DW_TAG_base_type > DW_AT_encoding DW_ATE_signed > DW_AT_name int > DW_AT_byte_size 4 > <1>< 121> DW_TAG_subprogram > DW_AT_name main > DW_AT_decl_file 1 > DW_AT_decl_line 2 > DW_AT_type <114> > DW_AT_external yes(1) > DW_AT_low_pc 0x0 > DW_AT_high_pc 0xe > DW_AT_frame_base DW_OP_reg7 > AT of 16359 (0x3fe7) is unknown to dwarfdump. Continuing. > yes(1) > > .debug_line: line number info for a single cu > dwarfdump ERROR: dwarf_srclines: DW_DLE_ATTR_FORM_BAD (114) > --------------------------------------------------------------- > > dwarfdump cleary doesn't like what llc has produced. With the patch applied we > > > try again: > > --------------------------------------------------------------- > .debug_info > > COMPILE_UNIT
: > <0>< 11> DW_TAG_compile_unit > DW_AT_producer clang version 2.9 (trunk 126545) > DW_AT_language DW_LANG_C99 > DW_AT_name empty.c > DW_AT_entry_pc 0x0 > DW_AT_stmt_list 0 > DW_AT_comp_dir >/home/jsjodin/Work/LLVM/Sandboxes/TOT/test > > LOCAL_SYMBOLS: > <1>< 110> DW_TAG_base_type > DW_AT_encoding DW_ATE_signed > DW_AT_name int > DW_AT_byte_size 4 > <1>< 117> DW_TAG_subprogram > DW_AT_name main > DW_AT_decl_file 1 > /home/jsjodin/Work/LLVM/Sandboxes/TOT/test/empty.c > DW_AT_decl_line 2 > DW_AT_type <110> > DW_AT_external yes(1) > DW_AT_low_pc 0x0 > DW_AT_high_pc 0xe > DW_AT_frame_base DW_OP_reg7 > AT of 16359 (0x3fe7) is unknown to dwarfdump. Continuing. > yes(1) > > .debug_line: line number info for a single cu > Source lines (from CU-DIE at .debug_info offset 11): > [row,column] // /home/jsjodin/Work/LLVM/Sandboxes/TOT/test/empty.c: [ 2,-1] 0x0 // >new > > statement > /home/jsjodin/Work/LLVM/Sandboxes/TOT/test/empty.c: [ 3, 3] 0xd // >new > > statement > /home/jsjodin/Work/LLVM/Sandboxes/TOT/test/empty.c: [ 3, 3] 0xe // >new > > statement // end of text sequence > > .debug_pubnames > global main die-in-sect 117, cu-in-sect 11, die-in-cu 117, > cu-header-in-sect 0 > > .debug_macinfo > > .debug_loc format means index section-offset begin-addr end-addr > length-of-block-entry > > .debug_abbrev > < 1>< 0> DW_TAG_compile_unit DW_children_yes > < 3> DW_AT_producer DW_FORM_string > < 5> DW_AT_language DW_FORM_data2 > < 7> DW_AT_name DW_FORM_string > < 9> DW_AT_entry_pc DW_FORM_addr > < 11> DW_AT_stmt_list DW_FORM_data4 > < 13> DW_AT_comp_dir DW_FORM_string > < 2>< 17> DW_TAG_base_type DW_children_no > < 20> DW_AT_encoding DW_FORM_data1 > < 22> DW_AT_name DW_FORM_string > < 24> DW_AT_byte_size DW_FORM_data1 > < 3>< 28> DW_TAG_subprogram DW_children_no > < 31> DW_AT_name DW_FORM_string > < 33> DW_AT_decl_file DW_FORM_data1 > < 35> DW_AT_decl_line DW_FORM_data1 > < 37> DW_AT_type DW_FORM_ref4 > < 39> DW_AT_external DW_FORM_flag > < 41> DW_AT_low_pc DW_FORM_addr > < 43> DW_AT_high_pc DW_FORM_addr > < 45> DW_AT_frame_base DW_FORM_block1 > < 47> AT of 16359 (0x3fe7) is unknown to dwarfdump. Continuing. > DW_FORM_flag > < 4>< 52> null .debug_abbrev entry > > .debug_string > > .debug_aranges > > .debug_frame > > fde: > < 0><0x0:0xe>
> 0x00000000: > > .debug_static_func > > .debug_static_vars > > .debug_pubtypes > > .debug_weaknames > --------------------------------------------------------------- > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110317/a14aa57c/attachment.html From baldrick at free.fr Thu Mar 17 15:24:06 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 17 Mar 2011 20:24:06 -0000 Subject: [llvm-commits] [dragonegg] r127826 - /dragonegg/trunk/Constants.cpp Message-ID: <20110317202406.AE6EC2A6C12C@llvm.org> Author: baldrick Date: Thu Mar 17 15:24:06 2011 New Revision: 127826 URL: http://llvm.org/viewvc/llvm-project?rev=127826&view=rev Log: When taking the address of a field of a constant struct, do not make any assumptions about the type of the LLVM constant the struct is turned into. In fact, just do pointer arithmetic to find the right address and don't bother to try and locate an appropriate LLVM field. If there is one the constant folder finds it for us (though it does get a little confused if there are annoyingly placed fields of size zero). Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=127826&r1=127825&r2=127826&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Thu Mar 17 15:24:06 2011 @@ -1301,6 +1301,16 @@ // ... AddressOf ... //===----------------------------------------------------------------------===// +/// getAsInteger - Given a constant of integer type, return its value as an LLVM +/// integer constant. +static Constant *getAsInteger(tree exp) { + tree type = TREE_TYPE(exp); + assert(INTEGRAL_TYPE_P(type) && "Constant does not have integer type!"); + Constant *C = ConvertInitializer(exp); + const Type *IntTy = IntegerType::get(Context, TYPE_PRECISION(type)); + return InterpretAsType(C, IntTy, 0); +} + /// AddressOfCST - Return the address of a simple constant, eg a of number. static Constant *AddressOfCST(tree exp) { Constant *Init = ConvertInitializer(exp); @@ -1355,22 +1365,17 @@ assert(TREE_CODE(TREE_TYPE(array)) == ARRAY_TYPE && "Unknown ARRAY_REF!"); // Check for variable sized reference. - // FIXME: add support for array types where the size doesn't fit into 64 bits assert(isSequentialCompatible(TREE_TYPE(array)) && "Global with variable size?"); - // Get the index into the array as an LLVM constant. The type of the constant - // returned by ConvertInitializer could be anything; turn it into an integer. - Constant *IndexVal = ConvertInitializer(index); - const Type *IndexTy = IntegerType::get(Context, TYPE_PRECISION(index_type)); - IndexVal = InterpretAsType(IndexVal, IndexTy, 0); - - // First subtract the lower bound, if any, in the type of the index. - tree LowerBound = array_ref_low_bound(exp); - if (!integer_zerop(LowerBound)) { - // Get the lower bound as an integer LLVM constant. - Constant *LowerBoundVal = ConvertInitializer(LowerBound); - LowerBoundVal = InterpretAsType(LowerBoundVal, IndexTy, 0); + // Get the index into the array as an LLVM integer constant. + Constant *IndexVal = getAsInteger(index); + + // Subtract off the lower bound, if any. + tree lower_bound = array_ref_low_bound(exp); + if (!integer_zerop(lower_bound)) { + // Get the lower bound as an LLVM integer constant. + Constant *LowerBoundVal = getAsInteger(lower_bound); IndexVal = TheFolder->CreateSub(IndexVal, LowerBoundVal, hasNUW(index_type), hasNSW(index_type)); } @@ -1386,81 +1391,51 @@ TheFolder->CreateGetElementPtr(ArrayAddr, &IndexVal, 1); } +/// AddressOfCOMPONENT_REF - Return the address of a field in a record. static Constant *AddressOfCOMPONENT_REF(tree exp) { - Constant *StructAddrLV = AddressOf(TREE_OPERAND(exp, 0)); + assert(!(BITS_PER_UNIT & 7) && "Unit size not a multiple of 8 bits!"); + tree field_decl = TREE_OPERAND(exp, 1); - tree FieldDecl = TREE_OPERAND(exp, 1); - const Type *StructTy = ConvertType(DECL_CONTEXT(FieldDecl)); - - StructAddrLV = TheFolder->CreateBitCast(StructAddrLV, - StructTy->getPointerTo()); - const Type *FieldTy = ConvertType(TREE_TYPE(FieldDecl)); - - // BitStart - This is the actual offset of the field from the start of the - // struct, in bits. For bitfields this may be on a non-byte boundary. - unsigned BitStart; - Constant *FieldPtr; - - // If the GCC field directly corresponds to an LLVM field, handle it. - unsigned MemberIndex = GetFieldIndex(FieldDecl, StructTy); - if (MemberIndex < INT_MAX) { - // Get a pointer to the byte in which the GCC field starts. - Constant *Ops[] = { - Constant::getNullValue(Type::getInt32Ty(Context)), - ConstantInt::get(Type::getInt32Ty(Context), MemberIndex) - }; - FieldPtr = TheFolder->CreateInBoundsGetElementPtr(StructAddrLV, Ops, 2); - // Within that byte, the bit at which the GCC field starts. - BitStart = TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(TREE_OPERAND(exp, 1))); - BitStart &= 7; + // Compute the field offset in octets from the start of the record. + Constant *Offset; + if (TREE_OPERAND(exp, 2)) { + Offset = getAsInteger(TREE_OPERAND(exp, 2)); + // At this point the offset is measured in units divided by (exactly) + // (DECL_OFFSET_ALIGN / BITS_PER_UNIT). Convert to octets. + unsigned factor = DECL_OFFSET_ALIGN(field_decl) / 8; + if (factor != 1) + Offset = TheFolder->CreateMul(Offset, + ConstantInt::get(Offset->getType(), + factor)); } else { - // Offset will hold the field offset in octets. - Constant *Offset; - - assert(!(BITS_PER_UNIT & 7) && "Unit size not a multiple of 8 bits!"); - if (TREE_OPERAND(exp, 2)) { - Offset = ConvertInitializer(TREE_OPERAND(exp, 2)); - // At this point the offset is measured in units divided by (exactly) - // (DECL_OFFSET_ALIGN / BITS_PER_UNIT). Convert to octets. - unsigned factor = DECL_OFFSET_ALIGN(FieldDecl) / 8; - if (factor != 1) - Offset = TheFolder->CreateMul(Offset, - ConstantInt::get(Offset->getType(), - factor)); - } else { - assert(DECL_FIELD_OFFSET(FieldDecl) && "Field offset not available!"); - Offset = ConvertInitializer(DECL_FIELD_OFFSET(FieldDecl)); - // At this point the offset is measured in units. Convert to octets. - unsigned factor = BITS_PER_UNIT / 8; - if (factor != 1) - Offset = TheFolder->CreateMul(Offset, - ConstantInt::get(Offset->getType(), - factor)); - } - - // Here BitStart gives the offset of the field in bits from Offset. - BitStart = getInt64(DECL_FIELD_BIT_OFFSET(FieldDecl), true); - // Incorporate as much of it as possible into the pointer computation. - unsigned ByteOffset = BitStart/8; - if (ByteOffset > 0) { - Offset = TheFolder->CreateAdd(Offset, + assert(DECL_FIELD_OFFSET(field_decl) && "Field offset not available!"); + Offset = getAsInteger(DECL_FIELD_OFFSET(field_decl)); + // At this point the offset is measured in units. Convert to octets. + unsigned factor = BITS_PER_UNIT / 8; + if (factor != 1) + Offset = TheFolder->CreateMul(Offset, ConstantInt::get(Offset->getType(), - ByteOffset)); - BitStart -= ByteOffset*8; - } - - const Type *BytePtrTy = Type::getInt8PtrTy(Context); - FieldPtr = TheFolder->CreateBitCast(StructAddrLV, BytePtrTy); - FieldPtr = TheFolder->CreateInBoundsGetElementPtr(FieldPtr, &Offset, 1); - FieldPtr = TheFolder->CreateBitCast(FieldPtr, FieldTy->getPointerTo()); + factor)); } - // Make sure we return a pointer to the right type. - const Type *EltTy = ConvertType(TREE_TYPE(exp)); - FieldPtr = TheFolder->CreateBitCast(FieldPtr, EltTy->getPointerTo()); - + // Here BitStart gives the offset of the field in bits from Offset. + uint64_t BitStart = getInt64(DECL_FIELD_BIT_OFFSET(field_decl), true); + // Incorporate as much of it as possible into the pointer computation. + uint64_t ByteOffset = BitStart / 8; + if (ByteOffset > 0) { + Offset = TheFolder->CreateAdd(Offset, + ConstantInt::get(Offset->getType(), + ByteOffset)); + BitStart -= ByteOffset*8; + } assert(BitStart == 0 && "It's a bitfield reference or we didn't get to the field!"); + + const Type *BytePtrTy = Type::getInt8PtrTy(Context); + Constant *StructAddr = AddressOf(TREE_OPERAND(exp, 0)); + Constant *FieldPtr = TheFolder->CreateBitCast(StructAddr, BytePtrTy); + FieldPtr = TheFolder->CreateInBoundsGetElementPtr(FieldPtr, &Offset, 1); + return FieldPtr; } From stuart at apple.com Thu Mar 17 15:34:24 2011 From: stuart at apple.com (Stuart Hastings) Date: Thu, 17 Mar 2011 13:34:24 -0700 Subject: [llvm-commits] [llvm] r126127 - in /llvm/trunk/lib: CodeGen/TargetLoweringObjectFileImpl.cpp MC/MCSectionMachO.cpp In-Reply-To: References: <20110221172717.C79962A6C12C@llvm.org> Message-ID: <751070C0-EEF6-4455-8105-0B8AD0705242@apple.com> On Mar 17, 2011, at 11:09 AM, Daniel Dunbar wrote: > Hi Stuart, > > On Mon, Feb 21, 2011 at 9:27 AM, Stuart Hastings wrote: >> Author: stuart >> Date: Mon Feb 21 11:27:17 2011 >> New Revision: 126127 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=126127&view=rev >> Log: >> Fix to correctly support attribute((section("__DATA, __common"))). >> Radar 9012638. >> >> Modified: >> llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp >> llvm/trunk/lib/MC/MCSectionMachO.cpp >> >> Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=126127&r1=126126&r2=126127&view=diff >> ============================================================================== >> --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original) >> +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Mon Feb 21 11:27:17 2011 >> @@ -630,7 +630,7 @@ >> Mangler *Mang, const TargetMachine &TM) const { >> // Parse the section specifier and create it if valid. >> StringRef Segment, Section; >> - unsigned TAA, StubSize; >> + unsigned TAA = (unsigned)MCSectionMachO::SECTION_ATTRIBUTES, StubSize = 0; >> std::string ErrorCode = >> MCSectionMachO::ParseSectionSpecifier(GV->getSection(), Segment, Section, >> TAA, StubSize); >> @@ -643,10 +643,19 @@ >> return DataSection; >> } >> >> + bool TAAWasSet = (TAA != MCSectionMachO::SECTION_ATTRIBUTES); >> + if (!TAAWasSet) >> + TAA = 0; // Sensible default if this is a new section. >> + >> // Get the section. >> const MCSectionMachO *S = >> getContext().getMachOSection(Segment, Section, TAA, StubSize, Kind); >> >> + // If TAA wasn't set by ParseSectionSpecifier() above, >> + // use the value returned by getMachOSection() as a default. >> + if (!TAAWasSet) >> + TAA = S->getTypeAndAttributes(); >> + >> // Okay, now that we got the section, verify that the TAA & StubSize agree. >> // If the user declared multiple globals with different section flags, we need >> // to reject it here. >> >> Modified: llvm/trunk/lib/MC/MCSectionMachO.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionMachO.cpp?rev=126127&r1=126126&r2=126127&view=diff >> ============================================================================== >> --- llvm/trunk/lib/MC/MCSectionMachO.cpp (original) >> +++ llvm/trunk/lib/MC/MCSectionMachO.cpp Mon Feb 21 11:27:17 2011 >> @@ -101,16 +101,16 @@ >> return; >> } >> >> - OS << ','; >> - >> unsigned SectionType = TAA & MCSectionMachO::SECTION_TYPE; >> assert(SectionType <= MCSectionMachO::LAST_KNOWN_SECTION_TYPE && >> "Invalid SectionType specified!"); >> >> - if (SectionTypeDescriptors[SectionType].AssemblerName) >> + if (SectionTypeDescriptors[SectionType].AssemblerName) { >> + OS << ','; >> OS << SectionTypeDescriptors[SectionType].AssemblerName; >> - else >> - OS << "<<" << SectionTypeDescriptors[SectionType].EnumName << ">>"; >> + } else >> + // If we have no name for the attribute, stop here. >> + return; >> >> // If we don't have any attributes, we're done. >> unsigned SectionAttrs = TAA & MCSectionMachO::SECTION_ATTRIBUTES; >> @@ -125,7 +125,9 @@ >> >> // Check each attribute to see if we have it. >> char Separator = ','; >> - for (unsigned i = 0; SectionAttrDescriptors[i].AttrFlag; ++i) { >> + for (unsigned i = 0; >> + SectionAttrs != 0 && SectionAttrDescriptors[i].AttrFlag; >> + ++i) { >> // Check to see if we have this attribute. >> if ((SectionAttrDescriptors[i].AttrFlag & SectionAttrs) == 0) >> continue; >> @@ -207,7 +209,6 @@ >> "between 1 and 16 characters"; >> >> // If there is no comma after the section, we're done. >> - TAA = 0; > > It looks like you changed the semantics of ParseSectionSpecifier, but > didn't update all callers. The side effect is that this ends up > allowing MC to emit sections with bogus flags. Sorry about that. > I added a minimal fix in r127812, but I find the code in > TargetLoweringObjectFileImpl a bit gross. Is it just using > MCSectionMachO::SECTION_ATTRIBUTES as a sentinel value? Yes. > I think it > would be better to have ParseSectionSpecifier explicitly return a bool > indicating whether the TAA was parsed or not, instead of using a > sentinel. I was reluctant to add a sixth parameter to ParseSectionSpecifier, but if you think that's better, I'll do that. stuart > Or at a minimum, it would be good to comment what > TargetLoweringObjectFileMachO::getExplicitSectionGlobal is doing. > > Thanks, > - Daniel > >> StubSize = 0; >> if (Comma.second.empty()) >> return ""; >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> From rafael.espindola at gmail.com Thu Mar 17 15:35:42 2011 From: rafael.espindola at gmail.com (Rafael Avila de Espindola) Date: Thu, 17 Mar 2011 16:35:42 -0400 Subject: [llvm-commits] Change DwarfUsesAbsoluteLabelForStmtList to false for X86ELFMCAsmInfo. In-Reply-To: <412579.37863.qm@web55604.mail.re4.yahoo.com> References: <412579.37863.qm@web55604.mail.re4.yahoo.com> Message-ID: <4D82709E.4020005@gmail.com> On 11-03-17 03:59 PM, Jan Sjodin wrote: > Re-ping! If we plan to use dwarfdump in the tests in the future this > needs to be fixed one way or another. I am not familiar with this part of the DWARF spec, but since this fixes a problem with dwarfdump, it is OK if it causes no regressions on the gdb testsuite. It might also be good to try to set this for all ELF targets. If that is really the case, we can even remove this flag, no? > - Jan Cheers, Rafael From rafael.espindola at gmail.com Thu Mar 17 15:41:03 2011 From: rafael.espindola at gmail.com (Rafael Avila de Espindola) Date: Thu, 17 Mar 2011 16:41:03 -0400 Subject: [llvm-commits] [llvm] r127540 - in /llvm/trunk: include/llvm/MC/MCSection.h include/llvm/MC/MCSectionELF.h lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp In-Reply-To: <517378.41476.qm@web55607.mail.re4.yahoo.com> References: <20110312130737.62D8C2A6C12C@llvm.org> <517378.41476.qm@web55607.mail.re4.yahoo.com> Message-ID: <4D8271DF.6020203@gmail.com> On 11-03-17 03:57 PM, Jan Sjodin wrote: > I have been investigating this failure for the past couple of days. > There is something wrong with the linker on the test machine. If i take > the generated asm file (.s) and assemble and link on my own machine it > works fine. If i assemble on the test machine and link on my machine it > works fine, but if I link on the test machine the ELF format becomes > corrupted somehow. This shows up e.g. with readelf -a, where the object > file is okay, but the binary does not list the symbol table (it is there > and can be listed with readelf -s) The patch should be good otherwise, > the object file is smaller with the patch than without. What are the liker versions on both cases? > - Jan Cheers, Rafael From stoklund at 2pi.dk Thu Mar 17 15:37:07 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 17 Mar 2011 20:37:07 -0000 Subject: [llvm-commits] [llvm] r127827 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/InlineSpiller.cpp lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/LiveRangeEdit.cpp lib/CodeGen/LiveRangeEdit.h lib/CodeGen/SplitKit.cpp Message-ID: <20110317203707.629BC2A6C12C@llvm.org> Author: stoklund Date: Thu Mar 17 15:37:07 2011 New Revision: 127827 URL: http://llvm.org/viewvc/llvm-project?rev=127827&view=rev Log: Dead code elimination may separate the live interval into multiple connected components. I have convinced myself that it can only happen when a phi value dies. When it happens, allocate new virtual registers for the components. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/InlineSpiller.cpp llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp llvm/trunk/lib/CodeGen/LiveRangeEdit.h llvm/trunk/lib/CodeGen/SplitKit.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=127827&r1=127826&r2=127827&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Mar 17 15:37:07 2011 @@ -160,7 +160,9 @@ /// defs for new uses, and it doesn't remove dead defs. /// Dead PHIDef values are marked as unused. /// New dead machine instructions are added to the dead vector. - void shrinkToUses(LiveInterval *li, + /// Return true if the interval may have been separated into multiple + /// connected components. + bool shrinkToUses(LiveInterval *li, SmallVectorImpl *dead = 0); // Interval removal Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=127827&r1=127826&r2=127827&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Thu Mar 17 15:37:07 2011 @@ -460,7 +460,7 @@ } // Alocate a new register for the remat. - LiveInterval &NewLI = Edit->create(MRI, LIS, VRM); + LiveInterval &NewLI = Edit->create(LIS, VRM); NewLI.markNotSpillable(); // Rematting for a copy: Set allocation hint to be the destination register. @@ -685,7 +685,7 @@ // Allocate interval around instruction. // FIXME: Infer regclass from instruction alone. - LiveInterval &NewLI = Edit->create(MRI, LIS, VRM); + LiveInterval &NewLI = Edit->create(LIS, VRM); NewLI.markNotSpillable(); if (Reads) Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=127827&r1=127826&r2=127827&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Mar 17 15:37:07 2011 @@ -746,7 +746,7 @@ /// shrinkToUses - After removing some uses of a register, shrink its live /// range to just the remaining uses. This method does not compute reaching /// defs for new uses, and it doesn't remove dead defs. -void LiveIntervals::shrinkToUses(LiveInterval *li, +bool LiveIntervals::shrinkToUses(LiveInterval *li, SmallVectorImpl *dead) { DEBUG(dbgs() << "Shrink: " << *li << '\n'); assert(TargetRegisterInfo::isVirtualRegister(li->reg) @@ -835,6 +835,7 @@ } // Handle dead values. + bool CanSeparate = false; for (LiveInterval::vni_iterator I = li->vni_begin(), E = li->vni_end(); I != E; ++I) { VNInfo *VNI = *I; @@ -848,6 +849,8 @@ // This is a dead PHI. Remove it. VNI->setIsUnused(true); NewLI.removeRange(*LII); + DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n"); + CanSeparate = true; } else { // This is a dead def. Make sure the instruction knows. MachineInstr *MI = getInstructionFromIndex(VNI->def); @@ -863,6 +866,7 @@ // Move the trimmed ranges back. li->ranges.swap(NewLI.ranges); DEBUG(dbgs() << "Shrunk: " << *li << '\n'); + return CanSeparate; } Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp?rev=127827&r1=127826&r2=127827&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp Thu Mar 17 15:37:07 2011 @@ -22,16 +22,16 @@ using namespace llvm; -LiveInterval &LiveRangeEdit::create(MachineRegisterInfo &mri, - LiveIntervals &lis, - VirtRegMap &vrm) { - const TargetRegisterClass *RC = mri.getRegClass(getReg()); - unsigned VReg = mri.createVirtualRegister(RC); - vrm.grow(); - vrm.setIsSplitFromReg(VReg, vrm.getOriginal(getReg())); - LiveInterval &li = lis.getOrCreateInterval(VReg); - newRegs_.push_back(&li); - return li; +LiveInterval &LiveRangeEdit::createFrom(unsigned OldReg, + LiveIntervals &LIS, + VirtRegMap &VRM) { + MachineRegisterInfo &MRI = VRM.getRegInfo(); + unsigned VReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); + VRM.grow(); + VRM.setIsSplitFromReg(VReg, VRM.getOriginal(OldReg)); + LiveInterval &LI = LIS.getOrCreateInterval(VReg); + newRegs_.push_back(&LI); + return LI; } void LiveRangeEdit::scanRemattable(LiveIntervals &lis, @@ -137,7 +137,7 @@ } void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl &Dead, - LiveIntervals &LIS, + LiveIntervals &LIS, VirtRegMap &VRM, const TargetInstrInfo &TII) { SetVector, @@ -205,7 +205,20 @@ ToShrink.pop_back(); if (delegate_) delegate_->LRE_WillShrinkVirtReg(LI->reg); - LIS.shrinkToUses(LI, &Dead); + if (!LIS.shrinkToUses(LI, &Dead)) + continue; + + // LI may have been separated, create new intervals. + LI->RenumberValues(LIS); + ConnectedVNInfoEqClasses ConEQ(LIS); + unsigned NumComp = ConEQ.Classify(LI); + if (NumComp <= 1) + continue; + DEBUG(dbgs() << NumComp << " components: " << *LI << '\n'); + SmallVector Dups(1, LI); + for (unsigned i = 1; i != NumComp; ++i) + Dups.push_back(&createFrom(LI->reg, LIS, VRM)); + ConEQ.Distribute(&Dups[0], VRM.getRegInfo()); } } Modified: llvm/trunk/lib/CodeGen/LiveRangeEdit.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeEdit.h?rev=127827&r1=127826&r2=127827&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.h (original) +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.h Thu Mar 17 15:37:07 2011 @@ -65,6 +65,9 @@ /// live range trimmed or entirely removed. SmallPtrSet rematted_; + /// createFrom - Create a new virtual register based on OldReg. + LiveInterval &createFrom(unsigned, LiveIntervals&, VirtRegMap &); + /// scanRemattable - Identify the parent_ values that may rematerialize. void scanRemattable(LiveIntervals &lis, const TargetInstrInfo &tii, @@ -110,9 +113,11 @@ return uselessRegs_; } - /// create - Create a new register with the same class and stack slot as + /// create - Create a new register with the same class and original slot as /// parent. - LiveInterval &create(MachineRegisterInfo&, LiveIntervals&, VirtRegMap&); + LiveInterval &create(LiveIntervals &LIS, VirtRegMap &VRM) { + return createFrom(getReg(), LIS, VRM); + } /// anyRematerializable - Return true if any parent values may be /// rematerializable. @@ -166,7 +171,7 @@ /// (allDefsAreDead returns true). This may cause live intervals to be trimmed /// and further dead efs to be eliminated. void eliminateDeadDefs(SmallVectorImpl &Dead, - LiveIntervals&, + LiveIntervals&, VirtRegMap&, const TargetInstrInfo&); }; Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=127827&r1=127826&r2=127827&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Thu Mar 17 15:37:07 2011 @@ -538,11 +538,11 @@ // Create the complement as index 0. if (Edit->empty()) - Edit->create(MRI, LIS, VRM); + Edit->create(LIS, VRM); // Create the open interval. OpenIdx = Edit->size(); - Edit->create(MRI, LIS, VRM); + Edit->create(LIS, VRM); } SlotIndex SplitEditor::enterIntvBefore(SlotIndex Idx) { @@ -802,7 +802,7 @@ if (Dead.empty()) return; - Edit->eliminateDeadDefs(Dead, LIS, TII); + Edit->eliminateDeadDefs(Dead, LIS, VRM, TII); } void SplitEditor::finish() { @@ -866,7 +866,7 @@ SmallVector dups; dups.push_back(li); for (unsigned i = 1; i != NumComp; ++i) - dups.push_back(&Edit->create(MRI, LIS, VRM)); + dups.push_back(&Edit->create(LIS, VRM)); ConEQ.Distribute(&dups[0], MRI); } From benny.kra at googlemail.com Thu Mar 17 15:39:06 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 17 Mar 2011 20:39:06 -0000 Subject: [llvm-commits] [llvm] r127828 - in /llvm/trunk: include/llvm/ADT/APInt.h lib/Support/APInt.cpp unittests/ADT/APIntTest.cpp Message-ID: <20110317203906.AA6972A6C12C@llvm.org> Author: d0k Date: Thu Mar 17 15:39:06 2011 New Revision: 127828 URL: http://llvm.org/viewvc/llvm-project?rev=127828&view=rev Log: Add an argument to APInt's magic udiv calculation to specify the number of bits that are known zero in the divided number. This will come in handy soon. Modified: llvm/trunk/include/llvm/ADT/APInt.h llvm/trunk/lib/Support/APInt.cpp llvm/trunk/unittests/ADT/APIntTest.cpp Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=127828&r1=127827&r2=127828&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Thu Mar 17 15:39:06 2011 @@ -1372,7 +1372,7 @@ /// Calculate the magic number for unsigned division by a constant. struct mu; - mu magicu() const; + mu magicu(unsigned LeadingZeros = 0) const; /// @} /// @name Building-block Operations for APInt and APFloat Modified: llvm/trunk/lib/Support/APInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=127828&r1=127827&r2=127828&view=diff ============================================================================== --- llvm/trunk/lib/Support/APInt.cpp (original) +++ llvm/trunk/lib/Support/APInt.cpp Thu Mar 17 15:39:06 2011 @@ -1517,13 +1517,15 @@ /// division by a constant as a sequence of multiplies, adds and shifts. /// Requires that the divisor not be 0. Taken from "Hacker's Delight", Henry /// S. Warren, Jr., chapter 10. -APInt::mu APInt::magicu() const { +/// LeadingZeros can be used to simplify the calculation if the upper bits +/// of the devided value are known zero. +APInt::mu APInt::magicu(unsigned LeadingZeros) const { const APInt& d = *this; unsigned p; APInt nc, delta, q1, r1, q2, r2; struct mu magu; magu.a = 0; // initialize "add" indicator - APInt allOnes = APInt::getAllOnesValue(d.getBitWidth()); + APInt allOnes = APInt::getAllOnesValue(d.getBitWidth()).lshr(LeadingZeros); APInt signedMin = APInt::getSignedMinValue(d.getBitWidth()); APInt signedMax = APInt::getSignedMaxValue(d.getBitWidth()); Modified: llvm/trunk/unittests/ADT/APIntTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=127828&r1=127827&r2=127828&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/APIntTest.cpp (original) +++ llvm/trunk/unittests/ADT/APIntTest.cpp Thu Mar 17 15:39:06 2011 @@ -348,6 +348,8 @@ EXPECT_EQ(APInt(32, 5).magicu().s, 2U); EXPECT_EQ(APInt(32, 7).magicu().m, APInt(32, "24924925", 16)); EXPECT_EQ(APInt(32, 7).magicu().s, 3U); + EXPECT_EQ(APInt(64, 25).magicu(1).m, APInt(64, "A3D70A3D70A3D70B", 16)); + EXPECT_EQ(APInt(64, 25).magicu(1).s, 4U); } #ifdef GTEST_HAS_DEATH_TEST From benny.kra at googlemail.com Thu Mar 17 15:39:14 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 17 Mar 2011 20:39:14 -0000 Subject: [llvm-commits] [llvm] r127829 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp test/CodeGen/X86/divide-by-constant.ll Message-ID: <20110317203914.7AB0D2A6C12C@llvm.org> Author: d0k Date: Thu Mar 17 15:39:14 2011 New Revision: 127829 URL: http://llvm.org/viewvc/llvm-project?rev=127829&view=rev Log: BuildUDIV: If the divisor is even we can simplify the fixup of the multiplied value by introducing an early shift. This allows us to compile "unsigned foo(unsigned x) { return x/28; }" into shrl $2, %edi imulq $613566757, %rdi, %rax shrq $32, %rax ret instead of movl %edi, %eax imulq $613566757, %rax, %rcx shrq $32, %rcx subl %ecx, %eax shrl %eax addl %ecx, %eax shrl $4, %eax on x86_64 Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=127829&r1=127828&r2=127829&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Mar 17 15:39:14 2011 @@ -3174,26 +3174,39 @@ // FIXME: We should use a narrower constant when the upper // bits are known to be zero. - ConstantSDNode *N1C = cast(N->getOperand(1)); - APInt::mu magics = N1C->getAPIntValue().magicu(); + const APInt &N1C = cast(N->getOperand(1))->getAPIntValue(); + APInt::mu magics = N1C.magicu(); + + SDValue Q = N->getOperand(0); + + // If the divisor is even, we can avoid using the expensive fixup by shifting + // the divided value upfront. + if (magics.a != 0 && !N1C[0]) { + unsigned Shift = N1C.countTrailingZeros(); + Q = DAG.getNode(ISD::SRL, dl, VT, Q, + DAG.getConstant(Shift, getShiftAmountTy(Q.getValueType()))); + if (Created) + Created->push_back(Q.getNode()); + + // Get magic number for the shifted divisor. + magics = N1C.lshr(Shift).magicu(Shift); + assert(magics.a == 0 && "Should use cheap fixup now"); + } // Multiply the numerator (operand 0) by the magic value // FIXME: We should support doing a MUL in a wider type - SDValue Q; if (isOperationLegalOrCustom(ISD::MULHU, VT)) - Q = DAG.getNode(ISD::MULHU, dl, VT, N->getOperand(0), - DAG.getConstant(magics.m, VT)); + Q = DAG.getNode(ISD::MULHU, dl, VT, Q, DAG.getConstant(magics.m, VT)); else if (isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) - Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(VT, VT), - N->getOperand(0), - DAG.getConstant(magics.m, VT)).getNode(), 1); + Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(VT, VT), Q, + DAG.getConstant(magics.m, VT)).getNode(), 1); else return SDValue(); // No mulhu or equvialent if (Created) Created->push_back(Q.getNode()); if (magics.a == 0) { - assert(magics.s < N1C->getAPIntValue().getBitWidth() && + assert(magics.s < N1C.getBitWidth() && "We shouldn't generate an undefined shift!"); return DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(magics.s, getShiftAmountTy(Q.getValueType()))); Modified: llvm/trunk/test/CodeGen/X86/divide-by-constant.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/divide-by-constant.ll?rev=127829&r1=127828&r2=127829&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/divide-by-constant.ll (original) +++ llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Thu Mar 17 15:39:14 2011 @@ -60,3 +60,14 @@ ; CHECK: shrl $31, %ecx ; CHECK: sarl $18, %eax } + +define i32 @test7(i32 %x) nounwind { + %div = udiv i32 %x, 28 + ret i32 %div +; CHECK: test7: +; CHECK: shrl $2 +; CHECK: movl $613566757 +; CHECK: mull +; CHECK-NOT: shrl +; CHECK: ret +} From baldrick at free.fr Thu Mar 17 16:31:12 2011 From: baldrick at free.fr (Duncan Sands) Date: Thu, 17 Mar 2011 21:31:12 -0000 Subject: [llvm-commits] [dragonegg] r127831 - /dragonegg/trunk/Constants.cpp Message-ID: <20110317213112.D743D2A6C12C@llvm.org> Author: baldrick Date: Thu Mar 17 16:31:12 2011 New Revision: 127831 URL: http://llvm.org/viewvc/llvm-project?rev=127831&view=rev Log: Reorder some methods, no functionality change. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=127831&r1=127830&r2=127831&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Thu Mar 17 16:31:12 2011 @@ -1334,29 +1334,6 @@ return Slot; } -/// AddressOfDecl - Return the address of a global. -static Constant *AddressOfDecl(tree exp) { - return cast(DEFINITION_LLVM(exp)); -} - -/// AddressOfLABEL_DECL - Return the address of a label. -static Constant *AddressOfLABEL_DECL(tree exp) { - extern TreeToLLVM *TheTreeToLLVM; - - assert(TheTreeToLLVM && - "taking the address of a label while not compiling the function!"); - - // Figure out which function this is for, verify it's the one we're compiling. - if (DECL_CONTEXT(exp)) { - assert(TREE_CODE(DECL_CONTEXT(exp)) == FUNCTION_DECL && - "Address of label in nested function?"); - assert(TheTreeToLLVM->getFUNCTION_DECL() == DECL_CONTEXT(exp) && - "Taking the address of a label that isn't in the current fn!?"); - } - - return TheTreeToLLVM->AddressOfLABEL_DECL(exp); -} - /// AddressOfARRAY_REF - Return the address of an array element or slice. static Constant *AddressOfARRAY_REF(tree exp) { tree array = TREE_OPERAND(exp, 0); @@ -1439,6 +1416,29 @@ return FieldPtr; } +/// AddressOfDecl - Return the address of a global. +static Constant *AddressOfDecl(tree exp) { + return cast(DEFINITION_LLVM(exp)); +} + +/// AddressOfLABEL_DECL - Return the address of a label. +static Constant *AddressOfLABEL_DECL(tree exp) { + extern TreeToLLVM *TheTreeToLLVM; + + assert(TheTreeToLLVM && + "taking the address of a label while not compiling the function!"); + + // Figure out which function this is for, verify it's the one we're compiling. + if (DECL_CONTEXT(exp)) { + assert(TREE_CODE(DECL_CONTEXT(exp)) == FUNCTION_DECL && + "Address of label in nested function?"); + assert(TheTreeToLLVM->getFUNCTION_DECL() == DECL_CONTEXT(exp) && + "Taking the address of a label that isn't in the current fn!?"); + } + + return TheTreeToLLVM->AddressOfLABEL_DECL(exp); +} + Constant *AddressOf(tree exp) { Constant *LV; From jan_sjodin at yahoo.com Thu Mar 17 16:59:13 2011 From: jan_sjodin at yahoo.com (Jan Sjodin) Date: Thu, 17 Mar 2011 14:59:13 -0700 (PDT) Subject: [llvm-commits] [llvm] r127540 - in /llvm/trunk: include/llvm/MC/MCSection.h include/llvm/MC/MCSectionELF.h lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp In-Reply-To: <4D8271DF.6020203@gmail.com> References: <20110312130737.62D8C2A6C12C@llvm.org> <517378.41476.qm@web55607.mail.re4.yahoo.com> <4D8271DF.6020203@gmail.com> Message-ID: <501755.94659.qm@web55603.mail.re4.yahoo.com> Test machine: GNU ld (GNU Binutils for Debian) 2.18.0.20080103 My machine: GNU ld (GNU Binutils for Ubuntu) 2.20.51-system.20100908 I actually did a few different things to see if I could possibly reproduce the problem on my machine. 1. I downloaded the closest versions of gdb, gcc and binutils that i could find: Test machine: gcc (Debian 4.3.2-1.1) 4.3.2, GNU gdb 6.8-debian and binutils (see above) Downloaded and compiled: gcc 4.3.2, gdb 6.8 and binutils 2.18 2. Compiled llvm, llvm-gcc with these and was not able to reproduce the problem. 3. Copied the ld binary and libbfd-2.18.0.20080103.so from the test machine to my own machine to see if I could use that linker to reproduce the error, and still was not able to reproduce the problem. There is something weird going on with that specific machine and I have no clue what it is. I know that ld is involved somehow. Perhaps it is some other supporting library that is at fault. - Jan ________________________________ From: Rafael Avila de Espindola To: llvm-commits at cs.uiuc.edu Sent: Thu, March 17, 2011 4:41:03 PM Subject: Re: [llvm-commits] [llvm] r127540 - in /llvm/trunk: include/llvm/MC/MCSection.h include/llvm/MC/MCSectionELF.h lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp On 11-03-17 03:57 PM, Jan Sjodin wrote: > I have been investigating this failure for the past couple of days. > There is something wrong with the linker on the test machine. If i take > the generated asm file (.s) and assemble and link on my own machine it > works fine. If i assemble on the test machine and link on my machine it > works fine, but if I link on the test machine the ELF format becomes > corrupted somehow. This shows up e.g. with readelf -a, where the object > file is okay, but the binary does not list the symbol table (it is there > and can be listed with readelf -s) The patch should be good otherwise, > the object file is smaller with the patch than without. What are the liker versions on both cases? > - Jan Cheers, Rafael _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110317/b817c357/attachment.html From dpatel at apple.com Thu Mar 17 16:58:19 2011 From: dpatel at apple.com (Devang Patel) Date: Thu, 17 Mar 2011 21:58:19 -0000 Subject: [llvm-commits] [llvm] r127832 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/Utils/Local.cpp lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <20110317215819.91B422A6C12C@llvm.org> Author: dpatel Date: Thu Mar 17 16:58:19 2011 New Revision: 127832 URL: http://llvm.org/viewvc/llvm-project?rev=127832&view=rev Log: Refactor into a separate utility function. Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/Utils/Local.cpp llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=127832&r1=127831&r2=127832&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Thu Mar 17 16:58:19 2011 @@ -21,12 +21,15 @@ class BasicBlock; class BranchInst; class Instruction; +class DbgDeclareInst; +class StoreInst; class Value; class Pass; class PHINode; class AllocaInst; class ConstantExpr; class TargetData; +class DIBuilder; template class SmallVectorImpl; @@ -157,6 +160,15 @@ return getOrEnforceKnownAlignment(V, 0, TD); } +///===---------------------------------------------------------------------===// +/// Dbg Intrinsic utilities +/// + +/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value +/// that has an associated llvm.dbg.decl intrinsic. +bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, + StoreInst *SI, DIBuilder &Builder); + } // End llvm namespace #endif Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=127832&r1=127831&r2=127832&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Mar 17 16:58:19 2011 @@ -22,6 +22,8 @@ #include "llvm/IntrinsicInst.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/DebugInfo.h" +#include "llvm/Analysis/DIBuilder.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" @@ -755,3 +757,29 @@ return Align; } +///===---------------------------------------------------------------------===// +/// Dbg Intrinsic utilities +/// + +/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value +/// that has an associated llvm.dbg.decl intrinsic. +bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, + StoreInst *SI, DIBuilder &Builder) { + DIVariable DIVar(DDI->getVariable()); + if (!DIVar.Verify()) + return false; + + Instruction *DbgVal = + Builder.insertDbgValueIntrinsic(SI->getOperand(0), 0, + DIVar, SI); + + // Propagate any debug metadata from the store onto the dbg.value. + DebugLoc SIDL = SI->getDebugLoc(); + if (!SIDL.isUnknown()) + DbgVal->setDebugLoc(SIDL); + // Otherwise propagate debug metadata from dbg.declare. + else + DbgVal->setDebugLoc(DDI->getDebugLoc()); + return true; +} + Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=127832&r1=127831&r2=127832&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Thu Mar 17 16:58:19 2011 @@ -38,6 +38,7 @@ #include "llvm/Analysis/DIBuilder.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -273,8 +274,6 @@ LargeBlockInfo &LBI); void PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI); - void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI); - void RenamePass(BasicBlock *BB, BasicBlock *Pred, RenamePassData::ValVector &IncVals, @@ -391,7 +390,9 @@ if (Info.UsingBlocks.empty()) { // Record debuginfo for the store and remove the declaration's debuginfo. if (DbgDeclareInst *DDI = Info.DbgDeclare) { - ConvertDebugDeclareToDebugValue(DDI, Info.OnlyStore); + if (!DIB) + DIB = new DIBuilder(*DDI->getParent()->getParent()->getParent()); + ConvertDebugDeclareToDebugValue(DDI, Info.OnlyStore, *DIB); DDI->eraseFromParent(); } // Remove the (now dead) store and alloca. @@ -423,8 +424,11 @@ while (!AI->use_empty()) { StoreInst *SI = cast(AI->use_back()); // Record debuginfo for the store before removing it. - if (DbgDeclareInst *DDI = Info.DbgDeclare) - ConvertDebugDeclareToDebugValue(DDI, SI); + if (DbgDeclareInst *DDI = Info.DbgDeclare) { + if (!DIB) + DIB = new DIBuilder(*SI->getParent()->getParent()->getParent()); + ConvertDebugDeclareToDebugValue(DDI, SI, *DIB); + } SI->eraseFromParent(); LBI.deleteValue(SI); } @@ -944,28 +948,6 @@ } } -// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value -// that has an associated llvm.dbg.decl intrinsic. -void PromoteMem2Reg::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, - StoreInst *SI) { - DIVariable DIVar(DDI->getVariable()); - if (!DIVar.Verify()) - return; - - if (!DIB) - DIB = new DIBuilder(*SI->getParent()->getParent()->getParent()); - Instruction *DbgVal = DIB->insertDbgValueIntrinsic(SI->getOperand(0), 0, - DIVar, SI); - - // Propagate any debug metadata from the store onto the dbg.value. - DebugLoc SIDL = SI->getDebugLoc(); - if (!SIDL.isUnknown()) - DbgVal->setDebugLoc(SIDL); - // Otherwise propagate debug metadata from dbg.declare. - else - DbgVal->setDebugLoc(DDI->getDebugLoc()); -} - // QueuePhiNode - queues a phi-node to be added to a basic-block for a specific // Alloca returns true if there wasn't already a phi-node for that variable // @@ -1076,8 +1058,11 @@ // what value were we writing? IncomingVals[ai->second] = SI->getOperand(0); // Record debuginfo for the store before removing it. - if (DbgDeclareInst *DDI = AllocaDbgDeclares[ai->second]) - ConvertDebugDeclareToDebugValue(DDI, SI); + if (DbgDeclareInst *DDI = AllocaDbgDeclares[ai->second]) { + if (!DIB) + DIB = new DIBuilder(*SI->getParent()->getParent()->getParent()); + ConvertDebugDeclareToDebugValue(DDI, SI, *DIB); + } BB->getInstList().erase(SI); } } From johnny.chen at apple.com Thu Mar 17 17:04:05 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 17 Mar 2011 22:04:05 -0000 Subject: [llvm-commits] [llvm] r127833 - in /llvm/trunk: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h test/MC/Disassembler/ARM/thumb-tests.txt Message-ID: <20110317220405.9FE202A6C12C@llvm.org> Author: johnny Date: Thu Mar 17 17:04:05 2011 New Revision: 127833 URL: http://llvm.org/viewvc/llvm-project?rev=127833&view=rev Log: It used to be that t_addrmode_s4 was used for both: o A8.6.195 STR (register) -- Encoding T1 o A8.6.193 STR (immediate, Thumb) -- Encoding T1 It has been changed so that now they use different addressing modes and thus different MC representation (Operand Infos). Modify the disassembler to reflect the change, and add relevant tests. Modified: llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h?rev=127833&r1=127832&r2=127833&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h Thu Mar 17 17:04:05 2011 @@ -598,7 +598,7 @@ // A6.2.4 Load/store single data item // -// Load/Store Register (reg|imm): tRd tRn imm5 tRm +// Load/Store Register (reg|imm): tRd tRn imm5|tRm // Load Register Signed Byte|Halfword: tRd tRn tRm static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) { @@ -624,28 +624,25 @@ getT1tRn(insn)))); OpIdx = 2; - // We have either { imm5, tRm } or { tRm } remaining. - // Process the imm5 first. Note that STR/LDR (register) should skip the imm5 - // offset operand for t_addrmode_s[1|2|4]. + // We have either { imm5 } or { tRm } remaining. + // Note that STR/LDR (register) should skip the imm5 offset operand for + // t_addrmode_s[1|2|4]. assert(OpIdx < NumOps && "More operands expected"); if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) { - - MI.addOperand(MCOperand::CreateImm(Imm5 ? getT1Imm5(insn) : 0)); + assert(Imm5 && "Immediate operand expected for this opcode"); + MI.addOperand(MCOperand::CreateImm(getT1Imm5(insn))); + ++OpIdx; + } else { + // The next reg operand is tRm, the offset. + assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID + && "Thumb reg operand expected"); + MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID, + getT1tRm(insn)))); ++OpIdx; } - - // The next reg operand is tRm, the offset. - assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID - && "Thumb reg operand expected"); - MI.addOperand(MCOperand::CreateReg( - Imm5 ? 0 - : getRegisterEnum(B, ARM::tGPRRegClassID, - getT1tRm(insn)))); - ++OpIdx; - return true; } Modified: llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt?rev=127833&r1=127832&r2=127833&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Thu Mar 17 17:04:05 2011 @@ -27,6 +27,15 @@ # CHECK: ldmia r0!, {r1} 0x02 0xc8 +# CHECK: str r0, [r3] +0x18 0x60 + +# CHECK: str r0, [r3, #4] +0x58 0x60 + +# CHECK: str r2, [r5, r3] +0xea 0x50 + # CHECK: ldrb.w r8, #-24 0x1f 0xf8 0x18 0x80 From dpatel at apple.com Thu Mar 17 17:18:16 2011 From: dpatel at apple.com (Devang Patel) Date: Thu, 17 Mar 2011 22:18:16 -0000 Subject: [llvm-commits] [llvm] r127834 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/InstCombine/InstructionCombining.cpp lib/Transforms/Utils/Local.cpp test/Transforms/InstCombine/debuginfo.ll Message-ID: <20110317221816.9ADC82A6C12C@llvm.org> Author: dpatel Date: Thu Mar 17 17:18:16 2011 New Revision: 127834 URL: http://llvm.org/viewvc/llvm-project?rev=127834&view=rev Log: Try to not lose variable's debug info during instcombine. This is done by lowering dbg.declare intrinsic into dbg.value intrinsic. Radar 9143931. Added: llvm/trunk/test/Transforms/InstCombine/debuginfo.ll Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=127834&r1=127833&r2=127834&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Thu Mar 17 17:18:16 2011 @@ -19,6 +19,7 @@ class User; class BasicBlock; +class Function; class BranchInst; class Instruction; class DbgDeclareInst; @@ -169,6 +170,10 @@ bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI, DIBuilder &Builder); +/// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set +/// of llvm.dbg.value intrinsics. +bool LowerDbgDeclare(Function &F); + } // End llvm namespace #endif Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=127834&r1=127833&r2=127834&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Thu Mar 17 17:18:16 2011 @@ -1648,6 +1648,10 @@ bool EverMadeChange = false; + // Lower dbg.declare intrinsics otherwise their value may be clobbered + // by instcombiner. + EverMadeChange = LowerDbgDeclare(F); + // Iterate while there is work to do. unsigned Iteration = 0; while (DoOneIteration(F, Iteration++)) Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=127834&r1=127833&r2=127834&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Mar 17 17:18:16 2011 @@ -783,3 +783,29 @@ return true; } +/// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set +/// of llvm.dbg.value intrinsics. +bool llvm::LowerDbgDeclare(Function &F) { + DIBuilder DIB(*F.getParent()); + SmallVector Dbgs; + for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) + for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { + if (DbgDeclareInst *DDI = dyn_cast(BI)) + Dbgs.push_back(DDI); + } + if (Dbgs.empty()) + return false; + + for (SmallVector::iterator I = Dbgs.begin(), + E = Dbgs.end(); I != E; ++I) { + DbgDeclareInst *DDI = *I; + if (AllocaInst *AI = dyn_cast_or_null(DDI->getAddress())) { + for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); + UI != E; ++UI) + if (StoreInst *SI = dyn_cast(*UI)) + ConvertDebugDeclareToDebugValue(DDI, SI, DIB); + } + DDI->eraseFromParent(); + } + return true; +} Added: llvm/trunk/test/Transforms/InstCombine/debuginfo.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/debuginfo.ll?rev=127834&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/debuginfo.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/debuginfo.ll Thu Mar 17 17:18:16 2011 @@ -0,0 +1,57 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone + +declare i8* @foo(i8*, i32, i64, i64) nounwind + +define hidden i8* @foobar(i8* %__dest, i32 %__val, i64 %__len) nounwind inlinehint ssp { +entry: + %__dest.addr = alloca i8*, align 8 + %__val.addr = alloca i32, align 4 + %__len.addr = alloca i64, align 8 + store i8* %__dest, i8** %__dest.addr, align 8, !tbaa !1 +; CHECK-NOT: call void @llvm.dbg.declare +; CHECK: call void @llvm.dbg.value + call void @llvm.dbg.declare(metadata !{i8** %__dest.addr}, metadata !0), !dbg !16 + store i32 %__val, i32* %__val.addr, align 4, !tbaa !17 + call void @llvm.dbg.declare(metadata !{i32* %__val.addr}, metadata !7), !dbg !18 + store i64 %__len, i64* %__len.addr, align 8, !tbaa !19 + call void @llvm.dbg.declare(metadata !{i64* %__len.addr}, metadata !9), !dbg !20 + %tmp = load i8** %__dest.addr, align 8, !dbg !21, !tbaa !13 + %tmp1 = load i32* %__val.addr, align 4, !dbg !21, !tbaa !17 + %tmp2 = load i64* %__len.addr, align 8, !dbg !21, !tbaa !19 + %tmp3 = load i8** %__dest.addr, align 8, !dbg !21, !tbaa !13 + %0 = call i64 @llvm.objectsize.i64(i8* %tmp3, i1 false), !dbg !21 + %call = call i8* @foo(i8* %tmp, i32 %tmp1, i64 %tmp2, i64 %0), !dbg !21 + ret i8* %call, !dbg !21 +} + +!llvm.dbg.lv.foobar = !{!0, !7, !9} +!llvm.dbg.sp = !{!1} + +!0 = metadata !{i32 590081, metadata !1, metadata !"__dest", metadata !2, i32 16777294, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foobar", metadata !"foobar", metadata !"", metadata !2, i32 79, metadata !4, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i8* (i8*, i32, i64)* @foobar} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 589865, metadata !"string.h", metadata !"Game", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 589841, i32 0, i32 12, metadata !"bits.c", metadata !"Game", metadata !"clang version 3.0 (trunk 127710)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !5, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{metadata !6} +!6 = metadata !{i32 589839, metadata !3, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 590081, metadata !1, metadata !"__val", metadata !2, i32 33554510, metadata !8, i32 0} ; [ DW_TAG_arg_variable ] +!8 = metadata !{i32 589860, metadata !3, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!9 = metadata !{i32 590081, metadata !1, metadata !"__len", metadata !2, i32 50331726, metadata !10, i32 0} ; [ DW_TAG_arg_variable ] +!10 = metadata !{i32 589846, metadata !3, metadata !"size_t", metadata !2, i32 80, i64 0, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_typedef ] +!11 = metadata !{i32 589846, metadata !3, metadata !"__darwin_size_t", metadata !2, i32 90, i64 0, i64 0, i64 0, i32 0, metadata !12} ; [ DW_TAG_typedef ] +!12 = metadata !{i32 589860, metadata !3, metadata !"long unsigned int", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!13 = metadata !{metadata !"any pointer", metadata !14} +!14 = metadata !{metadata !"omnipotent char", metadata !15} +!15 = metadata !{metadata !"Simple C/C++ TBAA", null} +!16 = metadata !{i32 78, i32 28, metadata !1, null} +!17 = metadata !{metadata !"int", metadata !14} +!18 = metadata !{i32 78, i32 40, metadata !1, null} +!19 = metadata !{metadata !"long", metadata !14} +!20 = metadata !{i32 78, i32 54, metadata !1, null} +!21 = metadata !{i32 80, i32 3, metadata !22, null} +!22 = metadata !{i32 589835, metadata !23, i32 80, i32 3, metadata !2, i32 7} ; [ DW_TAG_lexical_block ] +!23 = metadata !{i32 589835, metadata !1, i32 79, i32 1, metadata !2, i32 6} ; [ DW_TAG_lexical_block ] From rafael.espindola at gmail.com Thu Mar 17 17:18:42 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 17 Mar 2011 22:18:42 -0000 Subject: [llvm-commits] [llvm] r127835 - in /llvm/trunk: include/llvm/Support/MemoryBuffer.h lib/Support/MemoryBuffer.cpp tools/lto/LTOModule.cpp Message-ID: <20110317221842.EA74B2A6C12C@llvm.org> Author: rafael Date: Thu Mar 17 17:18:42 2011 New Revision: 127835 URL: http://llvm.org/viewvc/llvm-project?rev=127835&view=rev Log: Use RequiresNullTerminator to create buffers without a null terminator instead of copying. Modified: llvm/trunk/include/llvm/Support/MemoryBuffer.h llvm/trunk/lib/Support/MemoryBuffer.cpp llvm/trunk/tools/lto/LTOModule.cpp Modified: llvm/trunk/include/llvm/Support/MemoryBuffer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryBuffer.h?rev=127835&r1=127834&r2=127835&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/MemoryBuffer.h (original) +++ llvm/trunk/include/llvm/Support/MemoryBuffer.h Thu Mar 17 17:18:42 2011 @@ -81,7 +81,8 @@ /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note /// that InputData must be null terminated. static MemoryBuffer *getMemBuffer(StringRef InputData, - StringRef BufferName = ""); + StringRef BufferName = "", + bool RequiresNullTerminator = true); /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, /// copying the contents and taking ownership of it. InputData does not Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryBuffer.cpp?rev=127835&r1=127834&r2=127835&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Thu Mar 17 17:18:42 2011 @@ -92,8 +92,10 @@ /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note /// that EndPtr[0] must be a null byte and be accessible! MemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData, - StringRef BufferName) { - return GetNamedBuffer(InputData, BufferName, true); + StringRef BufferName, + bool RequiresNullTerminator) { + return GetNamedBuffer(InputData, BufferName, + RequiresNullTerminator); } /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, Modified: llvm/trunk/tools/lto/LTOModule.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=127835&r1=127834&r2=127835&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOModule.cpp (original) +++ llvm/trunk/tools/lto/LTOModule.cpp Thu Mar 17 17:18:42 2011 @@ -114,18 +114,11 @@ return makeLTOModule(buffer.get(), errMsg); } -/// makeBuffer - Create a MemoryBuffer from a memory range. MemoryBuffer -/// requires the byte past end of the buffer to be a zero. We might get lucky -/// and already be that way, otherwise make a copy. Also if next byte is on a -/// different page, don't assume it is readable. +/// makeBuffer - Create a MemoryBuffer from a memory range. MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) { const char *startPtr = (char*)mem; const char *endPtr = startPtr+length; - if (((uintptr_t)endPtr & (sys::Process::GetPageSize()-1)) == 0 || - *endPtr != 0) - return MemoryBuffer::getMemBufferCopy(StringRef(startPtr, length)); - - return MemoryBuffer::getMemBuffer(StringRef(startPtr, length)); + return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false); } From eli.friedman at gmail.com Thu Mar 17 17:36:01 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Thu, 17 Mar 2011 15:36:01 -0700 Subject: [llvm-commits] [llvm] r127834 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/InstCombine/InstructionCombining.cpp lib/Transforms/Utils/Local.cpp test/Transforms/InstCombine/debuginfo.ll In-Reply-To: <20110317221816.9ADC82A6C12C@llvm.org> References: <20110317221816.9ADC82A6C12C@llvm.org> Message-ID: On Thu, Mar 17, 2011 at 3:18 PM, Devang Patel wrote: > Author: dpatel > Date: Thu Mar 17 17:18:16 2011 > New Revision: 127834 > > URL: http://llvm.org/viewvc/llvm-project?rev=127834&view=rev > Log: > Try to not lose variable's debug info during instcombine. > This is done by lowering dbg.declare intrinsic into dbg.value intrinsic. > Radar 9143931. This looks like the wrong solution to a problem only caused by a few very specific pieces of instcombine. Adding an extra iteration over every instruction in the function isn't cheap, and it looks like this could do some serious damage to the debug info for cases other than the given testcase. -Eli > Added: > ? ?llvm/trunk/test/Transforms/InstCombine/debuginfo.ll > Modified: > ? ?llvm/trunk/include/llvm/Transforms/Utils/Local.h > ? ?llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp > ? ?llvm/trunk/lib/Transforms/Utils/Local.cpp > > Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=127834&r1=127833&r2=127834&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) > +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Thu Mar 17 17:18:16 2011 > @@ -19,6 +19,7 @@ > > ?class User; > ?class BasicBlock; > +class Function; > ?class BranchInst; > ?class Instruction; > ?class DbgDeclareInst; > @@ -169,6 +170,10 @@ > ?bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?StoreInst *SI, DIBuilder &Builder); > > +/// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set > +/// of llvm.dbg.value intrinsics. > +bool LowerDbgDeclare(Function &F); > + > ?} // End llvm namespace > > ?#endif > > Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=127834&r1=127833&r2=127834&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original) > +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Thu Mar 17 17:18:16 2011 > @@ -1648,6 +1648,10 @@ > > ? bool EverMadeChange = false; > > + ?// Lower dbg.declare intrinsics otherwise their value may be clobbered > + ?// by instcombiner. > + ?EverMadeChange = LowerDbgDeclare(F); > + > ? // Iterate while there is work to do. > ? unsigned Iteration = 0; > ? while (DoOneIteration(F, Iteration++)) > > Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=127834&r1=127833&r2=127834&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Mar 17 17:18:16 2011 > @@ -783,3 +783,29 @@ > ? return true; > ?} > > +/// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set > +/// of llvm.dbg.value intrinsics. > +bool llvm::LowerDbgDeclare(Function &F) { > + ?DIBuilder DIB(*F.getParent()); > + ?SmallVector Dbgs; > + ?for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) > + ? ?for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { > + ? ? ?if (DbgDeclareInst *DDI = dyn_cast(BI)) > + ? ? ? ?Dbgs.push_back(DDI); > + ? ?} > + ?if (Dbgs.empty()) > + ? ?return false; > + > + ?for (SmallVector::iterator I = Dbgs.begin(), > + ? ? ? ? E = Dbgs.end(); I != E; ++I) { > + ? ?DbgDeclareInst *DDI = *I; > + ? ?if (AllocaInst *AI = dyn_cast_or_null(DDI->getAddress())) { > + ? ? ?for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); > + ? ? ? ? ? UI != E; ++UI) > + ? ? ? ?if (StoreInst *SI = dyn_cast(*UI)) > + ? ? ? ? ?ConvertDebugDeclareToDebugValue(DDI, SI, DIB); > + ? ?} > + ? ?DDI->eraseFromParent(); > + ?} > + ?return true; > +} > > Added: llvm/trunk/test/Transforms/InstCombine/debuginfo.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/debuginfo.ll?rev=127834&view=auto > ============================================================================== > --- llvm/trunk/test/Transforms/InstCombine/debuginfo.ll (added) > +++ llvm/trunk/test/Transforms/InstCombine/debuginfo.ll Thu Mar 17 17:18:16 2011 > @@ -0,0 +1,57 @@ > +; RUN: opt < %s -instcombine -S | FileCheck %s > + > +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone > + > +declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone > + > +declare i8* @foo(i8*, i32, i64, i64) nounwind > + > +define hidden i8* @foobar(i8* %__dest, i32 %__val, i64 %__len) nounwind inlinehint ssp { > +entry: > + ?%__dest.addr = alloca i8*, align 8 > + ?%__val.addr = alloca i32, align 4 > + ?%__len.addr = alloca i64, align 8 > + ?store i8* %__dest, i8** %__dest.addr, align 8, !tbaa !1 > +; CHECK-NOT: call void @llvm.dbg.declare > +; CHECK: call void @llvm.dbg.value > + ?call void @llvm.dbg.declare(metadata !{i8** %__dest.addr}, metadata !0), !dbg !16 > + ?store i32 %__val, i32* %__val.addr, align 4, !tbaa !17 > + ?call void @llvm.dbg.declare(metadata !{i32* %__val.addr}, metadata !7), !dbg !18 > + ?store i64 %__len, i64* %__len.addr, align 8, !tbaa !19 > + ?call void @llvm.dbg.declare(metadata !{i64* %__len.addr}, metadata !9), !dbg !20 > + ?%tmp = load i8** %__dest.addr, align 8, !dbg !21, !tbaa !13 > + ?%tmp1 = load i32* %__val.addr, align 4, !dbg !21, !tbaa !17 > + ?%tmp2 = load i64* %__len.addr, align 8, !dbg !21, !tbaa !19 > + ?%tmp3 = load i8** %__dest.addr, align 8, !dbg !21, !tbaa !13 > + ?%0 = call i64 @llvm.objectsize.i64(i8* %tmp3, i1 false), !dbg !21 > + ?%call = call i8* @foo(i8* %tmp, i32 %tmp1, i64 %tmp2, i64 %0), !dbg !21 > + ?ret i8* %call, !dbg !21 > +} > + > +!llvm.dbg.lv.foobar = !{!0, !7, !9} > +!llvm.dbg.sp = !{!1} > + > +!0 = metadata !{i32 590081, metadata !1, metadata !"__dest", metadata !2, i32 16777294, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] > +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foobar", metadata !"foobar", metadata !"", metadata !2, i32 79, metadata !4, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i8* (i8*, i32, i64)* @foobar} ; [ DW_TAG_subprogram ] > +!2 = metadata !{i32 589865, metadata !"string.h", metadata !"Game", metadata !3} ; [ DW_TAG_file_type ] > +!3 = metadata !{i32 589841, i32 0, i32 12, metadata !"bits.c", metadata !"Game", metadata !"clang version 3.0 (trunk 127710)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] > +!4 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !5, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] > +!5 = metadata !{metadata !6} > +!6 = metadata !{i32 589839, metadata !3, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] > +!7 = metadata !{i32 590081, metadata !1, metadata !"__val", metadata !2, i32 33554510, metadata !8, i32 0} ; [ DW_TAG_arg_variable ] > +!8 = metadata !{i32 589860, metadata !3, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] > +!9 = metadata !{i32 590081, metadata !1, metadata !"__len", metadata !2, i32 50331726, metadata !10, i32 0} ; [ DW_TAG_arg_variable ] > +!10 = metadata !{i32 589846, metadata !3, metadata !"size_t", metadata !2, i32 80, i64 0, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_typedef ] > +!11 = metadata !{i32 589846, metadata !3, metadata !"__darwin_size_t", metadata !2, i32 90, i64 0, i64 0, i64 0, i32 0, metadata !12} ; [ DW_TAG_typedef ] > +!12 = metadata !{i32 589860, metadata !3, metadata !"long unsigned int", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] > +!13 = metadata !{metadata !"any pointer", metadata !14} > +!14 = metadata !{metadata !"omnipotent char", metadata !15} > +!15 = metadata !{metadata !"Simple C/C++ TBAA", null} > +!16 = metadata !{i32 78, i32 28, metadata !1, null} > +!17 = metadata !{metadata !"int", metadata !14} > +!18 = metadata !{i32 78, i32 40, metadata !1, null} > +!19 = metadata !{metadata !"long", metadata !14} > +!20 = metadata !{i32 78, i32 54, metadata !1, null} > +!21 = metadata !{i32 80, i32 3, metadata !22, null} > +!22 = metadata !{i32 589835, metadata !23, i32 80, i32 3, metadata !2, i32 7} ; [ DW_TAG_lexical_block ] > +!23 = metadata !{i32 589835, metadata !1, i32 79, i32 1, metadata !2, i32 6} ; [ DW_TAG_lexical_block ] > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From dpatel at apple.com Thu Mar 17 17:41:41 2011 From: dpatel at apple.com (Devang Patel) Date: Thu, 17 Mar 2011 15:41:41 -0700 Subject: [llvm-commits] [llvm] r127834 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/InstCombine/InstructionCombining.cpp lib/Transforms/Utils/Local.cpp test/Transforms/InstCombine/debuginfo.ll In-Reply-To: References: <20110317221816.9ADC82A6C12C@llvm.org> Message-ID: On Mar 17, 2011, at 3:36 PM, Eli Friedman wrote: > On Thu, Mar 17, 2011 at 3:18 PM, Devang Patel wrote: >> Author: dpatel >> Date: Thu Mar 17 17:18:16 2011 >> New Revision: 127834 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=127834&view=rev >> Log: >> Try to not lose variable's debug info during instcombine. >> This is done by lowering dbg.declare intrinsic into dbg.value intrinsic. >> Radar 9143931. > > This looks like the wrong solution to a problem only caused by a few > very specific pieces of instcombine. Adding an extra iteration over > every instruction in the function isn't cheap instcombine is already going to iterator over once. If there are compile time regressions because of this patch, I'll take a look asap. > , and it looks like this > could do some serious damage to the debug info for cases other than > the given testcase. ? - Devang From atrick at apple.com Thu Mar 17 18:46:48 2011 From: atrick at apple.com (Andrew Trick) Date: Thu, 17 Mar 2011 23:46:48 -0000 Subject: [llvm-commits] [llvm] r127837 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <20110317234648.872702A6C12C@llvm.org> Author: atrick Date: Thu Mar 17 18:46:48 2011 New Revision: 127837 URL: http://llvm.org/viewvc/llvm-project?rev=127837&view=rev Log: whitespace Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=127837&r1=127836&r2=127837&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Mar 17 18:46:48 2011 @@ -632,7 +632,7 @@ if (!isSafe(*I, L, SE)) return false; return true; } - + // A cast is safe if its operand is. if (const SCEVCastExpr *C = dyn_cast(S)) return isSafe(C->getOperand(), L, SE); @@ -859,7 +859,7 @@ BinaryOperator *Incr = dyn_cast(PN->getIncomingValue(BackEdge)); if (Incr == 0 || Incr->getOpcode() != Instruction::FAdd) return; - + // If this is not an add of the PHI with a constantfp, or if the constant fp // is not an integer, bail out. ConstantFP *IncValueVal = dyn_cast(Incr->getOperand(1)); @@ -884,7 +884,7 @@ if (Compare == 0 || !Compare->hasOneUse() || !isa(Compare->use_back())) return; - + BranchInst *TheBr = cast(Compare->use_back()); // We need to verify that the branch actually controls the iteration count @@ -896,8 +896,8 @@ (L->contains(TheBr->getSuccessor(0)) && L->contains(TheBr->getSuccessor(1)))) return; - - + + // If it isn't a comparison with an integer-as-fp (the exit value), we can't // transform it. ConstantFP *ExitValueVal = dyn_cast(Compare->getOperand(1)); @@ -905,7 +905,7 @@ if (ExitValueVal == 0 || !ConvertToSInt(ExitValueVal->getValueAPF(), ExitValue)) return; - + // Find new predicate for integer comparison. CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE; switch (Compare->getPredicate()) { @@ -923,13 +923,13 @@ case CmpInst::FCMP_OLE: case CmpInst::FCMP_ULE: NewPred = CmpInst::ICMP_SLE; break; } - + // We convert the floating point induction variable to a signed i32 value if // we can. This is only safe if the comparison will not overflow in a way // that won't be trapped by the integer equivalent operations. Check for this // now. // TODO: We could use i64 if it is native and the range requires it. - + // The start/stride/exit values must all fit in signed i32. if (!isInt<32>(InitValue) || !isInt<32>(IncValue) || !isInt<32>(ExitValue)) return; @@ -945,55 +945,55 @@ if (InitValue >= ExitValue || NewPred == CmpInst::ICMP_SGT || NewPred == CmpInst::ICMP_SGE) return; - + uint32_t Range = uint32_t(ExitValue-InitValue); if (NewPred == CmpInst::ICMP_SLE) { // Normalize SLE -> SLT, check for infinite loop. if (++Range == 0) return; // Range overflows. } - + unsigned Leftover = Range % uint32_t(IncValue); - + // If this is an equality comparison, we require that the strided value // exactly land on the exit value, otherwise the IV condition will wrap // around and do things the fp IV wouldn't. if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) && Leftover != 0) return; - + // If the stride would wrap around the i32 before exiting, we can't // transform the IV. if (Leftover != 0 && int32_t(ExitValue+IncValue) < ExitValue) return; - + } else { // If we have a negative stride, we require the init to be greater than the // exit value and an equality or greater than comparison. if (InitValue >= ExitValue || NewPred == CmpInst::ICMP_SLT || NewPred == CmpInst::ICMP_SLE) return; - + uint32_t Range = uint32_t(InitValue-ExitValue); if (NewPred == CmpInst::ICMP_SGE) { // Normalize SGE -> SGT, check for infinite loop. if (++Range == 0) return; // Range overflows. } - + unsigned Leftover = Range % uint32_t(-IncValue); - + // If this is an equality comparison, we require that the strided value // exactly land on the exit value, otherwise the IV condition will wrap // around and do things the fp IV wouldn't. if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) && Leftover != 0) return; - + // If the stride would wrap around the i32 before exiting, we can't // transform the IV. if (Leftover != 0 && int32_t(ExitValue+IncValue) > ExitValue) return; } - + const IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext()); // Insert new integer induction variable. From atrick at apple.com Thu Mar 17 18:51:11 2011 From: atrick at apple.com (Andrew Trick) Date: Thu, 17 Mar 2011 23:51:11 -0000 Subject: [llvm-commits] [llvm] r127839 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <20110317235111.57EEA2A6C12C@llvm.org> Author: atrick Date: Thu Mar 17 18:51:11 2011 New Revision: 127839 URL: http://llvm.org/viewvc/llvm-project?rev=127839&view=rev Log: Added isValidRewrite() to check the result of ScalarEvolutionExpander. SCEV may generate expressions composed of multiple pointers, which can lead to invalid GEP expansion. Until we can teach SCEV to follow strict pointer rules, make sure no bad GEPs creep into IR. Fixes rdar://problem/9038671. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=127839&r1=127838&r2=127839&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Thu Mar 17 18:51:11 2011 @@ -618,6 +618,12 @@ const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS, const SCEV *RHS); + /// getPointerBase - Transitively follow the chain of pointer-type operands + /// until reaching a SCEV that does not have a single pointer operand. This + /// returns a SCEVUnknown pointer for well-formed pointer-type expressions, + /// but corner cases do exist. + const SCEV *getPointerBase(const SCEV *V); + /// getSCEVAtScope - Return a SCEV expression for the specified value /// at the specified scope in the program. The L value specifies a loop /// nest to evaluate the expression at, where null is the top-level or a Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=127839&r1=127838&r2=127839&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu Mar 17 18:51:11 2011 @@ -2718,6 +2718,36 @@ return getUMinExpr(PromotedLHS, PromotedRHS); } +/// getPointerBase - Transitively follow the chain of pointer-type operands +/// until reaching a SCEV that does not have a single pointer operand. This +/// returns a SCEVUnknown pointer for well-formed pointer-type expressions, +/// but corner cases do exist. +const SCEV *ScalarEvolution::getPointerBase(const SCEV *V) { + // A pointer operand may evaluate to a nonpointer expression, such as null. + if (!V->getType()->isPointerTy()) + return V; + + if (const SCEVCastExpr *Cast = dyn_cast(V)) { + return getPointerBase(Cast->getOperand()); + } + else if (const SCEVNAryExpr *NAry = dyn_cast(V)) { + const SCEV *PtrOp = 0; + for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end(); + I != E; ++I) { + if ((*I)->getType()->isPointerTy()) { + // Cannot find the base of an expression with multiple pointer operands. + if (PtrOp) + return V; + PtrOp = *I; + } + } + if (!PtrOp) + return V; + return getPointerBase(PtrOp); + } + return V; +} + /// PushDefUseChildren - Push users of the given Instruction /// onto the given Worklist. static void Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=127839&r1=127838&r2=127839&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Mar 17 18:51:11 2011 @@ -51,12 +51,14 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Target/TargetData.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" @@ -73,6 +75,8 @@ LoopInfo *LI; ScalarEvolution *SE; DominatorTree *DT; + const TargetData *TD; + SmallVector DeadInsts; bool Changed; public: @@ -98,6 +102,7 @@ } private: + bool isValidRewrite(Value *FromVal, Value *ToVal); void EliminateIVComparisons(); void EliminateIVRemainders(); @@ -134,6 +139,53 @@ return new IndVarSimplify(); } +/// isValidRewrite - Return true if the SCEV expansion generated by the +/// rewriter can replace the original value. SCEV guarantees that it +/// produces the same value, but the way it is produced may be illegal IR. +/// Ideally, this function will only be called for verification. +bool IndVarSimplify::isValidRewrite(Value *FromVal, Value *ToVal) { + // If an SCEV expression subsumed multiple pointers, its expansion could + // reassociate the GEP changing the base pointer. This is illegal because the + // final address produced by a GEP chain must be inbounds relative to its + // underlying object. Otherwise basic alias analysis, among other things, + // could fail in a dangerous way. Ultimately, SCEV will be improved to avoid + // producing an expression involving multiple pointers. Until then, we must + // bail out here. + // + // Retrieve the pointer operand of the GEP. Don't use GetUnderlyingObject + // because it understands lcssa phis while SCEV does not. + Value *FromPtr = FromVal; + Value *ToPtr = ToVal; + if (GEPOperator *GEP = dyn_cast(FromVal)) { + FromPtr = GEP->getPointerOperand(); + } + if (GEPOperator *GEP = dyn_cast(ToVal)) { + ToPtr = GEP->getPointerOperand(); + } + if (FromPtr != FromVal || ToPtr != ToVal) { + // Quickly check the common case + if (FromPtr == ToPtr) + return true; + + // SCEV may have rewritten an expression that produces the GEP's pointer + // operand. That's ok as long as the pointer operand has the same base + // pointer. Unlike GetUnderlyingObject(), getPointerBase() will find the + // base of a recurrence. This handles the case in which SCEV expansion + // converts a pointer type recurrence into a nonrecurrent pointer base + // indexed by an integer recurrence. + const SCEV *FromBase = SE->getPointerBase(SE->getSCEV(FromPtr)); + const SCEV *ToBase = SE->getPointerBase(SE->getSCEV(ToPtr)); + if (FromBase == ToBase) + return true; + + DEBUG(dbgs() << "INDVARS: GEP rewrite bail out " + << *FromBase << " != " << *ToBase << "\n"); + + return false; + } + return true; +} + /// LinearFunctionTestReplace - This method rewrites the exit condition of the /// loop to be a canonical != comparison against the incremented loop induction /// variable. This pass is able to rewrite the exit tests of any loop where the @@ -304,14 +356,18 @@ if (!SE->isLoopInvariant(ExitValue, L)) continue; - Changed = true; - ++NumReplaced; - Value *ExitVal = Rewriter.expandCodeFor(ExitValue, PN->getType(), Inst); DEBUG(dbgs() << "INDVARS: RLEV: AfterLoopVal = " << *ExitVal << '\n' << " LoopVal = " << *Inst << "\n"); + if (!isValidRewrite(Inst, ExitVal)) { + DeadInsts.push_back(ExitVal); + continue; + } + Changed = true; + ++NumReplaced; + PN->setIncomingValue(i, ExitVal); // If this instruction is dead now, delete it. @@ -366,8 +422,6 @@ } void IndVarSimplify::EliminateIVComparisons() { - SmallVector DeadInsts; - // Look for ICmp users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; @@ -399,18 +453,9 @@ DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); DeadInsts.push_back(ICmp); } - - // Now that we're done iterating through lists, clean up any instructions - // which are now dead. - while (!DeadInsts.empty()) - if (Instruction *Inst = - dyn_cast_or_null(&*DeadInsts.pop_back_val())) - RecursivelyDeleteTriviallyDeadInstructions(Inst); } void IndVarSimplify::EliminateIVRemainders() { - SmallVector DeadInsts; - // Look for SRem and URem users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; @@ -466,13 +511,6 @@ DEBUG(dbgs() << "INDVARS: Simplified rem: " << *Rem << '\n'); DeadInsts.push_back(Rem); } - - // Now that we're done iterating through lists, clean up any instructions - // which are now dead. - while (!DeadInsts.empty()) - if (Instruction *Inst = - dyn_cast_or_null(&*DeadInsts.pop_back_val())) - RecursivelyDeleteTriviallyDeadInstructions(Inst); } bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { @@ -491,6 +529,8 @@ LI = &getAnalysis(); SE = &getAnalysis(); DT = &getAnalysis(); + TD = getAnalysisIfAvailable(); + DeadInsts.clear(); Changed = false; // If there are any floating-point recurrences, attempt to @@ -589,9 +629,21 @@ ExitingBlock, BI, Rewriter); } - // Rewrite IV-derived expressions. Clears the rewriter cache. + // Rewrite IV-derived expressions. RewriteIVExpressions(L, Rewriter); + // Clear the rewriter cache, because values that are in the rewriter's cache + // can be deleted in the loop below, causing the AssertingVH in the cache to + // trigger. + Rewriter.clear(); + + // Now that we're done iterating through lists, clean up any instructions + // which are now dead. + while (!DeadInsts.empty()) + if (Instruction *Inst = + dyn_cast_or_null(&*DeadInsts.pop_back_val())) + RecursivelyDeleteTriviallyDeadInstructions(Inst); + // The Rewriter may not be used from this point on. // Loop-invariant instructions in the preheader that aren't used in the @@ -651,8 +703,6 @@ } void IndVarSimplify::RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter) { - SmallVector DeadInsts; - // Rewrite all induction variable expressions in terms of the canonical // induction variable. // @@ -705,6 +755,13 @@ // Now expand it into actual Instructions and patch it into place. Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt); + DEBUG(dbgs() << "INDVARS: Rewrote IV '" << *AR << "' " << *Op << '\n' + << " into = " << *NewVal << "\n"); + + if (!isValidRewrite(Op, NewVal)) { + DeadInsts.push_back(NewVal); + continue; + } // Inform ScalarEvolution that this value is changing. The change doesn't // affect its value, but it does potentially affect which use lists the // value will be on after the replacement, which affects ScalarEvolution's @@ -717,25 +774,13 @@ NewVal->takeName(Op); User->replaceUsesOfWith(Op, NewVal); UI->setOperandValToReplace(NewVal); - DEBUG(dbgs() << "INDVARS: Rewrote IV '" << *AR << "' " << *Op << '\n' - << " into = " << *NewVal << "\n"); + ++NumRemoved; Changed = true; // The old value may be dead now. DeadInsts.push_back(Op); } - - // Clear the rewriter cache, because values that are in the rewriter's cache - // can be deleted in the loop below, causing the AssertingVH in the cache to - // trigger. - Rewriter.clear(); - // Now that we're done iterating through lists, clean up any instructions - // which are now dead. - while (!DeadInsts.empty()) - if (Instruction *Inst = - dyn_cast_or_null(&*DeadInsts.pop_back_val())) - RecursivelyDeleteTriviallyDeadInstructions(Inst); } /// If there's a single exit block, sink any loop-invariant values that From resistor at mac.com Thu Mar 17 18:52:05 2011 From: resistor at mac.com (Owen Anderson) Date: Thu, 17 Mar 2011 23:52:05 -0000 Subject: [llvm-commits] [llvm] r127840 - /llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Message-ID: <20110317235205.EAB832A6C12C@llvm.org> Author: resistor Date: Thu Mar 17 18:52:05 2011 New Revision: 127840 URL: http://llvm.org/viewvc/llvm-project?rev=127840&view=rev Log: There are two pseudos in this case that are Thumb mode, not one. Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=127840&r1=127839&r2=127840&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Thu Mar 17 18:52:05 2011 @@ -894,7 +894,7 @@ const MachineOperand &MO1 = MI.getOperand(1); const GlobalValue *GV = MO1.getGlobal(); unsigned TF = MO1.getTargetFlags(); - bool isARM = Opcode != ARM::t2MOV_ga_pcrel; + bool isARM = (Opcode != ARM::t2MOV_ga_pcrel && Opcode != ARM::t2MOV_ga_dyn); bool isPIC = (Opcode != ARM::MOV_ga_dyn && Opcode != ARM::t2MOV_ga_dyn); unsigned LO16Opc = isARM ? ARM::MOVi16_ga_pcrel : ARM::t2MOVi16_ga_pcrel; unsigned HI16Opc = isARM ? ARM::MOVTi16_ga_pcrel : ARM::t2MOVTi16_ga_pcrel; From atrick at apple.com Thu Mar 17 19:36:39 2011 From: atrick at apple.com (Andrew Trick) Date: Fri, 18 Mar 2011 00:36:39 -0000 Subject: [llvm-commits] [llvm] r127842 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <20110318003639.986742A6C12C@llvm.org> Author: atrick Date: Thu Mar 17 19:36:39 2011 New Revision: 127842 URL: http://llvm.org/viewvc/llvm-project?rev=127842&view=rev Log: Remove TargetData and ValueTracking includes. I didn't mean for them to sneak in my last checkin. Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=127842&r1=127841&r2=127842&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Mar 17 19:36:39 2011 @@ -51,14 +51,12 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Target/TargetData.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" @@ -75,7 +73,6 @@ LoopInfo *LI; ScalarEvolution *SE; DominatorTree *DT; - const TargetData *TD; SmallVector DeadInsts; bool Changed; public: @@ -529,7 +526,6 @@ LI = &getAnalysis(); SE = &getAnalysis(); DT = &getAnalysis(); - TD = getAnalysisIfAvailable(); DeadInsts.clear(); Changed = false; From eli.friedman at gmail.com Thu Mar 17 19:40:50 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Thu, 17 Mar 2011 17:40:50 -0700 Subject: [llvm-commits] [llvm] r127834 - in /llvm/trunk: include/llvm/Transforms/Utils/Local.h lib/Transforms/InstCombine/InstructionCombining.cpp lib/Transforms/Utils/Local.cpp test/Transforms/InstCombine/debuginfo.ll In-Reply-To: References: <20110317221816.9ADC82A6C12C@llvm.org> Message-ID: On Thu, Mar 17, 2011 at 3:41 PM, Devang Patel wrote: > > On Mar 17, 2011, at 3:36 PM, Eli Friedman wrote: > >> On Thu, Mar 17, 2011 at 3:18 PM, Devang Patel wrote: >>> Author: dpatel >>> Date: Thu Mar 17 17:18:16 2011 >>> New Revision: 127834 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=127834&view=rev >>> Log: >>> Try to not lose variable's debug info during instcombine. >>> This is done by lowering dbg.declare intrinsic into dbg.value intrinsic. >>> Radar 9143931. >> >> This looks like the wrong solution to a problem only caused by a few >> very specific pieces of instcombine. ?Adding an extra iteration over >> every instruction in the function isn't cheap > > instcombine is already going to iterator over once. If there are compile time regressions because of this patch, I'll take a look asap. Not sure there will be; worth watch for, though. >> , and it looks like this >> could do some serious damage to the debug info for cases other than >> the given testcase. > > ? Assuming I'm reading the change correctly, take an example like the following: void foo(int* x) { *x = 10; } int bar(int i) { int a; a = i; foo(&a); return a; // If you "print a" at this point, you'll get the value of i, not 10. } -Eli From johnny.chen at apple.com Thu Mar 17 19:38:03 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 18 Mar 2011 00:38:03 -0000 Subject: [llvm-commits] [llvm] r127843 - in /llvm/trunk: lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h test/MC/Disassembler/ARM/thumb-tests.txt Message-ID: <20110318003803.316E42A6C12C@llvm.org> Author: johnny Date: Thu Mar 17 19:38:03 2011 New Revision: 127843 URL: http://llvm.org/viewvc/llvm-project?rev=127843&view=rev Log: The disassembler for Thumb was wrongly adding 4 to the computed imm32 offset. Remove the offending logic and update the test cases. Modified: llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Modified: llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h?rev=127843&r1=127842&r2=127843&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h Thu Mar 17 19:38:03 2011 @@ -962,11 +962,7 @@ unsigned Imm11 = getT1Imm11(insn); - // When executing a Thumb instruction, PC reads as the address of the current - // instruction plus 4. The assembler subtracts 4 from the difference between - // the branch instruction and the target address, disassembler has to add 4 to - // to compensate. - MI.addOperand(MCOperand::CreateImm(SignExtend32<12>(Imm11 << 1) + 4)); + MI.addOperand(MCOperand::CreateImm(SignExtend32<12>(Imm11 << 1))); NumOpsAdded = 1; @@ -1747,11 +1743,7 @@ Offset = decodeImm32_BLX(insn); break; } - // When executing a Thumb instruction, PC reads as the address of the current - // instruction plus 4. The assembler subtracts 4 from the difference between - // the branch instruction and the target address, disassembler has to add 4 to - // to compensate. - MI.addOperand(MCOperand::CreateImm(Offset + 4)); + MI.addOperand(MCOperand::CreateImm(Offset)); // This is an increment as some predicate operands may have been added first. NumOpsAdded += 1; Modified: llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt?rev=127843&r1=127842&r2=127843&view=diff ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt (original) +++ llvm/trunk/test/MC/Disassembler/ARM/thumb-tests.txt Thu Mar 17 19:38:03 2011 @@ -6,10 +6,10 @@ # CHECK: adcs r0, r0, #1 0x50 0xf1 0x01 0x00 -# CHECK: b #34 +# CHECK: b #30 0x0f 0xe0 -# CHECK: b.w #-12 +# CHECK: b.w #-16 0xff 0xf7 0xf8 0xaf # CHECK: bfi r2, r10, #0, #1 @@ -128,5 +128,5 @@ # CHECK: msr cpsr_fc, r0 0x80 0xf3 0x00 0x89 -# CHECK: blx #0 +# CHECK: blx #-4 0xff 0xf7 0xfe 0xef From eli.friedman at gmail.com Thu Mar 17 20:10:31 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Fri, 18 Mar 2011 01:10:31 -0000 Subject: [llvm-commits] [llvm] r127845 - /llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll Message-ID: <20110318011031.D0BF92A6C12C@llvm.org> Author: efriedma Date: Thu Mar 17 20:10:31 2011 New Revision: 127845 URL: http://llvm.org/viewvc/llvm-project?rev=127845&view=rev Log: FileCheck-ize and update test. Modified: llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll Modified: llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll?rev=127845&r1=127844&r2=127845&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/fold-bin-operand.ll Thu Mar 17 20:10:31 2011 @@ -1,14 +1,17 @@ -; RUN: opt < %s -instcombine -S | not grep icmp +; RUN: opt < %s -instcombine -S | FileCheck %s target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define i1 @f(i1 %x) { +; CHECK: @f +; CHECK: ret i1 false %b = and i1 %x, icmp eq (i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 2 to i8*)) ret i1 %b } -; FIXME: This doesn't fold at the moment! -; define i32 @f(i32 %x) { -; %b = add i32 %x, zext (i1 icmp eq (i8* inttoptr (i32 1000000 to i8*), i8* inttoptr (i32 2000000 to i8*)) to i32) -; ret i32 %b -;} +define i32 @g(i32 %x) { +; CHECK: @g +; CHECK: ret i32 %x + %b = add i32 %x, zext (i1 icmp eq (i8* inttoptr (i32 1000000 to i8*), i8* inttoptr (i32 2000000 to i8*)) to i32) + ret i32 %b +} From eli.friedman at gmail.com Thu Mar 17 20:24:16 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Fri, 18 Mar 2011 01:24:16 -0000 Subject: [llvm-commits] [llvm] r127847 - in /llvm/trunk: lib/ExecutionEngine/MCJIT/ lib/Target/PowerPC/InstPrinter/ lib/Target/X86/Utils/ tools/llvm-objdump/ tools/macho-dump/ Message-ID: <20110318012416.9FB572A6C12C@llvm.org> Author: efriedma Date: Thu Mar 17 20:24:16 2011 New Revision: 127847 URL: http://llvm.org/viewvc/llvm-project?rev=127847&view=rev Log: Add some svn:ignore properties. Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/ (props changed) llvm/trunk/lib/Target/PowerPC/InstPrinter/ (props changed) llvm/trunk/lib/Target/X86/Utils/ (props changed) llvm/trunk/tools/llvm-objdump/ (props changed) llvm/trunk/tools/macho-dump/ (props changed) Propchange: llvm/trunk/lib/ExecutionEngine/MCJIT/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Mar 17 20:24:16 2011 @@ -0,0 +1,10 @@ +Debug +Debug+Checks +Debug+Coverage +Debug+Coverage-Asserts +Release +Release-Asserts +Release+Coverage +Debug+Asserts +Release+Asserts + Propchange: llvm/trunk/lib/Target/PowerPC/InstPrinter/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Mar 17 20:24:16 2011 @@ -0,0 +1,10 @@ +Debug +Debug+Checks +Debug+Coverage +Debug+Coverage-Asserts +Release +Release-Asserts +Release+Coverage +Debug+Asserts +Release+Asserts + Propchange: llvm/trunk/lib/Target/X86/Utils/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Mar 17 20:24:16 2011 @@ -0,0 +1,10 @@ +Debug +Debug+Checks +Debug+Coverage +Debug+Coverage-Asserts +Release +Release-Asserts +Release+Coverage +Debug+Asserts +Release+Asserts + Propchange: llvm/trunk/tools/llvm-objdump/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Mar 17 20:24:16 2011 @@ -0,0 +1,10 @@ +Debug +Debug+Checks +Debug+Coverage +Debug+Coverage-Asserts +Release +Release-Asserts +Release+Coverage +Debug+Asserts +Release+Asserts + Propchange: llvm/trunk/tools/macho-dump/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu Mar 17 20:24:16 2011 @@ -0,0 +1,10 @@ +Debug +Debug+Checks +Debug+Coverage +Debug+Coverage-Asserts +Release +Release-Asserts +Release+Coverage +Debug+Asserts +Release+Asserts + From kremenek at apple.com Thu Mar 17 21:05:11 2011 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 18 Mar 2011 02:05:11 -0000 Subject: [llvm-commits] [llvm] r127849 - in /llvm/trunk: include/llvm/Support/CrashRecoveryContext.h lib/Support/CrashRecoveryContext.cpp Message-ID: <20110318020511.7FDD82A6C12C@llvm.org> Author: kremenek Date: Thu Mar 17 21:05:11 2011 New Revision: 127849 URL: http://llvm.org/viewvc/llvm-project?rev=127849&view=rev Log: Augment CrashRecoveryContext to have registered "cleanup" objects that can be used to release resources during a crash. Modified: llvm/trunk/include/llvm/Support/CrashRecoveryContext.h llvm/trunk/lib/Support/CrashRecoveryContext.cpp Modified: llvm/trunk/include/llvm/Support/CrashRecoveryContext.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CrashRecoveryContext.h?rev=127849&r1=127848&r2=127849&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CrashRecoveryContext.h (original) +++ llvm/trunk/include/llvm/Support/CrashRecoveryContext.h Thu Mar 17 21:05:11 2011 @@ -15,6 +15,8 @@ namespace llvm { class StringRef; +class CrashRecoveryContextCleanup; + /// \brief Crash recovery helper object. /// /// This class implements support for running operations in a safe context so @@ -42,10 +44,14 @@ /// Crash recovery contexts may not be nested. class CrashRecoveryContext { void *Impl; + CrashRecoveryContextCleanup *head; public: - CrashRecoveryContext() : Impl(0) {} + CrashRecoveryContext() : Impl(0), head(0) {} ~CrashRecoveryContext(); + + void registerCleanup(CrashRecoveryContextCleanup *cleanup); + void unregisterCleanup(CrashRecoveryContextCleanup *cleanup); /// \brief Enable crash recovery. static void Enable(); @@ -87,6 +93,64 @@ const std::string &getBacktrace() const; }; +class CrashRecoveryContextCleanup { +public: + virtual ~CrashRecoveryContextCleanup(); + virtual void recoverResources() = 0; + + template static CrashRecoveryContextCleanup *create(T *); + +private: + friend class CrashRecoveryContext; + CrashRecoveryContextCleanup *prev, *next; +}; + +template +class CrashRecoveryContextDestructorCleanup + : public CrashRecoveryContextCleanup +{ + T *resource; +public: + CrashRecoveryContextDestructorCleanup(T *resource) : resource(resource) {} + virtual void recoverResources() { + resource->~T(); + } +}; + +template +struct CrashRecoveryContextTrait { + static inline CrashRecoveryContextCleanup *createCleanup(T *resource) { + return new CrashRecoveryContextDestructorCleanup(resource); + } +}; + +template +inline CrashRecoveryContextCleanup* CrashRecoveryContextCleanup::create(T *x) { + return CrashRecoveryContext::GetCurrent() ? + CrashRecoveryContextTrait::createCleanup(x) : + 0; +} + +class CrashRecoveryContextCleanupRegistrar { + CrashRecoveryContext *context; + CrashRecoveryContextCleanup *cleanup; +public: + CrashRecoveryContextCleanupRegistrar(CrashRecoveryContextCleanup *cleanup) + : context(CrashRecoveryContext::GetCurrent()), + cleanup(cleanup) + { + if (context && cleanup) + context->registerCleanup(cleanup); + } + ~CrashRecoveryContextCleanupRegistrar() { + if (cleanup) { + if (context) + context->unregisterCleanup(cleanup); + else + delete cleanup; + } + } +}; } #endif Modified: llvm/trunk/lib/Support/CrashRecoveryContext.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CrashRecoveryContext.cpp?rev=127849&r1=127848&r2=127849&view=diff ============================================================================== --- llvm/trunk/lib/Support/CrashRecoveryContext.cpp (original) +++ llvm/trunk/lib/Support/CrashRecoveryContext.cpp Thu Mar 17 21:05:11 2011 @@ -57,7 +57,18 @@ static sys::Mutex gCrashRecoveryContexMutex; static bool gCrashRecoveryEnabled = false; +CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {} + CrashRecoveryContext::~CrashRecoveryContext() { + // Reclaim registered resources. + CrashRecoveryContextCleanup *i = head; + while (i) { + CrashRecoveryContextCleanup *tmp = i; + i = tmp->next; + tmp->recoverResources(); + delete tmp; + } + CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl; delete CRCI; } @@ -70,6 +81,33 @@ return CRCI->CRC; } +void CrashRecoveryContext::registerCleanup(CrashRecoveryContextCleanup *cleanup) +{ + if (!cleanup) + return; + if (head) + head->prev = cleanup; + cleanup->next = head; + head = cleanup; +} + +void +CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { + if (!cleanup) + return; + if (cleanup == head) { + head = cleanup->next; + if (head) + head->prev = 0; + } + else { + cleanup->prev->next = cleanup->next; + if (cleanup->next) + cleanup->next->prev = cleanup->prev; + } + delete cleanup; +} + #ifdef LLVM_ON_WIN32 // FIXME: No real Win32 implementation currently. From eli.friedman at gmail.com Thu Mar 17 21:34:11 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Fri, 18 Mar 2011 02:34:11 -0000 Subject: [llvm-commits] [llvm] r127852 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/long-setcc.ll test/CodeGen/X86/sext-i1.ll Message-ID: <20110318023411.A9B652A6C12C@llvm.org> Author: efriedma Date: Thu Mar 17 21:34:11 2011 New Revision: 127852 URL: http://llvm.org/viewvc/llvm-project?rev=127852&view=rev Log: Add a target-specific branchless method for double-width relational comparisons on x86. Essentially, the way this works is that SUB+SBB sets the relevant flags the same way a double-width CMP would. This is a substantial improvement over the generic lowering in LLVM. The output is also shorter than the gcc-generated output; I haven't done any detailed benchmarking, though. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/X86/long-setcc.ll llvm/trunk/test/CodeGen/X86/sext-i1.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127852&r1=127851&r2=127852&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Mar 17 21:34:11 2011 @@ -446,12 +446,13 @@ setOperationAction(ISD::SETCC , MVT::i8 , Custom); setOperationAction(ISD::SETCC , MVT::i16 , Custom); setOperationAction(ISD::SETCC , MVT::i32 , Custom); + setOperationAction(ISD::SETCC , MVT::i64 , Custom); setOperationAction(ISD::SETCC , MVT::f32 , Custom); setOperationAction(ISD::SETCC , MVT::f64 , Custom); setOperationAction(ISD::SETCC , MVT::f80 , Custom); if (Subtarget->is64Bit()) { setOperationAction(ISD::SELECT , MVT::i64 , Custom); - setOperationAction(ISD::SETCC , MVT::i64 , Custom); + setOperationAction(ISD::SETCC , MVT::i128 , Custom); } setOperationAction(ISD::EH_RETURN , MVT::Other, Custom); @@ -2839,7 +2840,7 @@ } else if (SetCCOpcode == ISD::SETLT && RHSC->isNullValue()) { // X < 0 -> X == 0, jump on sign. return X86::COND_S; - } else if (SetCCOpcode == ISD::SETLT && RHSC->getZExtValue() == 1) { + } else if (SetCCOpcode == ISD::SETLT && RHSC->isOne()) { // X < 1 -> X <= 0 RHS = DAG.getConstant(0, RHS.getValueType()); return X86::COND_LE; @@ -7422,7 +7423,8 @@ // Lower (X & (1 << N)) == 0 to BT(X, N). // Lower ((X >>u N) & 1) != 0 to BT(X, N). // Lower ((X >>s N) & 1) != 0 to BT(X, N). - if (Op0.getOpcode() == ISD::AND && Op0.hasOneUse() && + if (isTypeLegal(Op0.getValueType()) && + Op0.getOpcode() == ISD::AND && Op0.hasOneUse() && Op1.getOpcode() == ISD::Constant && cast(Op1)->isNullValue() && (CC == ISD::SETEQ || CC == ISD::SETNE)) { @@ -7434,7 +7436,7 @@ // Look for X == 0, X == 1, X != 0, or X != 1. We can simplify some forms of // these. if (Op1.getOpcode() == ISD::Constant && - (cast(Op1)->getZExtValue() == 1 || + (cast(Op1)->isOne() || cast(Op1)->isNullValue()) && (CC == ISD::SETEQ || CC == ISD::SETNE)) { @@ -7457,6 +7459,73 @@ if (X86CC == X86::COND_INVALID) return SDValue(); + if ((!Subtarget->is64Bit() && Op0.getValueType() == MVT::i64) || + (Subtarget->is64Bit() && Op0.getValueType() == MVT::i128)) { + switch (X86CC) { + case X86::COND_E: + case X86::COND_NE: + case X86::COND_S: + case X86::COND_NS: + // Just use the generic lowering, which works well on x86. + return SDValue(); + case X86::COND_B: + case X86::COND_AE: + case X86::COND_L: + case X86::COND_GE: + // Use SBB-based lowering. + break; + case X86::COND_A: + // Use SBB-based lowering; commute so ZF isn't used. + X86CC = X86::COND_B; + std::swap(Op0, Op1); + break; + case X86::COND_BE: + // Use SBB-based lowering; commute so ZF isn't used. + X86CC = X86::COND_AE; + std::swap(Op0, Op1); + break; + case X86::COND_G: + // Use SBB-based lowering; commute so ZF isn't used. + X86CC = X86::COND_L; + std::swap(Op0, Op1); + break; + case X86::COND_LE: + // Use SBB-based lowering; commute so ZF isn't used. + X86CC = X86::COND_GE; + std::swap(Op0, Op1); + break; + default: + assert(0 && "Unexpected X86CC."); + return SDValue(); + } + MVT HalfType = getPointerTy(); + // FIXME: Refactor this code out to implement ISD::SADDO and friends. + SDValue Op0Low = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfType, + Op0, DAG.getIntPtrConstant(0)); + SDValue Op1Low = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfType, + Op1, DAG.getIntPtrConstant(0)); + SDValue Op0High = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfType, + Op0, DAG.getIntPtrConstant(1)); + SDValue Op1High = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfType, + Op1, DAG.getIntPtrConstant(1)); + // Redirect some cases which will simplify to the generic expansion; + // X86ISD::SUB and X86ISD::SBB are not optimized well at the moment. + // FIXME: We really need to add DAGCombines for SUB/SBB/etc. + if (Op1Low.getOpcode() == ISD::Constant && + cast(Op1Low)->isNullValue()) + return SDValue(); + if (Op0Low.getOpcode() == ISD::Constant && + cast(Op0Low)->isAllOnesValue()) + return SDValue(); + SDValue res1, res2; + SDVTList VTList = DAG.getVTList(HalfType, MVT::i32); + res1 = DAG.getNode(X86ISD::SUB, dl, VTList, Op0Low, Op1Low).getValue(1); + res2 = DAG.getNode(X86ISD::SBB, dl, VTList, Op0High, Op1High, + res1).getValue(1); + return DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86CC, MVT::i8), res2); + } + SDValue EFLAGS = EmitCmp(Op0, Op1, X86CC, DAG); return DAG.getNode(X86ISD::SETCC, dl, MVT::i8, DAG.getConstant(X86CC, MVT::i8), EFLAGS); Modified: llvm/trunk/test/CodeGen/X86/long-setcc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/long-setcc.ll?rev=127852&r1=127851&r2=127852&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/long-setcc.ll (original) +++ llvm/trunk/test/CodeGen/X86/long-setcc.ll Thu Mar 17 21:34:11 2011 @@ -1,18 +1,35 @@ -; RUN: llc < %s -march=x86 | grep cmp | count 1 -; RUN: llc < %s -march=x86 | grep shr | count 1 -; RUN: llc < %s -march=x86 | grep xor | count 1 +; RUN: llc < %s -march=x86 | FileCheck %s -define i1 @t1(i64 %x) nounwind { - %B = icmp slt i64 %x, 0 - ret i1 %B +; General case +define i1 @t1(i64 %x, i64 %y) nounwind { +; CHECK: @t1 +; CHECK: subl +; CHECK: sbbl +; CHECK: setl %al + %B = icmp slt i64 %x, %y + ret i1 %B } +; Some special cases define i1 @t2(i64 %x) nounwind { - %tmp = icmp ult i64 %x, 4294967296 - ret i1 %tmp +; CHECK: @t2 +; CHECK: shrl $31, %eax + %B = icmp slt i64 %x, 0 + ret i1 %B } -define i1 @t3(i32 %x) nounwind { - %tmp = icmp ugt i32 %x, -1 - ret i1 %tmp +define i1 @t3(i64 %x) nounwind { +; CHECK: @t3 +; CHECX: cmpl $0 +; CHECX: sete %al + %tmp = icmp ult i64 %x, 4294967296 + ret i1 %tmp +} + +define i1 @t4(i64 %x) nounwind { +; CHECK: @t4 +; CHECX: cmpl $0 +; CHECX: setne %al + %tmp = icmp ugt i64 %x, 4294967295 + ret i1 %tmp } Modified: llvm/trunk/test/CodeGen/X86/sext-i1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sext-i1.ll?rev=127852&r1=127851&r2=127852&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/sext-i1.ll (original) +++ llvm/trunk/test/CodeGen/X86/sext-i1.ll Thu Mar 17 21:34:11 2011 @@ -39,7 +39,8 @@ ; 32: t3: ; 32: cmpl $1 ; 32: sbbl -; 32: cmpl +; 32: subl +; 32: sbbl ; 32: xorl ; 64: t3: From rafael.espindola at gmail.com Thu Mar 17 21:55:51 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Fri, 18 Mar 2011 02:55:51 -0000 Subject: [llvm-commits] [llvm] r127853 - /llvm/trunk/lib/Support/MemoryBuffer.cpp Message-ID: <20110318025552.08EFE2A6C12C@llvm.org> Author: rafael Date: Thu Mar 17 21:55:51 2011 New Revision: 127853 URL: http://llvm.org/viewvc/llvm-project?rev=127853&view=rev Log: Check RequiresNullTerminator first, or we might read from an invalid address. Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryBuffer.cpp?rev=127853&r1=127852&r2=127853&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Thu Mar 17 21:55:51 2011 @@ -48,7 +48,7 @@ /// memory, memory that we know is already null terminated. void MemoryBuffer::init(const char *BufStart, const char *BufEnd, bool RequiresNullTerminator) { - assert((BufEnd[0] == 0 || !RequiresNullTerminator) && + assert((!RequiresNullTerminator || BufEnd[0] == 0) && "Buffer is not null terminated!"); BufferStart = BufStart; BufferEnd = BufEnd; From kremenek at apple.com Thu Mar 17 22:04:18 2011 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 18 Mar 2011 03:04:18 -0000 Subject: [llvm-commits] [llvm] r127855 - /llvm/trunk/include/llvm/Support/CrashRecoveryContext.h Message-ID: <20110318030418.8F7222A6C12C@llvm.org> Author: kremenek Date: Thu Mar 17 22:04:18 2011 New Revision: 127855 URL: http://llvm.org/viewvc/llvm-project?rev=127855&view=rev Log: Add new CrashRecoveryContextCleanup subclass: CrashRecoveryContextDeleteCleanup. This deletes the object, not just calls its destructor. Modified: llvm/trunk/include/llvm/Support/CrashRecoveryContext.h Modified: llvm/trunk/include/llvm/Support/CrashRecoveryContext.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CrashRecoveryContext.h?rev=127855&r1=127854&r2=127855&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CrashRecoveryContext.h (original) +++ llvm/trunk/include/llvm/Support/CrashRecoveryContext.h Thu Mar 17 22:04:18 2011 @@ -116,7 +116,19 @@ resource->~T(); } }; - + +template +class CrashRecoveryContextDeleteCleanup + : public CrashRecoveryContextCleanup +{ + T *resource; +public: + CrashRecoveryContextDeleteCleanup(T *resource) : resource(resource) {} + virtual void recoverResources() { + delete resource; + } +}; + template struct CrashRecoveryContextTrait { static inline CrashRecoveryContextCleanup *createCleanup(T *resource) { From stoklund at 2pi.dk Thu Mar 17 22:06:02 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 18 Mar 2011 03:06:02 -0000 Subject: [llvm-commits] [llvm] r127856 - /llvm/trunk/lib/CodeGen/SplitKit.cpp Message-ID: <20110318030602.653C22A6C12C@llvm.org> Author: stoklund Date: Thu Mar 17 22:06:02 2011 New Revision: 127856 URL: http://llvm.org/viewvc/llvm-project?rev=127856&view=rev Log: Be more accurate about the slot index reading a register when dealing with defs and early clobbers. Assert when trying to find an undefined value. Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=127856&r1=127855&r2=127856&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Thu Mar 17 22:06:02 2011 @@ -348,6 +348,7 @@ // Using LiveOutCache as a visited set, perform a BFS for all reaching defs. for (unsigned i = 0; i != LiveIn.size(); ++i) { MachineBasicBlock *MBB = LiveIn[i]->getBlock(); + assert(!MBB->pred_empty() && "Value live-in to entry block?"); for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { MachineBasicBlock *Pred = *PI; @@ -757,7 +758,8 @@ } SlotIndex Idx = LIS.getInstructionIndex(MI); - Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex(); + if (MO.isDef()) + Idx = MO.isEarlyClobber() ? Idx.getUseIndex() : Idx.getDefIndex(); // Rewrite to the mapped register at Idx. unsigned RegIdx = RegAssign.lookup(Idx); @@ -765,9 +767,23 @@ DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t' << Idx << ':' << RegIdx << '\t' << *MI); - // Extend liveness to Idx. - if (ExtendRanges) - extendRange(RegIdx, Idx); + // Extend liveness to Idx if the instruction reads reg. + if (!ExtendRanges) + continue; + + // Skip instructions that don't read Reg. + if (MO.isDef()) { + if (!MO.getSubReg() && !MO.isEarlyClobber()) + continue; + // We may wan't to extend a live range for a partial redef, or for a use + // tied to an early clobber. + Idx = Idx.getPrevSlot(); + if (!Edit->getParent().liveAt(Idx)) + continue; + } else + Idx = Idx.getUseIndex(); + + extendRange(RegIdx, Idx); } } From stoklund at 2pi.dk Thu Mar 17 22:06:04 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 18 Mar 2011 03:06:04 -0000 Subject: [llvm-commits] [llvm] r127857 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20110318030604.9A49C2A6C12D@llvm.org> Author: stoklund Date: Thu Mar 17 22:06:04 2011 New Revision: 127857 URL: http://llvm.org/viewvc/llvm-project?rev=127857&view=rev Log: Accept instructions that read undefined values. This is not supposed to happen, but I have seen the x86 rematter getting confused when rematerializing partial redefs. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=127857&r1=127856&r2=127857&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Mar 17 22:06:04 2011 @@ -761,7 +761,15 @@ continue; SlotIndex Idx = getInstructionIndex(UseMI).getUseIndex(); VNInfo *VNI = li->getVNInfoAt(Idx); - assert(VNI && "Live interval not live into reading instruction"); + if (!VNI) { + // This shouldn't happen: readsVirtualRegister returns true, but there is + // no live value. It is likely caused by a target getting flags + // wrong. + DEBUG(dbgs() << Idx << '\t' << *UseMI + << "Warning: Instr claims to read non-existent value in " + << *li << '\n'); + continue; + } if (VNI->def == Idx) { // Special case: An early-clobber tied operand reads and writes the // register one slot early. From geek4civic at gmail.com Thu Mar 17 22:21:04 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Fri, 18 Mar 2011 03:21:04 -0000 Subject: [llvm-commits] [llvm] r127858 - /llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Message-ID: <20110318032104.D894F2A6C12C@llvm.org> Author: chapuni Date: Thu Mar 17 22:21:04 2011 New Revision: 127858 URL: http://llvm.org/viewvc/llvm-project?rev=127858&view=rev Log: llvm-bcanalyzer.cpp: Tweak format string to suppress warnings on mingw32-g++. Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=127858&r1=127857&r2=127858&view=diff ============================================================================== --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original) +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Thu Mar 17 22:21:04 2011 @@ -471,11 +471,11 @@ } static void PrintSize(double Bits) { - fprintf(stderr, "%.2f/%.2fB/%lluW", Bits, Bits/8,(unsigned long long)Bits/32); + fprintf(stderr, "%.2f/%.2fB/%luW", Bits, Bits/8,(unsigned long)(Bits/32)); } static void PrintSize(uint64_t Bits) { - fprintf(stderr, "%llub/%.2fB/%lluW", (unsigned long long)Bits, - (double)Bits/8, (unsigned long long)Bits/32); + fprintf(stderr, "%lub/%.2fB/%luW", (unsigned long)Bits, + (double)Bits/8, (unsigned long)(Bits/32)); } @@ -601,8 +601,8 @@ for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) { const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second]; - fprintf(stderr, "\t\t%7d %9llu ", RecStats.NumInstances, - (unsigned long long)RecStats.TotalBits); + fprintf(stderr, "\t\t%7d %9lu ", RecStats.NumInstances, + (unsigned long)RecStats.TotalBits); if (RecStats.NumAbbrev) fprintf(stderr, "%7.2f ", From geek4civic at gmail.com Thu Mar 17 22:21:11 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Fri, 18 Mar 2011 03:21:11 -0000 Subject: [llvm-commits] [llvm] r127859 - /llvm/trunk/tools/lto/LTOModule.cpp Message-ID: <20110318032111.9A5AD2A6C12C@llvm.org> Author: chapuni Date: Thu Mar 17 22:21:11 2011 New Revision: 127859 URL: http://llvm.org/viewvc/llvm-project?rev=127859&view=rev Log: tools/lto/LTOModule.cpp: Eliminate an unused variable. Modified: llvm/trunk/tools/lto/LTOModule.cpp Modified: llvm/trunk/tools/lto/LTOModule.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=127859&r1=127858&r2=127859&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOModule.cpp (original) +++ llvm/trunk/tools/lto/LTOModule.cpp Thu Mar 17 22:21:11 2011 @@ -117,7 +117,6 @@ /// makeBuffer - Create a MemoryBuffer from a memory range. MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) { const char *startPtr = (char*)mem; - const char *endPtr = startPtr+length; return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false); } From rafael.espindola at gmail.com Thu Mar 17 22:46:17 2011 From: rafael.espindola at gmail.com (=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?=) Date: Thu, 17 Mar 2011 23:46:17 -0400 Subject: [llvm-commits] Why isn't the integrated as used with -static? Message-ID: <4D82D589.5080106@gmail.com> Driver.cpp has // FIXME: This doesn't belong here, but ideally we will support static soon // anyway. bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) || C.getArgs().hasArg(options::OPT_static) || C.getArgs().hasArg(options::OPT_fapple_kext)); That comment was added on 2010-05-14. Do we support -static now? :-) If not, is it ok to make this an OS X only test? Cheers, Rafael From kremenek at apple.com Thu Mar 17 22:46:21 2011 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 18 Mar 2011 03:46:21 -0000 Subject: [llvm-commits] [llvm] r127865 - /llvm/trunk/include/llvm/Support/CrashRecoveryContext.h Message-ID: <20110318034621.4583F2A6C12C@llvm.org> Author: kremenek Date: Thu Mar 17 22:46:21 2011 New Revision: 127865 URL: http://llvm.org/viewvc/llvm-project?rev=127865&view=rev Log: Tweak CrashRecoveryContextCleanup::createCleanup() to use the 'delete' cleanup as opposed to the 'destructor' cleanup (reclaims more memory). Modified: llvm/trunk/include/llvm/Support/CrashRecoveryContext.h Modified: llvm/trunk/include/llvm/Support/CrashRecoveryContext.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CrashRecoveryContext.h?rev=127865&r1=127864&r2=127865&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CrashRecoveryContext.h (original) +++ llvm/trunk/include/llvm/Support/CrashRecoveryContext.h Thu Mar 17 22:46:21 2011 @@ -132,7 +132,7 @@ template struct CrashRecoveryContextTrait { static inline CrashRecoveryContextCleanup *createCleanup(T *resource) { - return new CrashRecoveryContextDestructorCleanup(resource); + return new CrashRecoveryContextDeleteCleanup(resource); } }; From rafael.espindola at gmail.com Thu Mar 17 23:07:44 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Fri, 18 Mar 2011 04:07:44 -0000 Subject: [llvm-commits] [llvm] r127867 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <20110318040744.57D602A6C12C@llvm.org> Author: rafael Date: Thu Mar 17 23:07:44 2011 New Revision: 127867 URL: http://llvm.org/viewvc/llvm-project?rev=127867&view=rev Log: Some release notes. Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=127867&r1=127866&r2=127867&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Thu Mar 17 23:07:44 2011 @@ -347,7 +347,9 @@ release includes a few major enhancements and additions to the optimizers:

    -TBAA. +
  • TBAA.
  • +
  • LTO has been improved to use MC for parsing inline asm and now + can build large programs like Firefox 4 on both OS X and Linux.

@@ -504,7 +492,7 @@

This pass statically checks for common and easily-identified constructs @@ -535,15 +523,7 @@

-
-

LLVM IR Value liveness analysis pass.

-
- - -

@@ -569,7 +549,7 @@

This pass decodes the debug info metadata in a module and prints in a @@ -857,21 +837,6 @@

-
-

ABCD removes conditional branch instructions that can be proved redundant. - With the SSI representation, each variable has a constraint. By analyzing these - constraints we can prove that a branch is redundant. When a branch is proved - redundant it means that one direction will always be taken; thus, we can change - this branch into an unconditional jump.

-

It is advisable to run SimplifyCFG and - Aggressive Dead Code Elimination after ABCD - to clean up the code.

-
- - -
@@ -1284,7 +1249,7 @@

@@ -1378,7 +1343,7 @@

@@ -1416,17 +1381,6 @@

-
-

- This pass divides loop's iteration range by spliting loop such that each - individual loop is executed efficiently. -

-
- - -
@@ -1664,7 +1618,7 @@

@@ -1717,22 +1671,6 @@

-
-

This pass finds function arguments that are often a common constant and - specializes a version of the called function for that constant. - - This pass simply does the cloning for functions it specializes. It depends - on IPSCCP and DAE to clean up the results. - - The initial heuristic favors constant arguments that are used in control - flow. -

-
- - -
@@ -1786,7 +1724,7 @@

@@ -1854,16 +1792,6 @@

-
-

Simple pass that applies an experimental transformation on calls - to specific functions. -

-
- - -
@@ -1883,43 +1811,6 @@ -
-

This function breaks GEPs with more than 2 non-zero operands into smaller - GEPs each with no more than 2 non-zero operands. This exposes redundancy - between GEPs with common initial operand sequences. -

-
- - - -
-

This pass converts a list of variables to the Static Single Information - form. - - We are building an on-demand representation, that is, we do not convert - every single variable in the target function to SSI form. Rather, we receive - a list of target variables that must be converted. We also do not - completely convert a target variable to the SSI format. Instead, we only - change the variable in the points where new information can be attached - to its live range, that is, at branch points. -

-
- - - -
-

A pass that runs SSI on every non-void variable, intended for debugging. -

-
- - -
@@ -1942,7 +1833,7 @@

@@ -2187,7 +2078,7 @@

@@ -2197,7 +2088,7 @@

@@ -2210,7 +2101,7 @@

@@ -2220,7 +2111,7 @@

From eli.friedman at gmail.com Fri Mar 18 23:55:29 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Sat, 19 Mar 2011 04:55:29 -0000 Subject: [llvm-commits] [llvm] r127947 - /llvm/trunk/docs/Passes.html Message-ID: <20110319045529.75CEB2A6C12C@llvm.org> Author: efriedma Date: Fri Mar 18 23:55:29 2011 New Revision: 127947 URL: http://llvm.org/viewvc/llvm-project?rev=127947&view=rev Log: Update Passes.html, part 2: cleanup a bit more dead docs, a few more description updates. Modified: llvm/trunk/docs/Passes.html Modified: llvm/trunk/docs/Passes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Passes.html?rev=127947&r1=127946&r2=127947&view=diff ============================================================================== --- llvm/trunk/docs/Passes.html (original) +++ llvm/trunk/docs/Passes.html Fri Mar 18 23:55:29 2011 @@ -245,18 +245,6 @@ -
-

- This pass munges the code in the input function to better prepare it for - SelectionDAG-based code generation. This works around limitations in it's - basic-block-at-a-time approach. It should eventually be removed. -

-
- - -
@@ -344,7 +332,7 @@

@@ -356,8 +344,7 @@

@@ -370,7 +357,7 @@

@@ -382,8 +369,7 @@

@@ -419,29 +405,6 @@

-
-

This pass implements a simple N^2 alias analysis accuracy evaluator. - Basically, for each function in the program, it simply queries to see how the - alias analysis implementation answers alias queries between each pair of - pointers in the function. -

-
- - - -
-

This pass defines the default implementation of the Alias Analysis interface - that simply implements a few identities (two different globals cannot alias, - etc), but otherwise does no analysis. -

-
- - -
@@ -585,15 +548,6 @@ -
-

Tracking of pointer bounds. -

-
- - -
@@ -752,7 +706,7 @@

Pass that checks profiling information for plausibility.

@@ -784,7 +738,7 @@

Simple alias analysis implemented in terms of ScalarEvolution queries. @@ -913,7 +867,7 @@

This pass munges the code in the input function to better prepare it for @@ -1486,23 +1440,7 @@ -
-

- Turn malloc and free instructions into @malloc and - @free calls. -

- -

- This is a target-dependent tranformation because it depends on the size of - data types and alignment constraints. -

-
- - -

From eli.friedman at gmail.com Sat Mar 19 00:02:14 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Sat, 19 Mar 2011 05:02:14 -0000 Subject: [llvm-commits] [llvm] r127948 - /llvm/trunk/docs/Passes.html Message-ID: <20110319050214.7C6882A6C12C@llvm.org> Author: efriedma Date: Sat Mar 19 00:02:14 2011 New Revision: 127948 URL: http://llvm.org/viewvc/llvm-project?rev=127948&view=rev Log: Update Passes.html, part 3: alphabetize descriptions. Modified: llvm/trunk/docs/Passes.html Modified: llvm/trunk/docs/Passes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Passes.html?rev=127948&r1=127947&r2=127948&view=diff ============================================================================== --- llvm/trunk/docs/Passes.html (original) +++ llvm/trunk/docs/Passes.html Sat Mar 19 00:02:14 2011 @@ -754,28 +754,6 @@

-
-

- performs code stripping. this transformation can delete: -

- -
    -
  1. names for virtual registers
  2. -
  3. symbols for internal globals and functions
  4. -
  5. debug information
  6. -
- -

- note that this transformation makes code much less readable, so it should - only be used in situations where the strip utility would be used, - such as reducing code size or making it harder to reverse engineer code. -

-
- - -
@@ -1295,6 +1273,7 @@ variable.
+
-loop-deletion: Delete dead loops @@ -1357,6 +1336,47 @@ +
+

+ This pass performs several transformations to transform natural loops into a + simpler form, which makes subsequent analyses and transformations simpler and + more effective. +

+ +

+ Loop pre-header insertion guarantees that there is a single, non-critical + entry edge from outside of the loop to the loop header. This simplifies a + number of analyses and transformations, such as LICM. +

+ +

+ Loop exit-block insertion guarantees that all exit blocks from the loop + (blocks which are outside of the loop that have predecessors inside of the + loop) only have predecessors from inside of the loop (and are thus dominated + by the loop header). This simplifies transformations such as store-sinking + that are built into LICM. +

+ +

+ This pass also guarantees that loops will have exactly one backedge. +

+ +

+ Note that the simplifycfg pass will clean up blocks which are split out but + end up being unnecessary, so usage of this pass should not pessimize + generated code. +

+ +

+ This pass obviously modifies the CFG, but updates loop information and + dominator information. +

+
+ + +
@@ -1399,47 +1419,6 @@ -
-

- This pass performs several transformations to transform natural loops into a - simpler form, which makes subsequent analyses and transformations simpler and - more effective. -

- -

- Loop pre-header insertion guarantees that there is a single, non-critical - entry edge from outside of the loop to the loop header. This simplifies a - number of analyses and transformations, such as LICM. -

- -

- Loop exit-block insertion guarantees that all exit blocks from the loop - (blocks which are outside of the loop that have predecessors inside of the - loop) only have predecessors from inside of the loop (and are thus dominated - by the loop header). This simplifies transformations such as store-sinking - that are built into LICM. -

- -

- This pass also guarantees that loops will have exactly one backedge. -

- -

- Note that the simplifycfg pass will clean up blocks which are split out but - end up being unnecessary, so usage of this pass should not pessimize - generated code. -

- -

- This pass obviously modifies the CFG, but updates loop information and - dominator information. -

-
- - -
@@ -1707,16 +1686,6 @@ -
-

This pass moves instructions into successor blocks, when possible, so that - they aren't executed on paths where their results aren't needed. -

-
- - -
@@ -1749,6 +1718,39 @@ +
+

This pass moves instructions into successor blocks, when possible, so that + they aren't executed on paths where their results aren't needed. +

+
+ + + +
+

+ This pass finds functions that return a struct (using a pointer to the struct + as the first argument of the function, marked with the 'sret' attribute) and + replaces them with a new function that simply returns each of the elements of + that struct (using multiple return values). +

+ +

+ This pass works under a number of conditions: +

+ +
    +
  • The returned struct must not contain other structs
  • +
  • The returned struct must only be used to load values from
  • +
  • The placeholder struct passed in is the result of an alloca
  • +
+
+ + +
@@ -1771,6 +1773,28 @@ +
+

+ performs code stripping. this transformation can delete: +

+ +
    +
  1. names for virtual registers
  2. +
  3. symbols for internal globals and functions
  4. +
  5. debug information
  6. +
+ +

+ note that this transformation makes code much less readable, so it should + only be used in situations where the strip utility would be used, + such as reducing code size or making it harder to reverse engineer code. +

+
+ + +
@@ -1820,29 +1844,6 @@ -
-

- This pass finds functions that return a struct (using a pointer to the struct - as the first argument of the function, marked with the 'sret' attribute) and - replaces them with a new function that simply returns each of the elements of - that struct (using multiple return values). -

- -

- This pass works under a number of conditions: -

- -
    -
  • The returned struct must not contain other structs
  • -
  • The returned struct must only be used to load values from
  • -
  • The placeholder struct passed in is the result of an alloca
  • -
-
- - -
@@ -2026,9 +2027,7 @@

@@ -2049,9 +2048,7 @@

From fvbommel at gmail.com Sat Mar 19 02:31:41 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sat, 19 Mar 2011 08:31:41 +0100 Subject: [llvm-commits] [llvm] r127922 - /llvm/trunk/lib/Transforms/Utils/Local.cpp In-Reply-To: <20110318232802.31BA52A6C12C@llvm.org> References: <20110318232802.31BA52A6C12C@llvm.org> Message-ID: On Sat, Mar 19, 2011 at 12:28 AM, Devang Patel wrote: > - ?// We don't want debug info removed by anything this general. > + ?// We don't want debug info removed by anything this general, unless > + ?// debug info is empty. > + ?if (DbgDeclareInst *DDI = dyn_cast(I)) { > + ? ?if (DDI->getAddress()) > + ? ? ?return false; > + ? ?else > + ? ? ?return true; > + ?} else if (DbgValueInst *DVI = dyn_cast(I)) { > + ? ?if (DVI->getValue()) > + ? ? ?return false; > + ? ?else > + ? ? ?return true; > + ?} None of those three 'else's are needed, their 'then' cases all end in 'return'. From nadav.rotem at intel.com Sat Mar 19 08:09:10 2011 From: nadav.rotem at intel.com (Nadav Rotem) Date: Sat, 19 Mar 2011 13:09:10 -0000 Subject: [llvm-commits] [llvm] r127951 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/vec_uint_to_fp.ll Message-ID: <20110319130910.ADE812A6C12D@llvm.org> Author: nadav Date: Sat Mar 19 08:09:10 2011 New Revision: 127951 URL: http://llvm.org/viewvc/llvm-project?rev=127951&view=rev Log: Add support for legalizing UINT_TO_FP of vectors on platforms which do not have native support for this operation (such as X86). The legalized code uses two vector INT_TO_FP operations and is faster than scalarizing. Added: llvm/trunk/test/CodeGen/X86/vec_uint_to_fp.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp?rev=127951&r1=127950&r2=127951&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp Sat Mar 19 08:09:10 2011 @@ -58,6 +58,9 @@ SDValue UnrollVSETCC(SDValue Op); // Implements expansion for FNEG; falls back to UnrollVectorOp if FSUB // isn't legal. + // Implements expansion for UINT_TO_FLOAT; falls back to UnrollVectorOp if + // SINT_TO_FLOAT and SHR on vectors isn't legal. + SDValue ExpandUINT_TO_FLOAT(SDValue Op); SDValue ExpandFNEG(SDValue Op); // Implements vector promotion; this is essentially just bitcasting the // operands to a different type and bitcasting the result back to the @@ -207,7 +210,9 @@ // FALL THROUGH } case TargetLowering::Expand: - if (Node->getOpcode() == ISD::FNEG) + if (Node->getOpcode() == ISD::UINT_TO_FP) + Result = ExpandUINT_TO_FLOAT(Op); + else if (Node->getOpcode() == ISD::FNEG) Result = ExpandFNEG(Op); else if (Node->getOpcode() == ISD::VSETCC) Result = UnrollVSETCC(Op); @@ -251,6 +256,48 @@ return DAG.getNode(ISD::BITCAST, dl, VT, Op); } +SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) { + + + EVT VT = Op.getOperand(0).getValueType(); + DebugLoc DL = Op.getDebugLoc(); + + // Make sure that the SINT_TO_FP and SRL instructions are available. + if (!TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, VT) || + !TLI.isOperationLegalOrCustom(ISD::SRL, VT)) + return DAG.UnrollVectorOp(Op.getNode()); + + EVT SVT = VT.getScalarType(); + assert((SVT.getSizeInBits() == 64 || SVT.getSizeInBits() == 32) && + "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide"); + + unsigned BW = SVT.getSizeInBits(); + SDValue HalfWord = DAG.getConstant(BW/2, VT); + + // Constants to clear the upper part of the word. + // Notice that we can also use SHL+SHR, but using a constant is slightly + // faster on x86. + uint64_t HWMask = (SVT.getSizeInBits()==64)?0x00000000FFFFFFFF:0x0000FFFF; + SDValue HalfWordMask = DAG.getConstant(HWMask, VT); + + // Two to the power of half-word-size. + SDValue TWOHW = DAG.getConstantFP((1<<(BW/2)), Op.getValueType()); + + // Clear upper part of LO, lower HI + SDValue HI = DAG.getNode(ISD::SRL, DL, VT, Op.getOperand(0), HalfWord); + SDValue LO = DAG.getNode(ISD::AND, DL, VT, Op.getOperand(0), HalfWordMask); + + // Convert hi and lo to floats + // Convert the hi part back to the upper values + SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), HI); + fHI = DAG.getNode(ISD::FMUL, DL, Op.getValueType(), fHI, TWOHW); + SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), LO); + + // Add the two halves + return DAG.getNode(ISD::FADD, DL, Op.getValueType(), fHI, fLO); +} + + SDValue VectorLegalizer::ExpandFNEG(SDValue Op) { if (TLI.isOperationLegalOrCustom(ISD::FSUB, Op.getValueType())) { SDValue Zero = DAG.getConstantFP(-0.0, Op.getValueType()); Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127951&r1=127950&r2=127951&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Mar 19 08:09:10 2011 @@ -927,6 +927,7 @@ // Can turn SHL into an integer multiply. setOperationAction(ISD::SHL, MVT::v4i32, Custom); setOperationAction(ISD::SHL, MVT::v16i8, Custom); + setOperationAction(ISD::SRL, MVT::v4i32, Legal); // i8 and i16 vectors are custom , because the source register and source // source memory operand types are not the same width. f32 vectors are Added: llvm/trunk/test/CodeGen/X86/vec_uint_to_fp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_uint_to_fp.ll?rev=127951&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_uint_to_fp.ll (added) +++ llvm/trunk/test/CodeGen/X86/vec_uint_to_fp.ll Sat Mar 19 08:09:10 2011 @@ -0,0 +1,11 @@ +; RUN: llc < %s -march=x86 -mcpu=sandybridge | FileCheck %s + +; Test that we are not lowering uinttofp to scalars +define <4 x float> @test1(<4 x i32> %A) nounwind { +; CHECK: test1: +; CHECK-NOT: cvtsd2ss +; CHECK: ret + %C = uitofp <4 x i32> %A to <4 x float> + ret <4 x float> %C +} + From evan.cheng at apple.com Sat Mar 19 11:53:03 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 19 Mar 2011 09:53:03 -0700 Subject: [llvm-commits] [llvm] r127913 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/ARM/rev.ll In-Reply-To: <20110318215243.2316C2A6C12C@llvm.org> References: <20110318215243.2316C2A6C12C@llvm.org> Message-ID: <583682E0-8EB9-474D-9D29-6751EA5251C5@apple.com> A better fix might be to canonicalize (sext_inreg (or (srl $R, 8), (shl $R, 8)), i16) to (sra (bswap $R), 16). I'll implement that as soon as I have a chance. Evan On Mar 18, 2011, at 2:52 PM, Evan Cheng wrote: > Author: evancheng > Date: Fri Mar 18 16:52:42 2011 > New Revision: 127913 > > URL: http://llvm.org/viewvc/llvm-project?rev=127913&view=rev > Log: > Match a few more obvious patterns to revsh. rdar://9147637. > > Modified: > llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td > llvm/trunk/test/CodeGen/ARM/rev.ll > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=127913&r1=127912&r2=127913&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri Mar 18 16:52:42 2011 > @@ -2976,10 +2976,18 @@ > IIC_iUNAr, "revsh", "\t$Rd, $Rm", > [(set GPR:$Rd, > (sext_inreg > - (or (srl (and GPR:$Rm, 0xFF00), (i32 8)), > + (or (srl GPR:$Rm, (i32 8)), > (shl GPR:$Rm, (i32 8))), i16))]>, > Requires<[IsARM, HasV6]>; > > +def : ARMV6Pat<(sext_inreg (or (srl (and GPR:$Rm, 0xFF00), (i32 8)), > + (shl GPR:$Rm, (i32 8))), i16), > + (REVSH GPR:$Rm)>; > + > +// Need the AddedComplexity or else MOVs + REV would be chosen. > +let AddedComplexity = 5 in > +def : ARMV6Pat<(sra (bswap GPR:$Rm), (i32 16)), (REVSH GPR:$Rm)>; > + > def lsl_shift_imm : SDNodeXForm unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue()); > return CurDAG->getTargetConstant(Sh, MVT::i32); > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=127913&r1=127912&r2=127913&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Fri Mar 18 16:52:42 2011 > @@ -2579,9 +2579,15 @@ > "revsh", ".w\t$Rd, $Rm", > [(set rGPR:$Rd, > (sext_inreg > - (or (srl (and rGPR:$Rm, 0xFF00), (i32 8)), > + (or (srl rGPR:$Rm, (i32 8)), > (shl rGPR:$Rm, (i32 8))), i16))]>; > > +def : T2Pat<(sext_inreg (or (srl (and rGPR:$Rm, 0xFF00), (i32 8)), > + (shl rGPR:$Rm, (i32 8))), i16), > + (t2REVSH rGPR:$Rm)>; > + > +def : T2Pat<(sra (bswap rGPR:$Rm), (i32 16)), (t2REVSH rGPR:$Rm)>; > + > def t2PKHBT : T2ThreeReg< > (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh), > IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", > > Modified: llvm/trunk/test/CodeGen/ARM/rev.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/rev.ll?rev=127913&r1=127912&r2=127913&view=diff > ============================================================================== > --- llvm/trunk/test/CodeGen/ARM/rev.ll (original) > +++ llvm/trunk/test/CodeGen/ARM/rev.ll Fri Mar 18 16:52:42 2011 > @@ -1,6 +1,6 @@ > ; RUN: llc < %s -march=arm -mattr=+v6 | FileCheck %s > > -define i32 @test1(i32 %X) { > +define i32 @test1(i32 %X) nounwind { > ; CHECK: test1 > ; CHECK: rev16 r0, r0 > %tmp1 = lshr i32 %X, 8 > @@ -16,7 +16,7 @@ > ret i32 %tmp14 > } > > -define i32 @test2(i32 %X) { > +define i32 @test2(i32 %X) nounwind { > ; CHECK: test2 > ; CHECK: revsh r0, r0 > %tmp1 = lshr i32 %X, 8 > @@ -28,3 +28,29 @@ > %tmp5.upgrd.2 = sext i16 %tmp5 to i32 > ret i32 %tmp5.upgrd.2 > } > + > +; rdar://9147637 > +define i32 @test3(i16 zeroext %a) nounwind { > +entry: > +; CHECK: test3: > +; CHECK: revsh r0, r0 > + %0 = tail call i16 @llvm.bswap.i16(i16 %a) > + %1 = sext i16 %0 to i32 > + ret i32 %1 > +} > + > +declare i16 @llvm.bswap.i16(i16) nounwind readnone > + > +define i32 @test4(i16 zeroext %a) nounwind { > +entry: > +; CHECK: test4: > +; CHECK: revsh r0, r0 > + %conv = zext i16 %a to i32 > + %shr9 = lshr i16 %a, 8 > + %conv2 = zext i16 %shr9 to i32 > + %shl = shl nuw nsw i32 %conv, 8 > + %or = or i32 %conv2, %shl > + %sext = shl i32 %or, 16 > + %conv8 = ashr exact i32 %sext, 16 > + ret i32 %conv8 > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Sat Mar 19 12:03:16 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 19 Mar 2011 17:03:16 -0000 Subject: [llvm-commits] [llvm] r127952 - /llvm/trunk/lib/CodeGen/Analysis.cpp Message-ID: <20110319170316.51A392A6C12C@llvm.org> Author: evancheng Date: Sat Mar 19 12:03:16 2011 New Revision: 127952 URL: http://llvm.org/viewvc/llvm-project?rev=127952&view=rev Log: Minor code re-structuring. Modified: llvm/trunk/lib/CodeGen/Analysis.cpp Modified: llvm/trunk/lib/CodeGen/Analysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Analysis.cpp?rev=127952&r1=127951&r2=127952&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Analysis.cpp (original) +++ llvm/trunk/lib/CodeGen/Analysis.cpp Sat Mar 19 12:03:16 2011 @@ -211,7 +211,6 @@ const BasicBlock *ExitBB = I->getParent(); const TerminatorInst *Term = ExitBB->getTerminator(); const ReturnInst *Ret = dyn_cast(Term); - const Function *F = ExitBB->getParent(); // The block must end in a return statement or unreachable. // @@ -250,6 +249,7 @@ // Conservatively require the attributes of the call to match those of // the return. Ignore noalias because it doesn't affect the call sequence. + const Function *F = ExitBB->getParent(); unsigned CallerRetAttr = F->getAttributes().getRetAttributes(); if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias) return false; From evan.cheng at apple.com Sat Mar 19 12:17:40 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 19 Mar 2011 17:17:40 -0000 Subject: [llvm-commits] [llvm] r127953 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h lib/Transforms/Scalar/CodeGenPrepare.cpp test/CodeGen/X86/tailcall-cgp-dup.ll Message-ID: <20110319171740.4B43F2A6C12C@llvm.org> Author: evancheng Date: Sat Mar 19 12:17:39 2011 New Revision: 127953 URL: http://llvm.org/viewvc/llvm-project?rev=127953&view=rev Log: SimplifyCFG has stopped duplicating returns into predecessors to canonicalize IR to have single return block (at least getting there) for optimizations. This is general goodness but it would prevent some tailcall optimizations. One specific case is code like this: int f1(void); int f2(void); int f3(void); int f4(void); int f5(void); int f6(void); int foo(int x) { switch(x) { case 1: return f1(); case 2: return f2(); case 3: return f3(); case 4: return f4(); case 5: return f5(); case 6: return f6(); } } => LBB0_2: ## %sw.bb callq _f1 popq %rbp ret LBB0_3: ## %sw.bb1 callq _f2 popq %rbp ret LBB0_4: ## %sw.bb3 callq _f3 popq %rbp ret This patch teaches codegenprep to duplicate returns when the return value is a phi and where the phi operands are produced by tail calls followed by an unconditional branch: sw.bb7: ; preds = %entry %call8 = tail call i32 @f5() nounwind br label %return sw.bb9: ; preds = %entry %call10 = tail call i32 @f6() nounwind br label %return return: %retval.0 = phi i32 [ %call10, %sw.bb9 ], [ %call8, %sw.bb7 ], ... [ 0, %entry ] ret i32 %retval.0 This allows codegen to generate better code like this: LBB0_2: ## %sw.bb jmp _f1 ## TAILCALL LBB0_3: ## %sw.bb1 jmp _f2 ## TAILCALL LBB0_4: ## %sw.bb3 jmp _f3 ## TAILCALL rdar://9147433 Added: llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127953&r1=127952&r2=127953&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Sat Mar 19 12:17:39 2011 @@ -1287,6 +1287,14 @@ return false; } + /// mayBeEmittedAsTailCall - Return true if the target may be able emit the + /// call instruction as a tail call. This is used by optimization passes to + /// determine if it's profitable to duplicate return instructions to enable + /// tailcall optimization. + virtual bool mayBeEmittedAsTailCall(CallInst *CI) const { + return false; + } + /// getTypeForExtArgOrReturn - Return the type that should be used to zero or /// sign extend a zeroext/signext integer argument or return value. /// FIXME: Most C calling convention requires the return type to be promoted, Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127953&r1=127952&r2=127953&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Sat Mar 19 12:17:39 2011 @@ -1805,6 +1805,16 @@ return HasRet; } +bool ARMTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { + if (!EnableARMTailCalls) + return false; + + if (!CI->isTailCall()) + return false; + + return !Subtarget->isThumb1Only(); +} + // ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as // their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is // one of the above mentioned nodes. It has to be wrapped because otherwise Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=127953&r1=127952&r2=127953&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Sat Mar 19 12:17:39 2011 @@ -457,6 +457,8 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; + virtual bool mayBeEmittedAsTailCall(CallInst *CI) const; + SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &ARMcc, SelectionDAG &DAG, DebugLoc dl) const; SDValue getVFPCmp(SDValue LHS, SDValue RHS, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127953&r1=127952&r2=127953&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Mar 19 12:17:39 2011 @@ -45,6 +45,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/VectorExtras.h" +#include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" @@ -1595,6 +1596,18 @@ return (CC == CallingConv::Fast || CC == CallingConv::GHC); } +bool X86TargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { + if (!CI->isTailCall()) + return false; + + CallSite CS(CI); + CallingConv::ID CalleeCC = CS.getCallingConv(); + if (!IsTailCallConvention(CalleeCC) && CalleeCC != CallingConv::C) + return false; + + return true; +} + /// FuncIsMadeTailCallSafe - Return true if the function is being made into /// a tailcall target by changing its ABI. static bool FuncIsMadeTailCallSafe(CallingConv::ID CC) { Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127953&r1=127952&r2=127953&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Sat Mar 19 12:17:39 2011 @@ -843,6 +843,8 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; + virtual bool mayBeEmittedAsTailCall(CallInst *CI) const; + virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, ISD::NodeType ExtendKind) const; Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=127953&r1=127952&r2=127953&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Sat Mar 19 12:17:39 2011 @@ -47,16 +47,17 @@ using namespace llvm::PatternMatch; STATISTIC(NumBlocksElim, "Number of blocks eliminated"); -STATISTIC(NumPHIsElim, "Number of trivial PHIs eliminated"); -STATISTIC(NumGEPsElim, "Number of GEPs converted to casts"); +STATISTIC(NumPHIsElim, "Number of trivial PHIs eliminated"); +STATISTIC(NumGEPsElim, "Number of GEPs converted to casts"); STATISTIC(NumCmpUses, "Number of uses of Cmp expressions replaced with uses of " "sunken Cmps"); STATISTIC(NumCastUses, "Number of uses of Cast expressions replaced with uses " "of sunken Casts"); STATISTIC(NumMemoryInsts, "Number of memory instructions whose address " "computations were sunk"); -STATISTIC(NumExtsMoved, "Number of [s|z]ext instructions combined with loads"); -STATISTIC(NumExtUses, "Number of uses of [s|z]ext instructions optimized"); +STATISTIC(NumExtsMoved, "Number of [s|z]ext instructions combined with loads"); +STATISTIC(NumExtUses, "Number of uses of [s|z]ext instructions optimized"); +STATISTIC(NumRetsDup, "Number of return instructions duplicated"); static cl::opt DisableBranchOpts( "disable-cgp-branch-opts", cl::Hidden, cl::init(false), @@ -104,6 +105,7 @@ bool OptimizeCallInst(CallInst *CI); bool MoveExtToFormExtLoad(Instruction *I); bool OptimizeExtUses(Instruction *I); + bool DupRetToEnableTailCallOpts(ReturnInst *RI); }; } @@ -547,6 +549,96 @@ return Simplifier.fold(CI, TD); } +/// DupRetToEnableTailCallOpts - Look for opportunities to duplicate return +/// instructions to the predecessor to enable tail call optimizations. The +/// case it is currently looking for is: +/// bb0: +/// %tmp0 = tail call i32 @f0() +/// br label %return +/// bb1: +/// %tmp1 = tail call i32 @f1() +/// br label %return +/// bb2: +/// %tmp2 = tail call i32 @f2() +/// br label %return +/// return: +/// %retval = phi i32 [ %tmp0, %bb0 ], [ %tmp1, %bb1 ], [ %tmp2, %bb2 ] +/// ret i32 %retval +/// +/// => +/// +/// bb0: +/// %tmp0 = tail call i32 @f0() +/// ret i32 %tmp0 +/// bb1: +/// %tmp1 = tail call i32 @f1() +/// ret i32 %tmp1 +/// bb2: +/// %tmp2 = tail call i32 @f2() +/// ret i32 %tmp2 +/// +bool CodeGenPrepare::DupRetToEnableTailCallOpts(ReturnInst *RI) { + Value *V = RI->getReturnValue(); + if (!V) + return false; + + if (PHINode *PN = dyn_cast(V)) { + BasicBlock *BB = RI->getParent(); + if (PN->getParent() != BB) + return false; + + // It's not safe to eliminate the sign / zero extension of the return value. + // See llvm::isInTailCallPosition(). + const Function *F = BB->getParent(); + unsigned CallerRetAttr = F->getAttributes().getRetAttributes(); + if ((CallerRetAttr & Attribute::ZExt) || (CallerRetAttr & Attribute::SExt)) + return false; + + // Make sure there are no instructions between PHI and return. + BasicBlock::iterator BI = PN; + do { ++BI; } while (isa(BI)); + if (&*BI != RI) + return false; + + /// Only dup the ReturnInst if the CallInst is likely to be emitted as a + /// tail call. + SmallVector TailCalls; + for (unsigned I = 0, E = PN->getNumIncomingValues(); I != E; ++I) { + CallInst *CI = dyn_cast(PN->getIncomingValue(I)); + if (CI && TLI->mayBeEmittedAsTailCall(CI)) + TailCalls.push_back(CI); + } + + bool Changed = false; + for (unsigned i = 0, e = TailCalls.size(); i != e; ++i) { + CallInst *CI = TailCalls[i]; + CallSite CS(CI); + + // Conservatively require the attributes of the call to match those of + // the return. Ignore noalias because it doesn't affect the call sequence. + unsigned CalleeRetAttr = CS.getAttributes().getRetAttributes(); + if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias) + continue; + + // Make sure the call instruction is followed by an unconditional branch + // to the return block. + BasicBlock *CallBB = CI->getParent(); + BranchInst *BI = dyn_cast(CallBB->getTerminator()); + if (!BI || !BI->isUnconditional() || BI->getSuccessor(0) != BB) + continue; + + // Duplicate the return into CallBB. + (void)FoldReturnIntoUncondBranch(RI, BB, CallBB); + Changed = true; + ++NumRetsDup; + } + + return Changed; + } + + return false; +} + //===----------------------------------------------------------------------===// // Memory Optimization //===----------------------------------------------------------------------===// @@ -970,6 +1062,9 @@ if (CallInst *CI = dyn_cast(I)) return OptimizeCallInst(CI); + if (ReturnInst *RI = dyn_cast(I)) + return DupRetToEnableTailCallOpts(RI); + return false; } Added: llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll?rev=127953&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll (added) +++ llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll Sat Mar 19 12:17:39 2011 @@ -0,0 +1,63 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s + +; Teach CGP to dup returns to enable tail call optimization. +; rdar://9147433 + +define i32 @foo(i32 %x) nounwind ssp { +; CHECK: foo: +entry: + switch i32 %x, label %return [ + i32 1, label %sw.bb + i32 2, label %sw.bb1 + i32 3, label %sw.bb3 + i32 4, label %sw.bb5 + i32 5, label %sw.bb7 + i32 6, label %sw.bb9 + ] + +sw.bb: ; preds = %entry +; CHECK: jmp _f1 + %call = tail call i32 @f1() nounwind + br label %return + +sw.bb1: ; preds = %entry +; CHECK: jmp _f2 + %call2 = tail call i32 @f2() nounwind + br label %return + +sw.bb3: ; preds = %entry +; CHECK: jmp _f3 + %call4 = tail call i32 @f3() nounwind + br label %return + +sw.bb5: ; preds = %entry +; CHECK: jmp _f4 + %call6 = tail call i32 @f4() nounwind + br label %return + +sw.bb7: ; preds = %entry +; CHECK: jmp _f5 + %call8 = tail call i32 @f5() nounwind + br label %return + +sw.bb9: ; preds = %entry +; CHECK: jmp _f6 + %call10 = tail call i32 @f6() nounwind + br label %return + +return: ; preds = %entry, %sw.bb9, %sw.bb7, %sw.bb5, %sw.bb3, %sw.bb1, %sw.bb + %retval.0 = phi i32 [ %call10, %sw.bb9 ], [ %call8, %sw.bb7 ], [ %call6, %sw.bb5 ], [ %call4, %sw.bb3 ], [ %call2, %sw.bb1 ], [ %call, %sw.bb ], [ 0, %entry ] + ret i32 %retval.0 +} + +declare i32 @f1() + +declare i32 @f2() + +declare i32 @f3() + +declare i32 @f4() + +declare i32 @f5() + +declare i32 @f6() From daniel at zuster.org Sat Mar 19 16:47:14 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Sat, 19 Mar 2011 21:47:14 -0000 Subject: [llvm-commits] [llvm] r127954 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h lib/Transforms/Scalar/CodeGenPrepare.cpp test/CodeGen/X86/tailcall-cgp-dup.ll Message-ID: <20110319214714.CE33E2A6C12C@llvm.org> Author: ddunbar Date: Sat Mar 19 16:47:14 2011 New Revision: 127954 URL: http://llvm.org/viewvc/llvm-project?rev=127954&view=rev Log: Revert r127953, "SimplifyCFG has stopped duplicating returns into predecessors to canonicalize IR", it broke a lot of things. Removed: llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127954&r1=127953&r2=127954&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Sat Mar 19 16:47:14 2011 @@ -1287,14 +1287,6 @@ return false; } - /// mayBeEmittedAsTailCall - Return true if the target may be able emit the - /// call instruction as a tail call. This is used by optimization passes to - /// determine if it's profitable to duplicate return instructions to enable - /// tailcall optimization. - virtual bool mayBeEmittedAsTailCall(CallInst *CI) const { - return false; - } - /// getTypeForExtArgOrReturn - Return the type that should be used to zero or /// sign extend a zeroext/signext integer argument or return value. /// FIXME: Most C calling convention requires the return type to be promoted, Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127954&r1=127953&r2=127954&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Sat Mar 19 16:47:14 2011 @@ -1805,16 +1805,6 @@ return HasRet; } -bool ARMTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { - if (!EnableARMTailCalls) - return false; - - if (!CI->isTailCall()) - return false; - - return !Subtarget->isThumb1Only(); -} - // ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as // their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is // one of the above mentioned nodes. It has to be wrapped because otherwise Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=127954&r1=127953&r2=127954&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Sat Mar 19 16:47:14 2011 @@ -457,8 +457,6 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; - virtual bool mayBeEmittedAsTailCall(CallInst *CI) const; - SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &ARMcc, SelectionDAG &DAG, DebugLoc dl) const; SDValue getVFPCmp(SDValue LHS, SDValue RHS, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127954&r1=127953&r2=127954&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Mar 19 16:47:14 2011 @@ -45,7 +45,6 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/VectorExtras.h" -#include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" @@ -1596,18 +1595,6 @@ return (CC == CallingConv::Fast || CC == CallingConv::GHC); } -bool X86TargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { - if (!CI->isTailCall()) - return false; - - CallSite CS(CI); - CallingConv::ID CalleeCC = CS.getCallingConv(); - if (!IsTailCallConvention(CalleeCC) && CalleeCC != CallingConv::C) - return false; - - return true; -} - /// FuncIsMadeTailCallSafe - Return true if the function is being made into /// a tailcall target by changing its ABI. static bool FuncIsMadeTailCallSafe(CallingConv::ID CC) { Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127954&r1=127953&r2=127954&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Sat Mar 19 16:47:14 2011 @@ -843,8 +843,6 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; - virtual bool mayBeEmittedAsTailCall(CallInst *CI) const; - virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, ISD::NodeType ExtendKind) const; Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=127954&r1=127953&r2=127954&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Sat Mar 19 16:47:14 2011 @@ -47,17 +47,16 @@ using namespace llvm::PatternMatch; STATISTIC(NumBlocksElim, "Number of blocks eliminated"); -STATISTIC(NumPHIsElim, "Number of trivial PHIs eliminated"); -STATISTIC(NumGEPsElim, "Number of GEPs converted to casts"); +STATISTIC(NumPHIsElim, "Number of trivial PHIs eliminated"); +STATISTIC(NumGEPsElim, "Number of GEPs converted to casts"); STATISTIC(NumCmpUses, "Number of uses of Cmp expressions replaced with uses of " "sunken Cmps"); STATISTIC(NumCastUses, "Number of uses of Cast expressions replaced with uses " "of sunken Casts"); STATISTIC(NumMemoryInsts, "Number of memory instructions whose address " "computations were sunk"); -STATISTIC(NumExtsMoved, "Number of [s|z]ext instructions combined with loads"); -STATISTIC(NumExtUses, "Number of uses of [s|z]ext instructions optimized"); -STATISTIC(NumRetsDup, "Number of return instructions duplicated"); +STATISTIC(NumExtsMoved, "Number of [s|z]ext instructions combined with loads"); +STATISTIC(NumExtUses, "Number of uses of [s|z]ext instructions optimized"); static cl::opt DisableBranchOpts( "disable-cgp-branch-opts", cl::Hidden, cl::init(false), @@ -105,7 +104,6 @@ bool OptimizeCallInst(CallInst *CI); bool MoveExtToFormExtLoad(Instruction *I); bool OptimizeExtUses(Instruction *I); - bool DupRetToEnableTailCallOpts(ReturnInst *RI); }; } @@ -549,96 +547,6 @@ return Simplifier.fold(CI, TD); } -/// DupRetToEnableTailCallOpts - Look for opportunities to duplicate return -/// instructions to the predecessor to enable tail call optimizations. The -/// case it is currently looking for is: -/// bb0: -/// %tmp0 = tail call i32 @f0() -/// br label %return -/// bb1: -/// %tmp1 = tail call i32 @f1() -/// br label %return -/// bb2: -/// %tmp2 = tail call i32 @f2() -/// br label %return -/// return: -/// %retval = phi i32 [ %tmp0, %bb0 ], [ %tmp1, %bb1 ], [ %tmp2, %bb2 ] -/// ret i32 %retval -/// -/// => -/// -/// bb0: -/// %tmp0 = tail call i32 @f0() -/// ret i32 %tmp0 -/// bb1: -/// %tmp1 = tail call i32 @f1() -/// ret i32 %tmp1 -/// bb2: -/// %tmp2 = tail call i32 @f2() -/// ret i32 %tmp2 -/// -bool CodeGenPrepare::DupRetToEnableTailCallOpts(ReturnInst *RI) { - Value *V = RI->getReturnValue(); - if (!V) - return false; - - if (PHINode *PN = dyn_cast(V)) { - BasicBlock *BB = RI->getParent(); - if (PN->getParent() != BB) - return false; - - // It's not safe to eliminate the sign / zero extension of the return value. - // See llvm::isInTailCallPosition(). - const Function *F = BB->getParent(); - unsigned CallerRetAttr = F->getAttributes().getRetAttributes(); - if ((CallerRetAttr & Attribute::ZExt) || (CallerRetAttr & Attribute::SExt)) - return false; - - // Make sure there are no instructions between PHI and return. - BasicBlock::iterator BI = PN; - do { ++BI; } while (isa(BI)); - if (&*BI != RI) - return false; - - /// Only dup the ReturnInst if the CallInst is likely to be emitted as a - /// tail call. - SmallVector TailCalls; - for (unsigned I = 0, E = PN->getNumIncomingValues(); I != E; ++I) { - CallInst *CI = dyn_cast(PN->getIncomingValue(I)); - if (CI && TLI->mayBeEmittedAsTailCall(CI)) - TailCalls.push_back(CI); - } - - bool Changed = false; - for (unsigned i = 0, e = TailCalls.size(); i != e; ++i) { - CallInst *CI = TailCalls[i]; - CallSite CS(CI); - - // Conservatively require the attributes of the call to match those of - // the return. Ignore noalias because it doesn't affect the call sequence. - unsigned CalleeRetAttr = CS.getAttributes().getRetAttributes(); - if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias) - continue; - - // Make sure the call instruction is followed by an unconditional branch - // to the return block. - BasicBlock *CallBB = CI->getParent(); - BranchInst *BI = dyn_cast(CallBB->getTerminator()); - if (!BI || !BI->isUnconditional() || BI->getSuccessor(0) != BB) - continue; - - // Duplicate the return into CallBB. - (void)FoldReturnIntoUncondBranch(RI, BB, CallBB); - Changed = true; - ++NumRetsDup; - } - - return Changed; - } - - return false; -} - //===----------------------------------------------------------------------===// // Memory Optimization //===----------------------------------------------------------------------===// @@ -1062,9 +970,6 @@ if (CallInst *CI = dyn_cast(I)) return OptimizeCallInst(CI); - if (ReturnInst *RI = dyn_cast(I)) - return DupRetToEnableTailCallOpts(RI); - return false; } Removed: llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll?rev=127953&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll (original) +++ llvm/trunk/test/CodeGen/X86/tailcall-cgp-dup.ll (removed) @@ -1,63 +0,0 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s - -; Teach CGP to dup returns to enable tail call optimization. -; rdar://9147433 - -define i32 @foo(i32 %x) nounwind ssp { -; CHECK: foo: -entry: - switch i32 %x, label %return [ - i32 1, label %sw.bb - i32 2, label %sw.bb1 - i32 3, label %sw.bb3 - i32 4, label %sw.bb5 - i32 5, label %sw.bb7 - i32 6, label %sw.bb9 - ] - -sw.bb: ; preds = %entry -; CHECK: jmp _f1 - %call = tail call i32 @f1() nounwind - br label %return - -sw.bb1: ; preds = %entry -; CHECK: jmp _f2 - %call2 = tail call i32 @f2() nounwind - br label %return - -sw.bb3: ; preds = %entry -; CHECK: jmp _f3 - %call4 = tail call i32 @f3() nounwind - br label %return - -sw.bb5: ; preds = %entry -; CHECK: jmp _f4 - %call6 = tail call i32 @f4() nounwind - br label %return - -sw.bb7: ; preds = %entry -; CHECK: jmp _f5 - %call8 = tail call i32 @f5() nounwind - br label %return - -sw.bb9: ; preds = %entry -; CHECK: jmp _f6 - %call10 = tail call i32 @f6() nounwind - br label %return - -return: ; preds = %entry, %sw.bb9, %sw.bb7, %sw.bb5, %sw.bb3, %sw.bb1, %sw.bb - %retval.0 = phi i32 [ %call10, %sw.bb9 ], [ %call8, %sw.bb7 ], [ %call6, %sw.bb5 ], [ %call4, %sw.bb3 ], [ %call2, %sw.bb1 ], [ %call, %sw.bb ], [ 0, %entry ] - ret i32 %retval.0 -} - -declare i32 @f1() - -declare i32 @f2() - -declare i32 @f3() - -declare i32 @f4() - -declare i32 @f5() - -declare i32 @f6() From ofv at wanadoo.es Sat Mar 19 17:52:13 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sat, 19 Mar 2011 22:52:13 -0000 Subject: [llvm-commits] [llvm] r127956 - /llvm/trunk/cmake/modules/LLVMLibDeps.cmake Message-ID: <20110319225213.BA3802A6C12C@llvm.org> Author: ofv Date: Sat Mar 19 17:52:13 2011 New Revision: 127956 URL: http://llvm.org/viewvc/llvm-project?rev=127956&view=rev Log: Update CMake library dependencies. Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake Modified: llvm/trunk/cmake/modules/LLVMLibDeps.cmake URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMLibDeps.cmake?rev=127956&r1=127955&r2=127956&view=diff ============================================================================== --- llvm/trunk/cmake/modules/LLVMLibDeps.cmake (original) +++ llvm/trunk/cmake/modules/LLVMLibDeps.cmake Sat Mar 19 17:52:13 2011 @@ -34,7 +34,7 @@ set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsCodeGen LLVMMipsInfo LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreInfo) -set(MSVC_LIB_DEPS_LLVMMCJIT LLVMExecutionEngine LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMMCJIT LLVMCore LLVMExecutionEngine LLVMSupport LLVMTarget) set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMSP430CodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMSP430AsmPrinter LLVMMSP430Info LLVMSelectionDAG LLVMSupport LLVMTarget) From ofv at wanadoo.es Sat Mar 19 17:52:25 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sat, 19 Mar 2011 22:52:25 -0000 Subject: [llvm-commits] [llvm] r127957 - /llvm/trunk/tools/llvm-config/CMakeLists.txt Message-ID: <20110319225225.EFC342A6C12C@llvm.org> Author: ofv Date: Sat Mar 19 17:52:25 2011 New Revision: 127957 URL: http://llvm.org/viewvc/llvm-project?rev=127957&view=rev Log: CMake: store TARGET_TRIPLE on llvm-config.in. Modified: llvm/trunk/tools/llvm-config/CMakeLists.txt Modified: llvm/trunk/tools/llvm-config/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-config/CMakeLists.txt?rev=127957&r1=127956&r2=127957&view=diff ============================================================================== --- llvm/trunk/tools/llvm-config/CMakeLists.txt (original) +++ llvm/trunk/tools/llvm-config/CMakeLists.txt Sat Mar 19 17:52:25 2011 @@ -27,6 +27,7 @@ set(SHLIBEXT ${LTDL_SHLIB_EXT}) #EXEEXT already set. set(OS "${CMAKE_SYSTEM}") +set(target "${TARGET_TRIPLE}") set(ARCH "${LLVM_NATIVE_ARCH}") get_system_libs(LLVM_SYSTEM_LIBS_LIST) From ofv at wanadoo.es Sat Mar 19 17:52:33 2011 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sat, 19 Mar 2011 22:52:33 -0000 Subject: [llvm-commits] [llvm] r127958 - /llvm/trunk/tools/llvm-config/CMakeLists.txt Message-ID: <20110319225233.6E17F2A6C12C@llvm.org> Author: ofv Date: Sat Mar 19 17:52:33 2011 New Revision: 127958 URL: http://llvm.org/viewvc/llvm-project?rev=127958&view=rev Log: Make llvm-config.in configuration more MSYS-friendly. Some of those POSIX <-> Windows command line conversions ended on failure. Modified: llvm/trunk/tools/llvm-config/CMakeLists.txt Modified: llvm/trunk/tools/llvm-config/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-config/CMakeLists.txt?rev=127958&r1=127957&r2=127958&view=diff ============================================================================== --- llvm/trunk/tools/llvm-config/CMakeLists.txt (original) +++ llvm/trunk/tools/llvm-config/CMakeLists.txt Sat Mar 19 17:52:33 2011 @@ -55,9 +55,9 @@ @ONLY ) -set(LIBDEPS ${CMAKE_CURRENT_BINARY_DIR}/LibDeps.txt) -set(LIBDEPS_TMP ${CMAKE_CURRENT_BINARY_DIR}/LibDeps.txt.tmp) -set(FINAL_LIBDEPS ${CMAKE_CURRENT_BINARY_DIR}/FinalLibDeps.txt) +set(LIBDEPS LibDeps.txt) +set(LIBDEPS_TMP LibDeps.txt.tmp) +set(FINAL_LIBDEPS FinalLibDeps.txt) set(LLVM_CONFIG ${LLVM_TOOLS_BINARY_DIR}/llvm-config) set(LLVM_CONFIG_IN ${CMAKE_CURRENT_BINARY_DIR}/llvm-config.in) @@ -107,17 +107,18 @@ remove_option_from_llvm_config("-W") add_custom_command(OUTPUT ${LLVM_CONFIG} - COMMAND echo 's!@LLVM_CPPFLAGS@!${CPP_FLGS}!' > temp.sed - COMMAND echo 's!@LLVM_CFLAGS@!${C_FLGS}!' >> temp.sed - COMMAND echo 's!@LLVM_CXXFLAGS@!${CXX_FLGS}!' >> temp.sed + COMMAND echo s!@LLVM_CPPFLAGS@!${CPP_FLGS}! > temp.sed + COMMAND echo s!@LLVM_CFLAGS@!${C_FLGS}! >> temp.sed + COMMAND echo s!@LLVM_CXXFLAGS@!${CXX_FLGS}! >> temp.sed # TODO: Use general flags for linking! not just for shared libs: - COMMAND echo 's!@LLVM_LDFLAGS@!${CMAKE_SHARED_LINKER_FLAGS}!' >> temp.sed - COMMAND echo 's!@LIBS@!${LLVM_SYSTEM_LIBS}!' >> temp.sed - COMMAND echo 's!@LLVM_BUILDMODE@!${CMAKE_BUILD_TYPE}!' >> temp.sed + COMMAND echo s!@LLVM_LDFLAGS@!${CMAKE_SHARED_LINKER_FLAGS}! >> temp.sed + COMMAND echo s!@LIBS@!${LLVM_SYSTEM_LIBS}! >> temp.sed + COMMAND echo s!@LLVM_BUILDMODE@!${CMAKE_BUILD_TYPE}! >> temp.sed COMMAND sed -f temp.sed < ${LLVM_CONFIG_IN} > ${LLVM_CONFIG} COMMAND ${CMAKE_COMMAND} -E remove -f temp.sed COMMAND cat ${FINAL_LIBDEPS} >> ${LLVM_CONFIG} COMMAND chmod +x ${LLVM_CONFIG} + VERBATIM DEPENDS ${FINAL_LIBDEPS} ${LLVM_CONFIG_IN} COMMENT "Building llvm-config script." ) From stoklund at 2pi.dk Sat Mar 19 18:02:47 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sat, 19 Mar 2011 23:02:47 -0000 Subject: [llvm-commits] [llvm] r127959 - in /llvm/trunk/lib/CodeGen: InlineSpiller.cpp RegAllocGreedy.cpp Message-ID: <20110319230247.B42CC2A6C12C@llvm.org> Author: stoklund Date: Sat Mar 19 18:02:47 2011 New Revision: 127959 URL: http://llvm.org/viewvc/llvm-project?rev=127959&view=rev Log: Add debug output. Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=127959&r1=127958&r2=127959&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Sat Mar 19 18:02:47 2011 @@ -435,6 +435,8 @@ LiveInterval &OrigLI = LIS.getInterval(Original); VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx); StackInt.MergeValueInAsValue(OrigLI, OrigVNI, StackInt.getValNumInfo(0)); + DEBUG(dbgs() << "\tmerged orig valno " << OrigVNI->id << ": " + << StackInt << '\n'); // Already spilled everywhere. if (SVI.AllDefsAreReloads) @@ -480,6 +482,7 @@ // Add all of VNI's live range to StackInt. LiveInterval &LI = LIS.getInterval(Reg); StackInt.MergeValueInAsValue(LI, VNI, StackInt.getValNumInfo(0)); + DEBUG(dbgs() << "Merged to stack int: " << StackInt << '\n'); // Find all spills and copies of VNI. for (MachineRegisterInfo::use_nodbg_iterator UI = MRI.use_nodbg_begin(Reg); @@ -874,6 +877,7 @@ for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) stacklvr.MergeRangesInAsValue(LIS.getInterval(RegsToSpill[i]), stacklvr.getValNumInfo(0)); + DEBUG(dbgs() << "Merged spilled regs: " << stacklvr << '\n'); // Spill around uses of all RegsToSpill. for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=127959&r1=127958&r2=127959&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Sat Mar 19 18:02:47 2011 @@ -1265,6 +1265,7 @@ // Wait until the second time, when all smaller ranges have been allocated. // This gives a better picture of the interference to split around. if (Stage == RS_Original) { + DEBUG(dbgs() << "wait for second round\n"); NewVRegs.push_back(&VirtReg); return 0; } From stoklund at 2pi.dk Sat Mar 19 18:02:50 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sat, 19 Mar 2011 23:02:50 -0000 Subject: [llvm-commits] [llvm] r127960 - /llvm/trunk/lib/CodeGen/LiveInterval.cpp Message-ID: <20110319230250.16E1D2A6C12D@llvm.org> Author: stoklund Date: Sat Mar 19 18:02:49 2011 New Revision: 127960 URL: http://llvm.org/viewvc/llvm-project?rev=127960&view=rev Log: Replace a broken LiveInterval::MergeValueInAsValue() with something simpler. Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveInterval.cpp?rev=127960&r1=127959&r2=127960&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveInterval.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveInterval.cpp Sat Mar 19 18:02:49 2011 @@ -495,60 +495,19 @@ void LiveInterval::MergeValueInAsValue( const LiveInterval &RHS, const VNInfo *RHSValNo, VNInfo *LHSValNo) { - SmallVector ReplacedValNos; - iterator IP = begin(); + // TODO: Make this more efficient. + iterator InsertPos = begin(); for (const_iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { - assert(I->valno == RHS.getValNumInfo(I->valno->id) && "Bad VNInfo"); if (I->valno != RHSValNo) continue; - SlotIndex Start = I->start, End = I->end; - IP = std::upper_bound(IP, end(), Start); - // If the start of this range overlaps with an existing liverange, trim it. - if (IP != begin() && IP[-1].end > Start) { - if (IP[-1].valno != LHSValNo) { - ReplacedValNos.push_back(IP[-1].valno); - IP[-1].valno = LHSValNo; // Update val#. - } - Start = IP[-1].end; - // Trimmed away the whole range? - if (Start >= End) continue; - } - // If the end of this range overlaps with an existing liverange, trim it. - if (IP != end() && End > IP->start) { - if (IP->valno != LHSValNo) { - ReplacedValNos.push_back(IP->valno); - IP->valno = LHSValNo; // Update val#. - } - End = IP->start; - // If this trimmed away the whole range, ignore it. - if (Start == End) continue; - } - // Map the valno in the other live range to the current live range. - IP = addRangeFrom(LiveRange(Start, End, LHSValNo), IP); - } - - - SmallSet Seen; - for (unsigned i = 0, e = ReplacedValNos.size(); i != e; ++i) { - VNInfo *V1 = ReplacedValNos[i]; - if (Seen.insert(V1)) { - bool isDead = true; - for (const_iterator I = begin(), E = end(); I != E; ++I) - if (I->valno == V1) { - isDead = false; - break; - } - if (isDead) { - // Now that V1 is dead, remove it. - markValNoForDeletion(V1); - } - } + LiveRange Tmp = *I; + Tmp.valno = LHSValNo; + InsertPos = addRangeFrom(Tmp, InsertPos); } } - /// MergeValueNumberInto - This method is called when two value nubmers /// are found to be equivalent. This eliminates V1, replacing all /// LiveRanges with the V1 value number with the V2 value number. This can From bob.wilson at apple.com Sat Mar 19 18:40:34 2011 From: bob.wilson at apple.com (Bob Wilson) Date: Sat, 19 Mar 2011 16:40:34 -0700 Subject: [llvm-commits] [llvm] r127945 - /llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c In-Reply-To: <20110319035638.45BDC2A6C12C@llvm.org> References: <20110319035638.45BDC2A6C12C@llvm.org> Message-ID: Thanks, Stuart! On Mar 18, 2011, at 8:56 PM, Stuart Hastings wrote: > Author: stuart > Date: Fri Mar 18 22:56:38 2011 > New Revision: 127945 > > URL: http://llvm.org/viewvc/llvm-project?rev=127945&view=rev > Log: > Disable test to unbreak Linux. Radar 9156771. > > Modified: > llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c > > Modified: llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c?rev=127945&r1=127944&r2=127945&view=diff > ============================================================================== > --- llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c (original) > +++ llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c Fri Mar 18 22:56:38 2011 > @@ -1,4 +1,4 @@ > -// RUN: %llvmgcc %s -S -O0 -o - | FileCheck %s > +// R UN: %llvmgcc %s -S -O0 -o - | FileCheck %s > // Radar 9156771 > typedef struct RGBColor { > unsigned short red; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From daniel at zuster.org Sat Mar 19 19:04:51 2011 From: daniel at zuster.org (Daniel Dunbar) Date: Sun, 20 Mar 2011 00:04:51 -0000 Subject: [llvm-commits] [llvm] r127962 - /llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c Message-ID: <20110320000451.D44202A6C12C@llvm.org> Author: ddunbar Date: Sat Mar 19 19:04:51 2011 New Revision: 127962 URL: http://llvm.org/viewvc/llvm-project?rev=127962&view=rev Log: Disable test in a way that keeps lit happy. Modified: llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c Modified: llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c?rev=127962&r1=127961&r2=127962&view=diff ============================================================================== --- llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c (original) +++ llvm/trunk/test/FrontendC/2011-03-18-StructReturn.c Sat Mar 19 19:04:51 2011 @@ -1,4 +1,5 @@ -// R UN: %llvmgcc %s -S -O0 -o - | FileCheck %s +// RUN: %llvmgcc %s -S -O0 -o - | FileCheck %s +// REQUIRES: disabled // Radar 9156771 typedef struct RGBColor { unsigned short red; From stoklund at 2pi.dk Sun Mar 20 00:44:55 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sun, 20 Mar 2011 05:44:55 -0000 Subject: [llvm-commits] [llvm] r127964 - /llvm/trunk/lib/CodeGen/InlineSpiller.cpp Message-ID: <20110320054456.03E092A6C12C@llvm.org> Author: stoklund Date: Sun Mar 20 00:44:55 2011 New Revision: 127964 URL: http://llvm.org/viewvc/llvm-project?rev=127964&view=rev Log: Change an argument to a LiveInterval instead of a register number to save some redundant lookups. Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=127964&r1=127963&r2=127964&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Sun Mar 20 00:44:55 2011 @@ -124,7 +124,7 @@ void analyzeSiblingValues(); bool hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI); - void eliminateRedundantSpills(unsigned Reg, VNInfo *VNI); + void eliminateRedundantSpills(LiveInterval &LI, VNInfo *VNI); bool reMaterializeFor(MachineBasicBlock::iterator MI); void reMaterializeAll(); @@ -444,7 +444,7 @@ // We are going to spill SVI.SpillVNI immediately after its def, so clear out // any later spills of the same value. - eliminateRedundantSpills(SVI.SpillReg, SVI.SpillVNI); + eliminateRedundantSpills(LIS.getInterval(SVI.SpillReg), SVI.SpillVNI); MachineBasicBlock *MBB = LIS.getMBBFromIndex(SVI.SpillVNI->def); MachineBasicBlock::iterator MII; @@ -463,15 +463,17 @@ return true; } -/// eliminateRedundantSpills - Reg:VNI is known to be on the stack. Remove any -/// redundant spills of this value in Reg and sibling copies. -void InlineSpiller::eliminateRedundantSpills(unsigned Reg, VNInfo *VNI) { - SmallVector, 8> WorkList; - WorkList.push_back(std::make_pair(Reg, VNI)); +/// eliminateRedundantSpills - SLI:VNI is known to be on the stack. Remove any +/// redundant spills of this value in SLI.reg and sibling copies. +void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, VNInfo *VNI) { + SmallVector, 8> WorkList; + WorkList.push_back(std::make_pair(&SLI, VNI)); LiveInterval &StackInt = LSS.getInterval(StackSlot); do { - tie(Reg, VNI) = WorkList.pop_back_val(); + LiveInterval *LI; + tie(LI, VNI) = WorkList.pop_back_val(); + unsigned Reg = LI->reg; DEBUG(dbgs() << "Checking redundant spills for " << PrintReg(Reg) << ':' << VNI->id << '@' << VNI->def << '\n'); @@ -480,8 +482,7 @@ continue; // Add all of VNI's live range to StackInt. - LiveInterval &LI = LIS.getInterval(Reg); - StackInt.MergeValueInAsValue(LI, VNI, StackInt.getValNumInfo(0)); + StackInt.MergeValueInAsValue(*LI, VNI, StackInt.getValNumInfo(0)); DEBUG(dbgs() << "Merged to stack int: " << StackInt << '\n'); // Find all spills and copies of VNI. @@ -490,7 +491,7 @@ if (!MI->isCopy() && !MI->getDesc().mayStore()) continue; SlotIndex Idx = LIS.getInstructionIndex(MI); - if (LI.getVNInfoAt(Idx) != VNI) + if (LI->getVNInfoAt(Idx) != VNI) continue; // Follow sibling copies down the dominator tree. @@ -500,7 +501,7 @@ VNInfo *DstVNI = DstLI.getVNInfoAt(Idx.getDefIndex()); assert(DstVNI && "Missing defined value"); assert(DstVNI->def == Idx.getDefIndex() && "Wrong copy def slot"); - WorkList.push_back(std::make_pair(DstReg, DstVNI)); + WorkList.push_back(std::make_pair(&DstLI, DstVNI)); } continue; } @@ -841,7 +842,6 @@ Edit = &edit; assert(!TargetRegisterInfo::isStackSlot(edit.getReg()) && "Trying to spill a stack slot."); - // Share a stack slot among all descendants of Original. Original = VRM.getOriginal(edit.getReg()); StackSlot = VRM.getStackSlot(Original); From stoklund at 2pi.dk Sun Mar 20 00:44:58 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sun, 20 Mar 2011 05:44:58 -0000 Subject: [llvm-commits] [llvm] r127965 - /llvm/trunk/lib/CodeGen/InlineSpiller.cpp Message-ID: <20110320054458.6260F2A6C12D@llvm.org> Author: stoklund Date: Sun Mar 20 00:44:58 2011 New Revision: 127965 URL: http://llvm.org/viewvc/llvm-project?rev=127965&view=rev Log: Also eliminate redundant spills downstream of inserted reloads. This can happen when multiple sibling registers are spilled after live range splitting. Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp Modified: llvm/trunk/lib/CodeGen/InlineSpiller.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/InlineSpiller.cpp?rev=127965&r1=127964&r2=127965&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp (original) +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp Sun Mar 20 00:44:58 2011 @@ -466,6 +466,7 @@ /// eliminateRedundantSpills - SLI:VNI is known to be on the stack. Remove any /// redundant spills of this value in SLI.reg and sibling copies. void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, VNInfo *VNI) { + assert(VNI && "Missing value"); SmallVector, 8> WorkList; WorkList.push_back(std::make_pair(&SLI, VNI)); LiveInterval &StackInt = LSS.getInterval(StackSlot); @@ -793,15 +794,22 @@ // Check for a sibling copy. unsigned SibReg = isFullCopyOf(MI, Reg); - if (!isSibling(SibReg)) - SibReg = 0; - - // Hoist the spill of a sib-reg copy. - if (SibReg && Writes && !Reads && hoistSpill(OldLI, MI)) { - // This COPY is now dead, the value is already in the stack slot. - MI->getOperand(0).setIsDead(); - DeadDefs.push_back(MI); - continue; + if (SibReg && isSibling(SibReg)) { + if (Writes) { + // Hoist the spill of a sib-reg copy. + if (hoistSpill(OldLI, MI)) { + // This COPY is now dead, the value is already in the stack slot. + MI->getOperand(0).setIsDead(); + DeadDefs.push_back(MI); + continue; + } + } else { + // This is a reload for a sib-reg copy. Drop spills downstream. + SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex(); + LiveInterval &SibLI = LIS.getInterval(SibReg); + eliminateRedundantSpills(SibLI, SibLI.getVNInfoAt(Idx)); + // The COPY will fold to a reload below. + } } // Attempt to fold memory ops. From akyrtzi at gmail.com Sun Mar 20 01:14:56 2011 From: akyrtzi at gmail.com (Argyrios Kyrtzidis) Date: Sun, 20 Mar 2011 06:14:56 -0000 Subject: [llvm-commits] [llvm] r127966 - in /llvm/trunk/include/llvm: ADT/IntrusiveRefCntPtr.h CompilerDriver/CompilationGraph.h CompilerDriver/Tool.h Message-ID: <20110320061456.4CE782A6C12C@llvm.org> Author: akirtzidis Date: Sun Mar 20 01:14:56 2011 New Revision: 127966 URL: http://llvm.org/viewvc/llvm-project?rev=127966&view=rev Log: If a class inherits from RefCountedBaseVPTR allow all its subclasses to be used with IntrusiveRefCntPtr. Modified: llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h llvm/trunk/include/llvm/CompilerDriver/Tool.h Modified: llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h?rev=127966&r1=127965&r2=127966&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h (original) +++ llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h Sun Mar 20 01:14:56 2011 @@ -64,7 +64,6 @@ /// inherit from RefCountedBaseVPTR can't be allocated on stack - /// attempting to do this will produce a compile error. //===----------------------------------------------------------------------===// - template class RefCountedBaseVPTR { unsigned ref_cnt; @@ -78,7 +77,8 @@ if (--ref_cnt == 0) delete this; } - friend class IntrusiveRefCntPtr; + template + friend class IntrusiveRefCntPtr; }; //===----------------------------------------------------------------------===// Modified: llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h?rev=127966&r1=127965&r2=127966&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h (original) +++ llvm/trunk/include/llvm/CompilerDriver/CompilationGraph.h Sun Mar 20 01:14:56 2011 @@ -40,7 +40,7 @@ }; /// Edge - Represents an edge of the compilation graph. - class Edge : public llvm::RefCountedBaseVPTR { + class Edge : public llvm::RefCountedBaseVPTR { public: Edge(const std::string& T) : ToolName_(T) {} virtual ~Edge() {} Modified: llvm/trunk/include/llvm/CompilerDriver/Tool.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tool.h?rev=127966&r1=127965&r2=127966&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tool.h (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tool.h Sun Mar 20 01:14:56 2011 @@ -33,7 +33,7 @@ typedef llvm::StringSet<> InputLanguagesSet; /// Tool - Represents a single tool. - class Tool : public llvm::RefCountedBaseVPTR { + class Tool : public llvm::RefCountedBaseVPTR { public: virtual ~Tool() {} From wdietz2 at illinois.edu Sun Mar 20 05:46:46 2011 From: wdietz2 at illinois.edu (Will Dietz) Date: Sun, 20 Mar 2011 10:46:46 -0000 Subject: [llvm-commits] [poolalloc] r127968 - /poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Message-ID: <20110320104646.191062A6C12C@llvm.org> Author: wdietz2 Date: Sun Mar 20 05:46:45 2011 New Revision: 127968 URL: http://llvm.org/viewvc/llvm-project?rev=127968&view=rev Log: Add braces to explicitly disambiguate 'else' in nested conditionals. Fixes compiler warning/error. No functionality changes. Modified: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Modified: poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp?rev=127968&r1=127967&r2=127968&view=diff ============================================================================== --- poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp (original) +++ poolalloc/trunk/lib/AssistDS/AllocatorIdentification.cpp Sun Mar 20 05:46:45 2011 @@ -69,16 +69,18 @@ continue; if(isa(ui)) continue; - if(BitCastInst *BI = dyn_cast(ui)) + if(BitCastInst *BI = dyn_cast(ui)) { if(isNotStored(BI)) continue; else return false; - if(PHINode *PN = dyn_cast(ui)) + } + if(PHINode *PN = dyn_cast(ui)) { if(isNotStored(PN)) continue; else return false; + } return false; } From fvbommel at gmail.com Sun Mar 20 10:45:12 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 20 Mar 2011 16:45:12 +0100 Subject: [llvm-commits] [llvm] r127958 - /llvm/trunk/tools/llvm-config/CMakeLists.txt In-Reply-To: <20110319225233.6E17F2A6C12C@llvm.org> References: <20110319225233.6E17F2A6C12C@llvm.org> Message-ID: On Sat, Mar 19, 2011 at 11:52 PM, Oscar Fuentes wrote: > Log: > Make llvm-config.in configuration more MSYS-friendly. > > Some of those POSIX <-> Windows command line conversions ended on > failure. This description leads me to believe the first chunk was not intended: > -set(LIBDEPS ${CMAKE_CURRENT_BINARY_DIR}/LibDeps.txt) > -set(LIBDEPS_TMP ${CMAKE_CURRENT_BINARY_DIR}/LibDeps.txt.tmp) > -set(FINAL_LIBDEPS ${CMAKE_CURRENT_BINARY_DIR}/FinalLibDeps.txt) > +set(LIBDEPS LibDeps.txt) > +set(LIBDEPS_TMP LibDeps.txt.tmp) > +set(FINAL_LIBDEPS FinalLibDeps.txt) That change seems to have caused this error: [ 69%] Updating LibDeps.txt if necessary... Error copying file (if different) from "LibDeps.txt.tmp" to "LibDeps.txt". make[3]: *** [tools/llvm-config/LibDeps.txt] Error 1 make[2]: *** [tools/llvm-config/CMakeFiles/llvm-config.target.dir/all] Error 2 make[1]: *** [tools/clang/test/CMakeFiles/check-all.dir/rule] Error 2 make: *** [check-all] Error 2 (and reverting that chunk fixed it) From benny.kra at googlemail.com Sun Mar 20 10:52:24 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sun, 20 Mar 2011 15:52:24 -0000 Subject: [llvm-commits] [llvm] r127969 - /llvm/trunk/lib/Support/Unix/Program.inc Message-ID: <20110320155224.E3FC92A6C12C@llvm.org> Author: d0k Date: Sun Mar 20 10:52:24 2011 New Revision: 127969 URL: http://llvm.org/viewvc/llvm-project?rev=127969&view=rev Log: Avoid initializing posix_spawn_file_actions_t if not used. - glibc falls back to fork+exec if a file actions object is present. - On BSDs this saves a malloc. Modified: llvm/trunk/lib/Support/Unix/Program.inc Modified: llvm/trunk/lib/Support/Unix/Program.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Program.inc?rev=127969&r1=127968&r2=127969&view=diff ============================================================================== --- llvm/trunk/lib/Support/Unix/Program.inc (original) +++ llvm/trunk/lib/Support/Unix/Program.inc Sun Mar 20 10:52:24 2011 @@ -132,7 +132,7 @@ #ifdef HAVE_POSIX_SPAWN static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg, - posix_spawn_file_actions_t &FileActions) { + posix_spawn_file_actions_t *FileActions) { if (Path == 0) // Noop return false; const char *File; @@ -142,7 +142,7 @@ else File = Path->c_str(); - if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD, + if (int Err = posix_spawn_file_actions_addopen(FileActions, FD, File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666)) return MakeErrMsg(ErrMsg, "Cannot dup2", Err); return false; @@ -185,10 +185,13 @@ // posix_spawn. It is more efficient than fork/exec. #ifdef HAVE_POSIX_SPAWN if (memoryLimit == 0) { - posix_spawn_file_actions_t FileActions; - posix_spawn_file_actions_init(&FileActions); + posix_spawn_file_actions_t FileActionsStore; + posix_spawn_file_actions_t *FileActions = 0; if (redirects) { + FileActions = &FileActionsStore; + posix_spawn_file_actions_init(FileActions); + // Redirect stdin/stdout. if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) || RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions)) @@ -200,7 +203,7 @@ } else { // If stdout and stderr should go to the same place, redirect stderr // to the FD already open for stdout. - if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2)) + if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2)) return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err); } } @@ -216,10 +219,11 @@ // Explicitly initialized to prevent what appears to be a valgrind false // positive. pid_t PID = 0; - int Err = posix_spawn(&PID, path.c_str(), &FileActions, /*attrp*/0, + int Err = posix_spawn(&PID, path.c_str(), FileActions, /*attrp*/0, const_cast(args), const_cast(envp)); - posix_spawn_file_actions_destroy(&FileActions); + if (FileActions) + posix_spawn_file_actions_destroy(FileActions); if (Err) return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err); From ofv at wanadoo.es Sun Mar 20 11:52:38 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Sun, 20 Mar 2011 17:52:38 +0100 Subject: [llvm-commits] [llvm] r127958 - /llvm/trunk/tools/llvm-config/CMakeLists.txt In-Reply-To: (Frits van Bommel's message of "Sun, 20 Mar 2011 16:45:12 +0100") References: <20110319225233.6E17F2A6C12C@llvm.org> Message-ID: <87ei6120q1.fsf@wanadoo.es> Frits van Bommel writes: > On Sat, Mar 19, 2011 at 11:52 PM, Oscar Fuentes wrote: >> Log: >> Make llvm-config.in configuration more MSYS-friendly. >> >> Some of those POSIX <-> Windows command line conversions ended on >> failure. > > This description leads me to believe the first chunk was not intended: > >> -set(LIBDEPS ${CMAKE_CURRENT_BINARY_DIR}/LibDeps.txt) >> -set(LIBDEPS_TMP ${CMAKE_CURRENT_BINARY_DIR}/LibDeps.txt.tmp) >> -set(FINAL_LIBDEPS ${CMAKE_CURRENT_BINARY_DIR}/FinalLibDeps.txt) >> +set(LIBDEPS LibDeps.txt) >> +set(LIBDEPS_TMP LibDeps.txt.tmp) >> +set(FINAL_LIBDEPS FinalLibDeps.txt) The change was intended. Using full paths for those files caused incorrect Windows -> POSIX path conversions by MSYS. > That change seems to have caused this error: > > [ 69%] Updating LibDeps.txt if necessary... > Error copying file (if different) from "LibDeps.txt.tmp" to > "LibDeps.txt". OS? Compiler? CMake generator? Can you repeat the build with `make VERBOSE=1' and post the last 100 lines? [snip] From fvbommel at gmail.com Sun Mar 20 12:32:50 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 20 Mar 2011 18:32:50 +0100 Subject: [llvm-commits] [llvm] r127958 - /llvm/trunk/tools/llvm-config/CMakeLists.txt In-Reply-To: <87ei6120q1.fsf@wanadoo.es> References: <20110319225233.6E17F2A6C12C@llvm.org> <87ei6120q1.fsf@wanadoo.es> Message-ID: On Sun, Mar 20, 2011 at 5:52 PM, ?scar Fuentes wrote: > Frits van Bommel writes: >> That change seems to have caused this error: >> >> [ 69%] Updating LibDeps.txt if necessary... >> Error copying file (if different) from "LibDeps.txt.tmp" to >> "LibDeps.txt". > > OS? Compiler? CMake generator? Can you repeat the build with `make > VERBOSE=1' and post the last 100 lines? Ubuntu 10.10 (maverick), CMake 2.8.2. Unfortunately (or perhaps fortunately, depending on your point of view), it doesn't seem to reproduce anymore... From andersca at mac.com Sun Mar 20 12:59:11 2011 From: andersca at mac.com (Anders Carlsson) Date: Sun, 20 Mar 2011 17:59:11 -0000 Subject: [llvm-commits] [llvm] r127970 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll Message-ID: <20110320175911.814CD2A6C12C@llvm.org> Author: andersca Date: Sun Mar 20 12:59:11 2011 New Revision: 127970 URL: http://llvm.org/viewvc/llvm-project?rev=127970&view=rev Log: Add an optimization to GlobalOpt that eliminates calls to __cxa_atexit, if the function passed is empty. Added: llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=127970&r1=127969&r2=127970&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Mar 20 12:59:11 2011 @@ -54,6 +54,7 @@ STATISTIC(NumNestRemoved , "Number of nest attributes removed"); STATISTIC(NumAliasesResolved, "Number of global aliases resolved"); STATISTIC(NumAliasesRemoved, "Number of global aliases eliminated"); +STATISTIC(NumCXXDtorsRemoved, "Number of global C++ destructors removed"); namespace { struct GlobalStatus; @@ -77,6 +78,7 @@ bool ProcessInternalGlobal(GlobalVariable *GV,Module::global_iterator &GVI, const SmallPtrSet &PHIUsers, const GlobalStatus &GS); + bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn); }; } @@ -2696,12 +2698,106 @@ return Changed; } +static Function *FindCXAAtExit(Module &M) { + Function *Fn = M.getFunction("__cxa_atexit"); + + if (!Fn) + return 0; + + const FunctionType *FTy = Fn->getFunctionType(); + + // Checking that the function has the right number of parameters and that they + // all have pointer types should be enough. + if (FTy->getNumParams() != 3 || + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy() || + !FTy->getParamType(2)->isPointerTy()) + return 0; + + return Fn; +} + +/// cxxDtorIsEmpty - Returns whether the given function is an empty C++ +/// destructor and can therefore be eliminated. +/// Note that we assume that other optimization passes have already simplified +/// the code so we only look for a function with a single basic block, where +/// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. +static bool cxxDtorIsEmpty(const Function& Fn) { + if (Fn.empty()) + return true; + + if (++Fn.begin() != Fn.end()) + return false; + + const BasicBlock &EntryBlock = Fn.getEntryBlock(); + for (BasicBlock::const_iterator I = EntryBlock.begin(), E = EntryBlock.end(); + I != E; ++I) { + if (const CallInst *CI = dyn_cast(I)) { + const Function *CalledFn = CI->getCalledFunction(); + + if (!CalledFn) + return false; + + if (!cxxDtorIsEmpty(*CalledFn)) + return false; + } else if (isa(*I)) + return true; + else + return false; + } + + return false; +} + +bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) { + /// Itanium C++ ABI p3.3.5: + /// + /// After constructing a global (or local static) object, that will require + /// destruction on exit, a termination function is registered as follows: + /// + /// extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); + /// + /// This registration, e.g. __cxa_atexit(f,p,d), is intended to cause the + /// call f(p) when DSO d is unloaded, before all such termination calls + /// registered before this one. It returns zero if registration is + /// successful, nonzero on failure. + + // This pass will look for calls to __cxa_atexit where the function is trivial + // and remove them. + bool Changed = false; + + for (Function::use_iterator I = CXAAtExitFn->use_begin(), + E = CXAAtExitFn->use_end(); I != E;) { + CallSite CS(*I++); + if (!CS.getInstruction()) + continue; + + Function *DtorFn = + dyn_cast(CS.getArgument(0)->stripPointerCasts()); + if (!DtorFn) + continue; + + if (!cxxDtorIsEmpty(*DtorFn)) + continue; + + // Just remove the call. + CS.getInstruction()->eraseFromParent(); + ++NumCXXDtorsRemoved; + + Changed |= true; + } + + return Changed; +} + bool GlobalOpt::runOnModule(Module &M) { bool Changed = false; // Try to find the llvm.globalctors list. GlobalVariable *GlobalCtors = FindGlobalCtors(M); + Function *CXAAtExitFn = FindCXAAtExit(M); + bool LocalChange = true; while (LocalChange) { LocalChange = false; @@ -2718,6 +2814,11 @@ // Resolve aliases, when possible. LocalChange |= OptimizeGlobalAliases(M); + + // Try to remove trivial global destructors. + if (CXAAtExitFn) + LocalChange |= OptimizeEmptyGlobalCXXDtors(CXAAtExitFn); + Changed |= LocalChange; } Added: llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll?rev=127970&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll (added) +++ llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll Sun Mar 20 12:59:11 2011 @@ -0,0 +1,31 @@ +; RUN: opt < %s -globalopt -S | FileCheck %s + +%0 = type { i32, void ()* } +%struct.A = type { i8 } + + at a = global %struct.A zeroinitializer, align 1 + at __dso_handle = external global i8* + at llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I_a }] + +; CHECK-NOT: call i32 @__cxa_atexit + +define internal void @__cxx_global_var_init() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { + %1 = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) + ret void +} + +define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 { + call void @_ZN1AD2Ev(%struct.A* %this) + ret void +} + +declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) + +define linkonce_odr void @_ZN1AD2Ev(%struct.A* %this) nounwind align 2 { + ret void +} + +define internal void @_GLOBAL__I_a() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { + call void @__cxx_global_var_init() + ret void +} From ofv at wanadoo.es Sun Mar 20 13:12:36 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Sun, 20 Mar 2011 19:12:36 +0100 Subject: [llvm-commits] [llvm] r127958 - /llvm/trunk/tools/llvm-config/CMakeLists.txt In-Reply-To: (Frits van Bommel's message of "Sun, 20 Mar 2011 18:32:50 +0100") References: <20110319225233.6E17F2A6C12C@llvm.org> <87ei6120q1.fsf@wanadoo.es> Message-ID: <87aagp1x0r.fsf@wanadoo.es> Frits van Bommel writes: > On Sun, Mar 20, 2011 at 5:52 PM, ?scar Fuentes wrote: >> Frits van Bommel writes: >>> That change seems to have caused this error: >>> >>> [ 69%] Updating LibDeps.txt if necessary... >>> Error copying file (if different) from "LibDeps.txt.tmp" to >>> "LibDeps.txt". >> >> OS? Compiler? CMake generator? Can you repeat the build with `make >> VERBOSE=1' and post the last 100 lines? > > Ubuntu 10.10 (maverick), CMake 2.8.2. > Unfortunately (or perhaps fortunately, depending on your point of > view), it doesn't seem to reproduce anymore... :-( I have the same setup and no problems here. Thanks for reporting. From rafael.espindola at gmail.com Sun Mar 20 13:44:20 2011 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Sun, 20 Mar 2011 18:44:20 -0000 Subject: [llvm-commits] [llvm] r127972 - in /llvm/trunk: lib/MC/ test/CodeGen/ARM/ test/MC/ARM/ test/MC/ELF/ Message-ID: <20110320184420.B5D5D2A6C12C@llvm.org> Author: rafael Date: Sun Mar 20 13:44:20 2011 New Revision: 127972 URL: http://llvm.org/viewvc/llvm-project?rev=127972&view=rev Log: Write the section table and the section data in the same order that gun as does. This makes it a lot easier to compare the output of both as the addresses are now a lot closer. Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp llvm/trunk/lib/MC/ELFObjectWriter.h llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll llvm/trunk/test/MC/ARM/elf-reloc-01.ll llvm/trunk/test/MC/ARM/elf-reloc-02.ll llvm/trunk/test/MC/ARM/elf-reloc-03.ll llvm/trunk/test/MC/ELF/alias-reloc.s llvm/trunk/test/MC/ELF/basic-elf-32.s llvm/trunk/test/MC/ELF/basic-elf-64.s llvm/trunk/test/MC/ELF/cfi-advance-loc2.s llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s llvm/trunk/test/MC/ELF/cfi-def-cfa.s llvm/trunk/test/MC/ELF/cfi-offset.s llvm/trunk/test/MC/ELF/cfi-remember.s llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s llvm/trunk/test/MC/ELF/cfi.s llvm/trunk/test/MC/ELF/comdat.s llvm/trunk/test/MC/ELF/common.s llvm/trunk/test/MC/ELF/got.s llvm/trunk/test/MC/ELF/local-reloc.s llvm/trunk/test/MC/ELF/merge.s llvm/trunk/test/MC/ELF/pic-diff.s llvm/trunk/test/MC/ELF/relocation-386.s llvm/trunk/test/MC/ELF/relocation-pc.s llvm/trunk/test/MC/ELF/relocation.s llvm/trunk/test/MC/ELF/rename.s llvm/trunk/test/MC/ELF/symref.s llvm/trunk/test/MC/ELF/tls.s llvm/trunk/test/MC/ELF/undef2.s llvm/trunk/test/MC/ELF/weakref-reloc.s llvm/trunk/test/MC/ELF/weakref.s Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sun Mar 20 13:44:20 2011 @@ -500,7 +500,8 @@ } void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, - SectionIndexMapTy &SectionIndexMap) { + SectionIndexMapTy &SectionIndexMap, + const RelMapTy &RelMap) { unsigned Index = 1; for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { @@ -515,15 +516,21 @@ ie = Asm.end(); it != ie; ++it) { const MCSectionELF &Section = static_cast(it->getSection()); - if (Section.getType() == ELF::SHT_GROUP) + if (Section.getType() == ELF::SHT_GROUP || + Section.getType() == ELF::SHT_REL || + Section.getType() == ELF::SHT_RELA) continue; SectionIndexMap[&Section] = Index++; + const MCSectionELF *RelSection = RelMap.lookup(&Section); + if (RelSection) + SectionIndexMap[RelSection] = Index++; } } void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, const SectionIndexMapTy &SectionIndexMap, - RevGroupMapTy RevGroupMap) { + RevGroupMapTy RevGroupMap, + unsigned NumRegularSections) { // FIXME: Is this the correct place to do this? if (NeedsGOT) { llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; @@ -533,9 +540,6 @@ MCELF::SetBinding(Data, ELF::STB_GLOBAL); } - // Build section lookup table. - int NumRegularSections = Asm.size(); - // Index 0 is always the empty string. StringMap StringIndexMap; StringTable += '\x00'; @@ -636,11 +640,16 @@ UndefinedSymbolData[i].SymbolData->setIndex(Index++); } -void ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, - const MCSectionData &SD) { - if (!Relocations[&SD].empty()) { +void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, + MCAsmLayout &Layout, + RelMapTy &RelMap) { + for (MCAssembler::const_iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + const MCSectionData &SD = *it; + if (Relocations[&SD].empty()) + continue; + MCContext &Ctx = Asm.getContext(); - const MCSectionELF *RelaSection; const MCSectionELF &Section = static_cast(SD.getSection()); @@ -654,17 +663,32 @@ else EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); - RelaSection = Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? - ELF::SHT_RELA : ELF::SHT_REL, 0, - SectionKind::getReadOnly(), - EntrySize, ""); + const MCSectionELF *RelaSection = + Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? + ELF::SHT_RELA : ELF::SHT_REL, 0, + SectionKind::getReadOnly(), + EntrySize, ""); + RelMap[&Section] = RelaSection; + Asm.getOrCreateSectionData(*RelaSection); + } +} + +void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, + const RelMapTy &RelMap) { + for (MCAssembler::const_iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + const MCSectionData &SD = *it; + const MCSectionELF &Section = + static_cast(SD.getSection()); + const MCSectionELF *RelaSection = RelMap.lookup(&Section); + if (!RelaSection) + continue; MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); RelaSD.setAlignment(is64Bit() ? 8 : 4); MCDataFragment *F = new MCDataFragment(&RelaSD); - - WriteRelocationsFragment(Asm, F, &SD); + WriteRelocationsFragment(Asm, F, &*it); } } @@ -726,7 +750,8 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, - const SectionIndexMapTy &SectionIndexMap) { + SectionIndexMapTy &SectionIndexMap, + const RelMapTy &RelMap) { MCContext &Ctx = Asm.getContext(); MCDataFragment *F; @@ -738,7 +763,6 @@ SectionKind::getReadOnly()); MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); ShstrtabSD.setAlignment(1); - ShstrtabIndex = Asm.size(); const MCSectionELF *SymtabSection = Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, @@ -746,7 +770,6 @@ EntrySize, ""); MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); SymtabSD.setAlignment(is64Bit() ? 8 : 4); - SymbolTableIndex = Asm.size(); MCSectionData *SymtabShndxSD = NULL; @@ -758,14 +781,17 @@ SymtabShndxSD->setAlignment(4); } - const MCSection *StrtabSection; + const MCSectionELF *StrtabSection; StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, SectionKind::getReadOnly()); MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); StrtabSD.setAlignment(1); - StringTableIndex = Asm.size(); - WriteRelocations(Asm, Layout); + ComputeIndexMap(Asm, SectionIndexMap, RelMap); + + ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); + SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); + StringTableIndex = SectionIndexMap.lookup(StrtabSection); // Symbol table F = new MCDataFragment(&SymtabSD); @@ -813,7 +839,9 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout, GroupMapTy &GroupMap, - RevGroupMapTy &RevGroupMap) { + RevGroupMapTy &RevGroupMap, + SectionIndexMapTy &SectionIndexMap, + const RelMapTy &RelMap) { // Create the .note.GNU-stack section if needed. MCContext &Ctx = Asm.getContext(); if (Asm.getNoExecStack()) { @@ -844,11 +872,11 @@ GroupMap[Group] = SignatureSymbol; } + ComputeIndexMap(Asm, SectionIndexMap, RelMap); + // Add sections to the groups - unsigned Index = 1; - unsigned NumGroups = RevGroupMap.size(); for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); - it != ie; ++it, ++Index) { + it != ie; ++it) { const MCSectionELF &Section = static_cast(it->getSection()); if (!(Section.getFlags() & ELF::SHF_GROUP)) @@ -857,7 +885,8 @@ MCSectionData &Data = Asm.getOrCreateSectionData(*Group); // FIXME: we could use the previous fragment MCDataFragment *F = new MCDataFragment(&Data); - String32(*F, NumGroups + Index); + unsigned Index = SectionIndexMap.lookup(&Section); + String32(*F, Index); } } @@ -966,13 +995,98 @@ return Layout.getSectionAddressSize(&SD); } -void ELFObjectWriter::WriteDataSectionData(ELFObjectWriter *W, - const MCSectionData &SD) { - for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; - ++i) { - const MCFragment &F = *i; - assert(F.getKind() == MCFragment::FT_Data); - W->WriteBytes(cast(F).getContents().str()); +void ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCSectionELF &Section) { + uint64_t FileOff = OS.tell(); + const MCSectionData &SD = Asm.getOrCreateSectionData(Section); + + uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); + WriteZeros(Padding); + FileOff += Padding; + + FileOff += GetSectionFileSize(Layout, SD); + + if (IsELFMetaDataSection(SD)) { + for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; + ++i) { + const MCFragment &F = *i; + assert(F.getKind() == MCFragment::FT_Data); + WriteBytes(cast(F).getContents().str()); + } + } else { + Asm.WriteSectionData(&SD, Layout); + } +} + +void ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, + const GroupMapTy &GroupMap, + const MCAsmLayout &Layout, + const SectionIndexMapTy &SectionIndexMap, + const SectionOffsetMapTy &SectionOffsetMap) { + const unsigned NumSections = Asm.size() + 1; + + std::vector Sections; + Sections.resize(NumSections - 1); + + for (SectionIndexMapTy::const_iterator i= + SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { + const std::pair &p = *i; + Sections[p.second - 1] = p.first; + } + + // Null section first. + uint64_t FirstSectionSize = + NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; + uint32_t FirstSectionLink = + ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; + WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); + + for (unsigned i = 0; i < NumSections - 1; ++i) { + const MCSectionELF &Section = *Sections[i]; + const MCSectionData &SD = Asm.getOrCreateSectionData(Section); + uint32_t GroupSymbolIndex; + if (Section.getType() != ELF::SHT_GROUP) + GroupSymbolIndex = 0; + else + GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, + GroupMap.lookup(&Section)); + + uint64_t Size = GetSectionAddressSize(Layout, SD); + + WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, + SectionOffsetMap.lookup(&Section), Size, + SD.getAlignment(), Section); + } +} + +void ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, + std::vector &Sections) { + for (MCAssembler::iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + const MCSectionELF &Section = + static_cast(it->getSection()); + if (Section.getType() == ELF::SHT_GROUP) + Sections.push_back(&Section); + } + + for (MCAssembler::iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + const MCSectionELF &Section = + static_cast(it->getSection()); + if (Section.getType() != ELF::SHT_GROUP && + Section.getType() != ELF::SHT_REL && + Section.getType() != ELF::SHT_RELA) + Sections.push_back(&Section); + } + + for (MCAssembler::iterator it = Asm.begin(), + ie = Asm.end(); it != ie; ++it) { + const MCSectionELF &Section = + static_cast(it->getSection()); + if (Section.getType() == ELF::SHT_REL || + Section.getType() == ELF::SHT_RELA) + Sections.push_back(&Section); } } @@ -980,107 +1094,96 @@ const MCAsmLayout &Layout) { GroupMapTy GroupMap; RevGroupMapTy RevGroupMap; - CreateIndexedSections(Asm, const_cast(Layout), GroupMap, - RevGroupMap); - SectionIndexMapTy SectionIndexMap; - ComputeIndexMap(Asm, SectionIndexMap); + unsigned NumUserSections = Asm.size(); + + DenseMap RelMap; + CreateRelocationSections(Asm, const_cast(Layout), RelMap); + + const unsigned NumUserAndRelocSections = Asm.size(); + CreateIndexedSections(Asm, const_cast(Layout), GroupMap, + RevGroupMap, SectionIndexMap, RelMap); + const unsigned AllSections = Asm.size(); + const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; + + unsigned NumRegularSections = NumUserSections + NumIndexedSections; // Compute symbol table information. - ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap); + ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); + + + WriteRelocations(Asm, const_cast(Layout), RelMap); CreateMetadataSections(const_cast(Asm), const_cast(Layout), - SectionIndexMap); + SectionIndexMap, + RelMap); - // Update to include the metadata sections. - ComputeIndexMap(Asm, SectionIndexMap); - - // Add 1 for the null section. - unsigned NumSections = Asm.size() + 1; uint64_t NaturalAlignment = is64Bit() ? 8 : 4; uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr); uint64_t FileOff = HeaderSize; std::vector Sections; - Sections.resize(NumSections); - - for (SectionIndexMapTy::const_iterator i= - SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { - const std::pair &p = *i; - Sections[p.second] = p.first; - } - - for (unsigned i = 1; i < NumSections; ++i) { + ComputeSectionOrder(Asm, Sections); + unsigned NumSections = Sections.size(); + SectionOffsetMapTy SectionOffsetMap; + for (unsigned i = 0; i < NumRegularSections + 1; ++i) { const MCSectionELF &Section = *Sections[i]; const MCSectionData &SD = Asm.getOrCreateSectionData(Section); FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); + // Remember the offset into the file for this section. + SectionOffsetMap[&Section] = FileOff; + // Get the size of the section in the output file (including padding). FileOff += GetSectionFileSize(Layout, SD); } FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); - // Write out the ELF header ... - WriteHeader(FileOff - HeaderSize, NumSections); - - FileOff = HeaderSize; + const unsigned SectionHeaderOffset = FileOff - HeaderSize; - // ... then all of the sections ... - DenseMap SectionOffsetMap; + uint64_t SectionHeaderEntrySize = is64Bit() ? + sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); + FileOff += (NumSections + 1) * SectionHeaderEntrySize; - for (unsigned i = 1; i < NumSections; ++i) { + for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { const MCSectionELF &Section = *Sections[i]; const MCSectionData &SD = Asm.getOrCreateSectionData(Section); - uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); - WriteZeros(Padding); - FileOff += Padding; + FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); // Remember the offset into the file for this section. SectionOffsetMap[&Section] = FileOff; + // Get the size of the section in the output file (including padding). FileOff += GetSectionFileSize(Layout, SD); - - if (IsELFMetaDataSection(SD)) - WriteDataSectionData(this, SD); - else - Asm.WriteSectionData(&SD, Layout); } - uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); - WriteZeros(Padding); - FileOff += Padding; - - // ... and then the section header table. - // Should we align the section header table? - // - // Null section first. - uint64_t FirstSectionSize = - NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; - uint32_t FirstSectionLink = - ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; - WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); + // Write out the ELF header ... + WriteHeader(SectionHeaderOffset, NumSections + 1); - for (unsigned i = 1; i < NumSections; ++i) { - const MCSectionELF &Section = *Sections[i]; - const MCSectionData &SD = Asm.getOrCreateSectionData(Section); - uint32_t GroupSymbolIndex; - if (Section.getType() != ELF::SHT_GROUP) - GroupSymbolIndex = 0; - else - GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]); + // ... then the regular sections ... + // + because of .shstrtab + for (unsigned i = 0; i < NumRegularSections + 1; ++i) + WriteDataSectionData(Asm, Layout, *Sections[i]); - uint64_t Size = GetSectionAddressSize(Layout, SD); + FileOff = OS.tell(); + uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); + WriteZeros(Padding); - WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, - SectionOffsetMap[&Section], Size, - SD.getAlignment(), Section); - } + // ... then the section header table ... + WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, + SectionOffsetMap); + + FileOff = OS.tell(); + + // ... and then the remainting sections ... + for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) + WriteDataSectionData(Asm, Layout, *Sections[i]); } bool Modified: llvm/trunk/lib/MC/ELFObjectWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.h?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.h (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.h Sun Mar 20 13:44:20 2011 @@ -50,8 +50,10 @@ const MCSectionData &SD); static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout, const MCSectionData &SD); - static void WriteDataSectionData(ELFObjectWriter *W, - const MCSectionData &SD); + + void WriteDataSectionData(MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCSectionELF &Section); /*static bool isFixupKindX86RIPRel(unsigned Kind) { return Kind == X86::reloc_riprel_4byte || @@ -267,6 +269,10 @@ typedef DenseMap GroupMapTy; // Map from a signature symbol to the group section typedef DenseMap RevGroupMapTy; + // Map from a section to the section with the relocations + typedef DenseMap RelMapTy; + // Map from a section to its offset + typedef DenseMap SectionOffsetMapTy; /// ComputeSymbolTable - Compute the symbol table data /// @@ -275,33 +281,42 @@ /// string table. virtual void ComputeSymbolTable(MCAssembler &Asm, const SectionIndexMapTy &SectionIndexMap, - RevGroupMapTy RevGroupMap); + RevGroupMapTy RevGroupMap, + unsigned NumRegularSections); virtual void ComputeIndexMap(MCAssembler &Asm, - SectionIndexMapTy &SectionIndexMap); + SectionIndexMapTy &SectionIndexMap, + const RelMapTy &RelMap); - virtual void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, - const MCSectionData &SD); + void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout, + RelMapTy &RelMap); - virtual void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) { - for (MCAssembler::const_iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - WriteRelocation(Asm, Layout, *it); - } - } + void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, + const RelMapTy &RelMap); virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, - const SectionIndexMapTy &SectionIndexMap); + SectionIndexMapTy &SectionIndexMap, + const RelMapTy &RelMap); // Create the sections that show up in the symbol table. Currently // those are the .note.GNU-stack section and the group sections. virtual void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout, GroupMapTy &GroupMap, - RevGroupMapTy &RevGroupMap); + RevGroupMapTy &RevGroupMap, + SectionIndexMapTy &SectionIndexMap, + const RelMapTy &RelMap); virtual void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); + void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap, + const MCAsmLayout &Layout, + const SectionIndexMapTy &SectionIndexMap, + const SectionOffsetMapTy &SectionOffsetMap); + + void ComputeSectionOrder(MCAssembler &Asm, + std::vector &Sections); + virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, uint64_t Address, uint64_t Offset, uint64_t Size, uint32_t Link, uint32_t Info, Modified: llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll Sun Mar 20 13:44:20 2011 @@ -15,7 +15,7 @@ -; OBJ: Section 0x00000003 +; OBJ: Section 0x00000004 ; OBJ-NEXT: '.bss' ; OBJ: 'array00' @@ -24,7 +24,7 @@ ; OBJ-NEXT: 'st_bind', 0x00000000 ; OBJ-NEXT: 'st_type', 0x00000001 ; OBJ-NEXT: 'st_other', 0x00000000 -; OBJ-NEXT: 'st_shndx', 0x00000003 +; OBJ-NEXT: 'st_shndx', 0x00000004 define i32 @main(i32 %argc) nounwind { %1 = load i32* @sum, align 4 Modified: llvm/trunk/test/MC/ARM/elf-reloc-01.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/elf-reloc-01.ll?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ARM/elf-reloc-01.ll (original) +++ llvm/trunk/test/MC/ARM/elf-reloc-01.ll Sun Mar 20 13:44:20 2011 @@ -60,12 +60,11 @@ declare void @exit(i32) noreturn nounwind - -;; OBJ: Symbol 0x00000002 -;; OBJ-NEXT: '_MergedGlobals' -;; OBJ-NEXT: 'st_value', 0x00000010 - ;; OBJ: Relocation 0x00000001 ;; OBJ-NEXT: 'r_offset', ;; OBJ-NEXT: 'r_sym', 0x00000002 ;; OBJ-NEXT: 'r_type', 0x0000002b + +;; OBJ: Symbol 0x00000002 +;; OBJ-NEXT: '_MergedGlobals' +;; OBJ-NEXT: 'st_value', 0x00000010 Modified: llvm/trunk/test/MC/ARM/elf-reloc-02.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/elf-reloc-02.ll?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ARM/elf-reloc-02.ll (original) +++ llvm/trunk/test/MC/ARM/elf-reloc-02.ll Sun Mar 20 13:44:20 2011 @@ -41,11 +41,10 @@ declare void @exit(i32) noreturn nounwind - -;; OBJ: Symbol 0x00000002 -;; OBJ-NEXT: '.L.str' - ;; OBJ: Relocation 0x00000000 ;; OBJ-NEXT: 'r_offset', ;; OBJ-NEXT: 'r_sym', 0x00000002 ;; OBJ-NEXT: 'r_type', 0x0000002b + +;; OBJ: Symbol 0x00000002 +;; OBJ-NEXT: '.L.str' Modified: llvm/trunk/test/MC/ARM/elf-reloc-03.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/elf-reloc-03.ll?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ARM/elf-reloc-03.ll (original) +++ llvm/trunk/test/MC/ARM/elf-reloc-03.ll Sun Mar 20 13:44:20 2011 @@ -88,11 +88,10 @@ declare void @exit(i32) noreturn nounwind - -;; OBJ: Symbol 0x0000000c -;; OBJ-NEXT: 'vtable' - ;; OBJ: Relocation 0x00000001 ;; OBJ-NEXT: 'r_offset', ;; OBJ-NEXT: 'r_sym', 0x0000000c ;; OBJ-NEXT: 'r_type', 0x0000002b + +;; OBJ: Symbol 0x0000000c +;; OBJ-NEXT: 'vtable' Modified: llvm/trunk/test/MC/ELF/alias-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/alias-reloc.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/alias-reloc.s (original) +++ llvm/trunk/test/MC/ELF/alias-reloc.s Sun Mar 20 13:44:20 2011 @@ -17,6 +17,20 @@ .set bar2,foo2 .quad bar2 +// CHECK: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000001) +// CHECK-NEXT: ('r_sym', 0x00000001) +// CHECK-NEXT: ('r_type', 0x00000004) +// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ), + +// CHECK: # Relocation 0x00000001 +// CHECK-NEXT: (('r_offset', 0x00000005) +// CHECK-NEXT: ('r_sym', 0x00000006) +// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), + // CHECK: # Symbol 0x00000001 // CHECK-NEXT: (('st_name', 0x00000005) # 'bar' // CHECK-NEXT: ('st_bind', 0x00000000) @@ -36,17 +50,3 @@ // CHECK-NEXT: ('st_value', 0x0000000000000005) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), - -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000001) -// CHECK-NEXT: ('r_sym', 0x00000001) -// CHECK-NEXT: ('r_type', 0x00000004) -// CHECK-NEXT: ('r_addend', 0xfffffffc) -// CHECK-NEXT: ), - -// CHECK: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000005) -// CHECK-NEXT: ('r_sym', 0x00000006) -// CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) -// CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/basic-elf-32.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/basic-elf-32.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/basic-elf-32.s (original) +++ llvm/trunk/test/MC/ELF/basic-elf-32.s Sun Mar 20 13:44:20 2011 @@ -39,23 +39,6 @@ // CHECK: # '.text' -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) - -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) - -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) - -// CHECK: # 'main' -// CHECK: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000002) - -// CHECK: # 'puts' -// CHECK: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) - // CHECK: # '.rel.text' // CHECK: ('_relocations', [ @@ -76,3 +59,20 @@ // CHECK: ('r_type', 0x00000002) // CHECK: ), // CHECK: ]) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: # 'main' +// CHECK: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000002) + +// CHECK: # 'puts' +// CHECK: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000000) Modified: llvm/trunk/test/MC/ELF/basic-elf-64.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/basic-elf-64.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/basic-elf-64.s (original) +++ llvm/trunk/test/MC/ELF/basic-elf-64.s Sun Mar 20 13:44:20 2011 @@ -39,23 +39,6 @@ // CHECK: # '.text' -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) - -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) - -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) - -// CHECK: # 'main' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000002) - -// CHECK: # 'puts' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) - // CHECK: # '.rela.text' // CHECK: ('_relocations', [ @@ -80,3 +63,20 @@ // CHECK: ('r_addend', 0xfffffffc) // CHECK: ), // CHECK: ]) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) + +// CHECK: # 'main' +// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000002) + +// CHECK: # 'puts' +// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000000) Modified: llvm/trunk/test/MC/ELF/cfi-advance-loc2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-advance-loc2.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-advance-loc2.s (original) +++ llvm/trunk/test/MC/ELF/cfi-advance-loc2.s Sun Mar 20 13:44:20 2011 @@ -24,13 +24,13 @@ // CHECK-NEXT: ), -// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK: (('sh_name', 0x0000001c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000258) +// CHECK-NEXT: ('sh_offset', 0x00000498) // CHECK-NEXT: ('sh_size', 0x00000018) -// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s (original) +++ llvm/trunk/test/MC/ELF/cfi-def-cfa-offset.s Sun Mar 20 13:44:20 2011 @@ -24,14 +24,14 @@ // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 0a000000 00440e10 450e0800') // CHECK-NEXT: ), -// CHECK: # Section 0x00000008 -// CHECK-NEXT: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK: # Section 0x00000005 +// CHECK-NEXT: (('sh_name', 0x0000001c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000160) +// CHECK-NEXT: ('sh_offset', 0x000003a0) // CHECK-NEXT: ('sh_size', 0x00000018) -// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s (original) +++ llvm/trunk/test/MC/ELF/cfi-def-cfa-register.s Sun Mar 20 13:44:20 2011 @@ -20,13 +20,13 @@ // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00410d06 00000000') // CHECK-NEXT: ), -// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK: (('sh_name', 0x0000001c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000158) +// CHECK-NEXT: ('sh_offset', 0x00000398) // CHECK-NEXT: ('sh_size', 0x00000018) -// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/cfi-def-cfa.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-def-cfa.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-def-cfa.s (original) +++ llvm/trunk/test/MC/ELF/cfi-def-cfa.s Sun Mar 20 13:44:20 2011 @@ -21,13 +21,13 @@ // CHECK-NEXT: ), -// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK: (('sh_name', 0x0000001c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000158) +// CHECK-NEXT: ('sh_offset', 0x00000398) // CHECK-NEXT: ('sh_size', 0x00000018) -// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/cfi-offset.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-offset.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-offset.s (original) +++ llvm/trunk/test/MC/ELF/cfi-offset.s Sun Mar 20 13:44:20 2011 @@ -21,13 +21,13 @@ // CHECK-NEXT: ), -// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK: (('sh_name', 0x0000001c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000158) +// CHECK-NEXT: ('sh_offset', 0x00000398) // CHECK-NEXT: ('sh_size', 0x00000018) -// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/cfi-remember.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-remember.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-remember.s (original) +++ llvm/trunk/test/MC/ELF/cfi-remember.s Sun Mar 20 13:44:20 2011 @@ -23,14 +23,14 @@ // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 03000000 00410a41 0b000000') // CHECK-NEXT: ), -// CHECK: # Section 0x00000008 -// CHECK-NEXT: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK: # Section 0x00000005 +// CHECK-NEXT: (('sh_name', 0x0000001c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000158) +// CHECK-NEXT: ('sh_offset', 0x00000398) // CHECK-NEXT: ('sh_size', 0x00000018) -// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s (original) +++ llvm/trunk/test/MC/ELF/cfi-zero-addr-delta.s Sun Mar 20 13:44:20 2011 @@ -27,13 +27,13 @@ // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 1c000000 1c000000 00000000 04000000 00410e10 410a0e08 410b0000 00000000') // CHECK-NEXT: ), -// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK: (('sh_name', 0x0000001c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000160) +// CHECK-NEXT: ('sh_offset', 0x000003a0) // CHECK-NEXT: ('sh_size', 0x00000018) -// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/cfi.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/cfi.s (original) +++ llvm/trunk/test/MC/ELF/cfi.s Sun Mar 20 13:44:20 2011 @@ -226,14 +226,14 @@ // CHECK-NEXT: ('_section_data', '14000000 00000000 017a4c52 00017810 02031b0c 07089001 14000000 1c000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000003 1b0c0708 90010000 14000000 28000000 00000000 01000000 04000000 00000000 14000000 70000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000002 1b0c0708 90010000 10000000 28000000 00000000 01000000 02000000 18000000 00000000 017a5052 00017810 04020000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06030000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a040000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 040a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 060b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a0c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a080000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a100000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04120000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06130000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a140000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 041a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 061b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a1c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a180000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a800000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04820000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06830000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a840000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 048a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 068b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a8c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a88000 0 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a900000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04920000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06930000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a940000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 049a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 069b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a9c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a980000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000') // CHECK-NEXT: ), -// CHECK: # Section 0x00000008 -// CHECK-NEXT: (('sh_name', 0x00000036) # '.rela.eh_frame' +// CHECK: # Section 0x00000005 +// CHECK-NEXT: (('sh_name', 0x0000001c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000bf8) +// CHECK-NEXT: ('sh_offset', 0x00000e38) // CHECK-NEXT: ('sh_size', 0x000006c0) -// CHECK-NEXT: ('sh_link', 0x00000006) +// CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/comdat.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/comdat.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/comdat.s (original) +++ llvm/trunk/test/MC/ELF/comdat.s Sun Mar 20 13:44:20 2011 @@ -4,37 +4,37 @@ // of the file. // CHECK: # Section 0x00000001 -// CHECK-NEXT: (('sh_name', 0x00000026) # '.group' +// CHECK-NEXT: (('sh_name', 0x00000030) # '.group' // CHECK-NEXT: ('sh_type', 0x00000011) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) // CHECK-NEXT: ('sh_offset', 0x00000040) // CHECK-NEXT: ('sh_size', 0x0000000c) -// CHECK-NEXT: ('sh_link', 0x0000000c) +// CHECK-NEXT: ('sh_link', 0x0000000d) // CHECK-NEXT: ('sh_info', 0x00000001) // CHECK-NEXT: ('sh_addralign', 0x00000004) // CHECK-NEXT: ('sh_entsize', 0x00000004) // CHECK-NEXT: ), // CHECK-NEXT: # Section 0x00000002 -// CHECK-NEXT: (('sh_name', 0x00000026) # '.group' +// CHECK-NEXT: (('sh_name', 0x00000030) # '.group' // CHECK-NEXT: ('sh_type', 0x00000011) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) // CHECK-NEXT: ('sh_offset', 0x0000004c) // CHECK-NEXT: ('sh_size', 0x00000008) -// CHECK-NEXT: ('sh_link', 0x0000000c) +// CHECK-NEXT: ('sh_link', 0x0000000d) // CHECK-NEXT: ('sh_info', 0x00000002) // CHECK-NEXT: ('sh_addralign', 0x00000004) // CHECK-NEXT: ('sh_entsize', 0x00000004) // CHECK-NEXT: ), // CHECK-NEXT: # Section 0x00000003 -// CHECK-NEXT: (('sh_name', 0x00000026) # '.group' +// CHECK-NEXT: (('sh_name', 0x00000030) # '.group' // CHECK-NEXT: ('sh_type', 0x00000011) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) // CHECK-NEXT: ('sh_offset', 0x00000054) // CHECK-NEXT: ('sh_size', 0x00000008) -// CHECK-NEXT: ('sh_link', 0x0000000c) +// CHECK-NEXT: ('sh_link', 0x0000000d) // CHECK-NEXT: ('sh_info', 0x0000000d) // CHECK-NEXT: ('sh_addralign', 0x00000004) // CHECK-NEXT: ('sh_entsize', 0x00000004) Modified: llvm/trunk/test/MC/ELF/common.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/common.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/common.s (original) +++ llvm/trunk/test/MC/ELF/common.s Sun Mar 20 13:44:20 2011 @@ -38,7 +38,7 @@ // CHECK-NEXT: ('st_bind', 0x00000000) // CHECK-NEXT: ('st_type', 0x00000001) // CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000003) +// CHECK-NEXT: ('st_shndx', 0x00000004) // CHECK-NEXT: ('st_value', 0x0000000000000010) // CHECK-NEXT: ('st_size', 0x0000000000000008) // CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/got.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/got.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/got.s (original) +++ llvm/trunk/test/MC/ELF/got.s Sun Mar 20 13:44:20 2011 @@ -6,9 +6,6 @@ movl foo at GOT, %eax movl foo at GOTPCREL(%rip), %eax -// CHECK: (('st_name', 0x00000005) # '_GLOBAL_OFFSET_TABLE_' -// CHECK-NEXT: ('st_bind', 0x00000001) - // CHECK: ('_relocations', [ // CHECK-NEXT: # Relocation 0x00000000 // CHECK-NEXT: (('r_offset', @@ -23,3 +20,6 @@ // CHECK-NEXT: ('r_addend', // CHECK-NEXT: ), // CHECK-NEXT: ]) + +// CHECK: (('st_name', 0x00000005) # '_GLOBAL_OFFSET_TABLE_' +// CHECK-NEXT: ('st_bind', 0x00000001) Modified: llvm/trunk/test/MC/ELF/local-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/local-reloc.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/local-reloc.s (original) +++ llvm/trunk/test/MC/ELF/local-reloc.s Sun Mar 20 13:44:20 2011 @@ -10,16 +10,6 @@ // CHECK: # Section 0x00000001 // CHECK-next: (('sh_name', 0x00000001) # '.text' -// Symbol number 2 is section number 1 -// CHECK: # Symbol 0x00000002 -// CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) -// CHECK-NEXT: ('st_value', 0x0000000000000000) -// CHECK-NEXT: ('st_size', 0x0000000000000000) - // Relocation refers to symbol number 2 // CHECK: ('_relocations', [ // CHECK-NEXT: # Relocation 0x00000000 @@ -29,3 +19,13 @@ // CHECK-NEXT: ('r_addend', // CHECK-NEXT: ), // CHECK-NEXT: ]) + +// Symbol number 2 is section number 1 +// CHECK: # Symbol 0x00000002 +// CHECK-NEXT: (('st_name', 0x00000000) # '' +// CHECK-NEXT: ('st_bind', 0x00000000) +// CHECK-NEXT: ('st_type', 0x00000003) +// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_value', 0x0000000000000000) +// CHECK-NEXT: ('st_size', 0x0000000000000000) Modified: llvm/trunk/test/MC/ELF/merge.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/merge.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/merge.s (original) +++ llvm/trunk/test/MC/ELF/merge.s Sun Mar 20 13:44:20 2011 @@ -22,30 +22,6 @@ .section bar,"ax", at progbits foo: -// Section 4 is "sec1" -// CHECK: # Section 0x00000004 -// CHECK-NEXT: (('sh_name', 0x00000012) # '.sec1' - -// Symbol number 1 is .Lfoo -// CHECK: # Symbol 0x00000001 -// CHECK-NEXT: (('st_name', 0x00000001) # '.Lfoo' - -// Symbol number 2 is foo -// CHECK: # Symbol 0x00000002 -// CHECK-NEXT: (('st_name', 0x00000007) # 'foo' - -// Symbol number 6 is section 4 -// CHECK: # Symbol 0x00000006 -// CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) - -// Symbol number 8 is zed -// CHECK: # Symbol 0x00000008 -// CHECK-NEXT: (('st_name', 0x0000000b) # 'zed' - // Relocation 0 refers to symbol 1 // CHECK: ('_relocations', [ // CHECK-NEXT: # Relocation 0 @@ -95,3 +71,27 @@ // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) + +// Section 5 is "sec1" +// CHECK: # Section 0x00000005 +// CHECK-NEXT: (('sh_name', 0x00000012) # '.sec1' + +// Symbol number 1 is .Lfoo +// CHECK: # Symbol 0x00000001 +// CHECK-NEXT: (('st_name', 0x00000001) # '.Lfoo' + +// Symbol number 2 is foo +// CHECK: # Symbol 0x00000002 +// CHECK-NEXT: (('st_name', 0x00000007) # 'foo' + +// Symbol number 6 is section 5 +// CHECK: # Symbol 0x00000006 +// CHECK-NEXT: (('st_name', 0x00000000) # '' +// CHECK-NEXT: ('st_bind', 0x00000000) +// CHECK-NEXT: ('st_type', 0x00000003) +// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_shndx', 0x00000005) + +// Symbol number 8 is zed +// CHECK: # Symbol 0x00000008 +// CHECK-NEXT: (('st_name', 0x0000000b) # 'zed' Modified: llvm/trunk/test/MC/ELF/pic-diff.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/pic-diff.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/pic-diff.s (original) +++ llvm/trunk/test/MC/ELF/pic-diff.s Sun Mar 20 13:44:20 2011 @@ -1,5 +1,14 @@ // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s +// CHECK: ('_relocations', [ +// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x0000000c) +// CHECK-NEXT: ('r_sym', 0x00000005) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x00000008) +// CHECK-NEXT: ), +// CHECK-NEXT: ]) + // CHECK: # Symbol 0x00000005 // CHECK-NEXT: (('st_name', 0x00000005) # 'baz' // CHECK-NEXT: ('st_bind', 0x00000001) @@ -10,15 +19,6 @@ // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x0000000c) -// CHECK-NEXT: ('r_sym', 0x00000005) -// CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000008) -// CHECK-NEXT: ), -// CHECK-NEXT: ]) - .zero 4 .data Modified: llvm/trunk/test/MC/ELF/relocation-386.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/relocation-386.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/relocation-386.s (original) +++ llvm/trunk/test/MC/ELF/relocation-386.s Sun Mar 20 13:44:20 2011 @@ -3,33 +3,6 @@ // Test that we produce the correct relocation types and that the relocations // correctly point to the section or the symbol. -// Section 3 is bss -// CHECK: # Section 0x00000003 -// CHECK-NEXT: (('sh_name', 0x0000000d) # '.bss' - -// CHECK: # Symbol 0x00000001 -// CHECK-NEXT: (('st_name', 0x00000005) # '.Lfoo' - -// Symbol 4 is zed -// CHECK: # Symbol 0x00000004 -// CHECK-NEXT: (('st_name', 0x00000035) # 'zed' -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) - -// Symbol 7 is section 3 -// CHECK: # Symbol 0x00000007 -// CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_value', 0x00000000) -// CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000003) - // CHECK: # Relocation 0x00000000 // CHECK-NEXT: (('r_offset', 0x00000002) // CHECK-NEXT: ('r_sym', 0x00000001) @@ -181,6 +154,34 @@ // CHECK-NEXT: ('r_type', 0x00000001) // CHECK-NEXT: ), +// Section 4 is bss +// CHECK: # Section 0x00000004 +// CHECK-NEXT: (('sh_name', 0x0000000d) # '.bss' + +// CHECK: # Symbol 0x00000001 +// CHECK-NEXT: (('st_name', 0x00000005) # '.Lfoo' + +// Symbol 4 is zed +// CHECK: # Symbol 0x00000004 +// CHECK-NEXT: (('st_name', 0x00000035) # 'zed' +// CHECK-NEXT: ('st_value', 0x00000000) +// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x00000000) +// CHECK-NEXT: ('st_type', 0x00000006) +// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_shndx', 0x00000005) + +// Symbol 7 is section 4 +// CHECK: # Symbol 0x00000007 +// CHECK-NEXT: (('st_name', 0x00000000) # '' +// CHECK-NEXT: ('st_value', 0x00000000) +// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x00000000) +// CHECK-NEXT: ('st_type', 0x00000003) +// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_shndx', 0x00000004) + + .text bar: leal .Lfoo at GOTOFF(%ebx), %eax Modified: llvm/trunk/test/MC/ELF/relocation-pc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/relocation-pc.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/relocation-pc.s (original) +++ llvm/trunk/test/MC/ELF/relocation-pc.s Sun Mar 20 13:44:20 2011 @@ -5,14 +5,14 @@ loope 0 # R_X86_64_PC8 jmp -256 # R_X86_64_PC32 -// CHECK: # Section 0x00000007 -// CHECK-NEXT: (('sh_name', 0x0000002c) # '.rela.text' +// CHECK: # Section 0x00000002 +// CHECK-NEXT: (('sh_name', 0x00000012) # '.rela.text' // CHECK-NEXT: ('sh_type', 0x00000004) // CHECK-NEXT: ('sh_flags', 0x00000000) // CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x000000e8) +// CHECK-NEXT: ('sh_offset', 0x000002e8) // CHECK-NEXT: ('sh_size', 0x00000030) -// CHECK-NEXT: ('sh_link', 0x00000005) +// CHECK-NEXT: ('sh_link', 0x00000006) // CHECK-NEXT: ('sh_info', 0x00000001) // CHECK-NEXT: ('sh_addralign', 0x00000008) // CHECK-NEXT: ('sh_entsize', 0x00000018) Modified: llvm/trunk/test/MC/ELF/relocation.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/relocation.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/relocation.s (original) +++ llvm/trunk/test/MC/ELF/relocation.s Sun Mar 20 13:44:20 2011 @@ -22,13 +22,6 @@ // CHECK: # Section 0x00000001 // CHECK: (('sh_name', 0x00000001) # '.text' -// CHECK: # Symbol 0x00000002 -// CHECK: (('st_name', 0x00000000) # '' -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) -// CHECK: ('st_other', 0x00000000) -// CHECK: ('st_shndx', 0x00000001) - // CHECK: # Relocation 0x00000000 // CHECK-NEXT: (('r_offset', 0x00000001) // CHECK-NEXT: ('r_sym', 0x00000002) @@ -112,3 +105,10 @@ // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000002) // CHECK-NEXT: ('r_addend', 0x0000005c) + +// CHECK: # Symbol 0x00000002 +// CHECK: (('st_name', 0x00000000) # '' +// CHECK: ('st_bind', 0x00000000) +// CHECK: ('st_type', 0x00000003) +// CHECK: ('st_other', 0x00000000) +// CHECK: ('st_shndx', 0x00000001) Modified: llvm/trunk/test/MC/ELF/rename.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/rename.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/rename.s (original) +++ llvm/trunk/test/MC/ELF/rename.s Sun Mar 20 13:44:20 2011 @@ -28,6 +28,13 @@ // CHECK-NEXT: ('sh_addralign', 0x00000004) // CHECK-NEXT: ('sh_entsize', 0x00000000) +// The relocation uses symbol 2 +// CHECK: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000000) +// CHECK-NEXT: ('r_sym', 0x00000002) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) + // Symbol 2 is section 1 // CHECK: # Symbol 0x00000002 // CHECK-NEXT: (('st_name', 0x00000000) # '' @@ -37,10 +44,3 @@ // CHECK-NEXT: ('st_shndx', 0x00000001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) - -// The relocation uses symbol 2 -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000000) -// CHECK-NEXT: ('r_sym', 0x00000002) -// CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) Modified: llvm/trunk/test/MC/ELF/symref.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/symref.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/symref.s (original) +++ llvm/trunk/test/MC/ELF/symref.s Sun Mar 20 13:44:20 2011 @@ -22,6 +22,38 @@ global1: +// CHECK: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000000) +// CHECK-NEXT: ('r_sym', 0x00000006) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000001 +// CHECK-NEXT: (('r_offset', 0x00000004) +// CHECK-NEXT: ('r_sym', 0x0000000b) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000002 +// CHECK-NEXT: (('r_offset', 0x00000008) +// CHECK-NEXT: ('r_sym', 0x00000006) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000003 +// CHECK-NEXT: (('r_offset', 0x0000000c) +// CHECK-NEXT: ('r_sym', 0x00000006) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000004 +// CHECK-NEXT: (('r_offset', 0x00000010) +// CHECK-NEXT: ('r_sym', 0x0000000c) +// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT:]) + // CHECK: # Symbol 0x00000001 // CHECK-NEXT: (('st_name', 0x00000013) # 'bar1 at zed' // CHECK-NEXT: ('st_bind', 0x00000000) @@ -81,7 +113,7 @@ // CHECK-NEXT: ('st_bind', 0x00000000) // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000002) +// CHECK-NEXT: ('st_shndx', 0x00000003) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), @@ -90,7 +122,7 @@ // CHECK-NEXT: ('st_bind', 0x00000000) // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000003) +// CHECK-NEXT: ('st_shndx', 0x00000004) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), @@ -131,35 +163,3 @@ // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT:]) - -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000000) -// CHECK-NEXT: ('r_sym', 0x00000006) -// CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) -// CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000004) -// CHECK-NEXT: ('r_sym', 0x0000000b) -// CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) -// CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000002 -// CHECK-NEXT: (('r_offset', 0x00000008) -// CHECK-NEXT: ('r_sym', 0x00000006) -// CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) -// CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000003 -// CHECK-NEXT: (('r_offset', 0x0000000c) -// CHECK-NEXT: ('r_sym', 0x00000006) -// CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) -// CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000004 -// CHECK-NEXT: (('r_offset', 0x00000010) -// CHECK-NEXT: ('r_sym', 0x0000000c) -// CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) -// CHECK-NEXT: ), -// CHECK-NEXT:]) Modified: llvm/trunk/test/MC/ELF/tls.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/tls.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/tls.s (original) +++ llvm/trunk/test/MC/ELF/tls.s Sun Mar 20 13:44:20 2011 @@ -14,7 +14,7 @@ // CHECK-NEXT: ('st_bind', 0x00000000) // CHECK-NEXT: ('st_type', 0x00000006) // CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) +// CHECK-NEXT: ('st_shndx', 0x00000005) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/undef2.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/undef2.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/undef2.s (original) +++ llvm/trunk/test/MC/ELF/undef2.s Sun Mar 20 13:44:20 2011 @@ -7,4 +7,4 @@ // CHECK: ('_symbols', [ // CHECK: (('st_name', 0x00000001) # '.Lfoo' // CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK: (('sh_name', 0x00000024) # '.strtab' +// CHECK: (('sh_name', 0x0000002f) # '.strtab' Modified: llvm/trunk/test/MC/ELF/weakref-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/weakref-reloc.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/weakref-reloc.s (original) +++ llvm/trunk/test/MC/ELF/weakref-reloc.s Sun Mar 20 13:44:20 2011 @@ -7,6 +7,19 @@ call zed at PLT call bar +// CHECK: # Relocation 0x00000000 +// CHECK-NEXT: (('r_offset', 0x00000001) +// CHECK-NEXT: ('r_sym', 0x00000006) +// CHECK-NEXT: ('r_type', 0x00000004) +// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ), +// CHECK-NEXT: # Relocation 0x00000001 +// CHECK-NEXT: (('r_offset', 0x00000006) +// CHECK-NEXT: ('r_sym', 0x00000005) +// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ), + // CHECK: # Symbol 0x00000004 // CHECK-NEXT: (('st_name', 0x00000009) # '_GLOBAL_OFFSET_TABLE_' // CHECK-NEXT: ('st_bind', 0x00000001) @@ -34,16 +47,3 @@ // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), - -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000001) -// CHECK-NEXT: ('r_sym', 0x00000006) -// CHECK-NEXT: ('r_type', 0x00000004) -// CHECK-NEXT: ('r_addend', 0xfffffffc) -// CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000006) -// CHECK-NEXT: ('r_sym', 0x00000005) -// CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0xfffffffc) -// CHECK-NEXT: ), Modified: llvm/trunk/test/MC/ELF/weakref.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/weakref.s?rev=127972&r1=127971&r2=127972&view=diff ============================================================================== --- llvm/trunk/test/MC/ELF/weakref.s (original) +++ llvm/trunk/test/MC/ELF/weakref.s Sun Mar 20 13:44:20 2011 @@ -128,7 +128,7 @@ // CHECK-NEXT: ('st_bind', 0x00000000) // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000002) +// CHECK-NEXT: ('st_shndx', 0x00000003) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), @@ -137,7 +137,7 @@ // CHECK-NEXT: ('st_bind', 0x00000000) // CHECK-NEXT: ('st_type', 0x00000003) // CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000003) +// CHECK-NEXT: ('st_shndx', 0x00000004) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), From fvbommel at gmail.com Sun Mar 20 13:53:59 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 20 Mar 2011 19:53:59 +0100 Subject: [llvm-commits] [llvm] r127970 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll In-Reply-To: <20110320175911.814CD2A6C12C@llvm.org> References: <20110320175911.814CD2A6C12C@llvm.org> Message-ID: On Sun, Mar 20, 2011 at 6:59 PM, Anders Carlsson wrote: > +static Function *FindCXAAtExit(Module &M) { > + ?Function *Fn = M.getFunction("__cxa_atexit"); > + > + ?if (!Fn) > + ? ?return 0; > + > + ?const FunctionType *FTy = Fn->getFunctionType(); > + > + ?// Checking that the function has the right number of parameters and that they > + ?// all have pointer types should be enough. > + ?if (FTy->getNumParams() != 3 || > + ? ? ?!FTy->getParamType(0)->isPointerTy() || > + ? ? ?!FTy->getParamType(1)->isPointerTy() || > + ? ? ?!FTy->getParamType(2)->isPointerTy()) > + ? ?return 0; You're not checking the return type here; see below. > + > + ?return Fn; > +} > + > +/// cxxDtorIsEmpty - Returns whether the given function is an empty C++ > +/// destructor and can therefore be eliminated. > +/// Note that we assume that other optimization passes have already simplified > +/// the code so we only look for a function with a single basic block, where > +/// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. > +static bool cxxDtorIsEmpty(const Function& Fn) { > + ?if (Fn.empty()) > + ? ?return true; Fn.empty() is equivalent to Fn.isDeclaration(). Do you really want to allow external destructors to be deleted? (Note: you can allow them if they're readonly/readnone and nounwind) > + > + ?if (++Fn.begin() != Fn.end()) > + ? ?return false; > + > + ?const BasicBlock &EntryBlock = Fn.getEntryBlock(); > + ?for (BasicBlock::const_iterator I = EntryBlock.begin(), E = EntryBlock.end(); > + ? ? ? I != E; ++I) { > + ? ?if (const CallInst *CI = dyn_cast(I)) { > + ? ? ?const Function *CalledFn = CI->getCalledFunction(); > + > + ? ? ?if (!CalledFn) > + ? ? ? ?return false; > + > + ? ? ?if (!cxxDtorIsEmpty(*CalledFn)) > + ? ? ? ?return false; If the destructor is an infinite recursion at run-time, this turns it into an infinite recursion at compile time... > + ? ?} else if (isa(*I)) > + ? ? ?return true; > + ? ?else > + ? ? ?return false; I think you could allow arbitrary non-terminator instructions without side-effects here too. These could be passed as parameters to the calls, for instance. In fact, that check could be moved up to filter out side-effect-free function calls too. > + ?} > + > + ?return false; > +} > + > +bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) { > + ?/// Itanium C++ ABI p3.3.5: > + ?/// > + ?/// ? After constructing a global (or local static) object, that will require > + ?/// ? destruction on exit, a termination function is registered as follows: > + ?/// > + ?/// ? extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); > + ?/// > + ?/// ? This registration, e.g. __cxa_atexit(f,p,d), is intended to cause the > + ?/// ? call f(p) when DSO d is unloaded, before all such termination calls > + ?/// ? registered before this one. It returns zero if registration is > + ?/// ? ?successful, nonzero on failure. > + > + ?// This pass will look for calls to __cxa_atexit where the function is trivial > + ?// and remove them. [snip] > + ? ?if (!cxxDtorIsEmpty(*DtorFn)) > + ? ? ?continue; > + > + ? ?// Just remove the call. > + ? ?CS.getInstruction()->eraseFromParent(); > + ? ?++NumCXXDtorsRemoved; According to the comment above, __cxa_atexit returns an int. If it has any uses, this leaves them dangling. Since it should be safe to pretend that registering an empty destructor is successful, you should call "CS->replaceAllUsesWith(Constant::getNullValue(CS.getType()));" before erasing __cxa_atexit calls that have uses. You should probably also either check for non-void return type in FindCXAAtExit(), or skip the RAUW if the return type is void. Also, note that 'CS.getInstruction()->' is equivalent to 'CS->' due to operator overloading :). From eli.friedman at gmail.com Sun Mar 20 14:36:40 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Sun, 20 Mar 2011 12:36:40 -0700 Subject: [llvm-commits] [llvm] r127970 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll In-Reply-To: References: <20110320175911.814CD2A6C12C@llvm.org> Message-ID: On Sun, Mar 20, 2011 at 11:53 AM, Frits van Bommel wrote: > On Sun, Mar 20, 2011 at 6:59 PM, Anders Carlsson wrote: >> +static Function *FindCXAAtExit(Module &M) { >> + ?Function *Fn = M.getFunction("__cxa_atexit"); >> + >> + ?if (!Fn) >> + ? ?return 0; >> + >> + ?const FunctionType *FTy = Fn->getFunctionType(); >> + >> + ?// Checking that the function has the right number of parameters and that they >> + ?// all have pointer types should be enough. >> + ?if (FTy->getNumParams() != 3 || >> + ? ? ?!FTy->getParamType(0)->isPointerTy() || >> + ? ? ?!FTy->getParamType(1)->isPointerTy() || >> + ? ? ?!FTy->getParamType(2)->isPointerTy()) >> + ? ?return 0; > > You're not checking the return type here; see below. > >> + >> + ?return Fn; >> +} >> + >> +/// cxxDtorIsEmpty - Returns whether the given function is an empty C++ >> +/// destructor and can therefore be eliminated. >> +/// Note that we assume that other optimization passes have already simplified >> +/// the code so we only look for a function with a single basic block, where >> +/// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. >> +static bool cxxDtorIsEmpty(const Function& Fn) { >> + ?if (Fn.empty()) >> + ? ?return true; > > Fn.empty() is equivalent to Fn.isDeclaration(). Do you really want to > allow external destructors to be deleted? > > (Note: you can allow them if they're readonly/readnone and nounwind) > >> + >> + ?if (++Fn.begin() != Fn.end()) >> + ? ?return false; >> + >> + ?const BasicBlock &EntryBlock = Fn.getEntryBlock(); >> + ?for (BasicBlock::const_iterator I = EntryBlock.begin(), E = EntryBlock.end(); >> + ? ? ? I != E; ++I) { >> + ? ?if (const CallInst *CI = dyn_cast(I)) { >> + ? ? ?const Function *CalledFn = CI->getCalledFunction(); >> + >> + ? ? ?if (!CalledFn) >> + ? ? ? ?return false; >> + >> + ? ? ?if (!cxxDtorIsEmpty(*CalledFn)) >> + ? ? ? ?return false; > > If the destructor is an infinite recursion at run-time, this turns it > into an infinite recursion at compile time... > >> + ? ?} else if (isa(*I)) >> + ? ? ?return true; >> + ? ?else >> + ? ? ?return false; > > I think you could allow arbitrary non-terminator instructions without > side-effects here too. These could be passed as parameters to the > calls, for instance. > In fact, that check could be moved up to filter out side-effect-free > function calls too. > >> + ?} >> + >> + ?return false; >> +} >> + >> +bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) { >> + ?/// Itanium C++ ABI p3.3.5: >> + ?/// >> + ?/// ? After constructing a global (or local static) object, that will require >> + ?/// ? destruction on exit, a termination function is registered as follows: >> + ?/// >> + ?/// ? extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); >> + ?/// >> + ?/// ? This registration, e.g. __cxa_atexit(f,p,d), is intended to cause the >> + ?/// ? call f(p) when DSO d is unloaded, before all such termination calls >> + ?/// ? registered before this one. It returns zero if registration is >> + ?/// ? ?successful, nonzero on failure. >> + >> + ?// This pass will look for calls to __cxa_atexit where the function is trivial >> + ?// and remove them. > [snip] >> + ? ?if (!cxxDtorIsEmpty(*DtorFn)) >> + ? ? ?continue; >> + >> + ? ?// Just remove the call. >> + ? ?CS.getInstruction()->eraseFromParent(); >> + ? ?++NumCXXDtorsRemoved; > > According to the comment above, __cxa_atexit returns an int. If it has > any uses, this leaves them dangling. > Since it should be safe to pretend that registering an empty > destructor is successful, you should call > "CS->replaceAllUsesWith(Constant::getNullValue(CS.getType()));" before > erasing __cxa_atexit calls that have uses. > You should probably also either check for non-void return type in > FindCXAAtExit(), or skip the RAUW if the return type is void. Also worth pointing out that the CS could be an invoke. (It wouldn't be very useful because __cxa_atexit can't throw, but not illegal AFAIK.) -Eli > Also, note that 'CS.getInstruction()->' is equivalent to 'CS->' due to > operator overloading :). > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From stoklund at 2pi.dk Sun Mar 20 14:46:24 2011 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sun, 20 Mar 2011 19:46:24 -0000 Subject: [llvm-commits] [llvm] r127973 - /llvm/trunk/lib/CodeGen/SplitKit.cpp Message-ID: <20110320194624.1CB9F2A6C12C@llvm.org> Author: stoklund Date: Sun Mar 20 14:46:23 2011 New Revision: 127973 URL: http://llvm.org/viewvc/llvm-project?rev=127973&view=rev Log: Process all dead defs after rematerializing during splitting. Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=127973&r1=127972&r2=127973&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SplitKit.cpp (original) +++ llvm/trunk/lib/CodeGen/SplitKit.cpp Sun Mar 20 14:46:23 2011 @@ -789,30 +789,23 @@ void SplitEditor::deleteRematVictims() { SmallVector Dead; - for (LiveInterval::const_vni_iterator I = Edit->getParent().vni_begin(), - E = Edit->getParent().vni_end(); I != E; ++I) { - const VNInfo *VNI = *I; - // Was VNI rematted anywhere? - if (VNI->isUnused() || VNI->isPHIDef() || !Edit->didRematerialize(VNI)) - continue; - unsigned RegIdx = RegAssign.lookup(VNI->def); - LiveInterval *LI = Edit->get(RegIdx); - LiveInterval::const_iterator LII = LI->FindLiveRangeContaining(VNI->def); - assert(LII != LI->end() && "Missing live range for rematted def"); - - // Is this a dead def? - if (LII->end != VNI->def.getNextSlot()) - continue; - - MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def); - assert(MI && "Missing instruction for dead def"); - MI->addRegisterDead(LI->reg, &TRI); + for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I){ + LiveInterval *LI = *I; + for (LiveInterval::const_iterator LII = LI->begin(), LIE = LI->end(); + LII != LIE; ++LII) { + // Dead defs end at the store slot. + if (LII->end != LII->valno->def.getNextSlot()) + continue; + MachineInstr *MI = LIS.getInstructionFromIndex(LII->valno->def); + assert(MI && "Missing instruction for dead def"); + MI->addRegisterDead(LI->reg, &TRI); - if (!MI->allDefsAreDead()) - continue; + if (!MI->allDefsAreDead()) + continue; - DEBUG(dbgs() << "All defs dead: " << *MI); - Dead.push_back(MI); + DEBUG(dbgs() << "All defs dead: " << *MI); + Dead.push_back(MI); + } } if (Dead.empty()) From andersca at mac.com Sun Mar 20 14:51:13 2011 From: andersca at mac.com (Anders Carlsson) Date: Sun, 20 Mar 2011 19:51:13 -0000 Subject: [llvm-commits] [llvm] r127974 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <20110320195113.6A9492A6C12C@llvm.org> Author: andersca Date: Sun Mar 20 14:51:13 2011 New Revision: 127974 URL: http://llvm.org/viewvc/llvm-project?rev=127974&view=rev Log: Address comments from Frits van Bommel. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=127974&r1=127973&r2=127974&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Mar 20 14:51:13 2011 @@ -2706,9 +2706,10 @@ const FunctionType *FTy = Fn->getFunctionType(); - // Checking that the function has the right number of parameters and that they - // all have pointer types should be enough. - if (FTy->getNumParams() != 3 || + // Checking that the function has the right return type, the right number of + // parameters and that they all have pointer types should be enough. + if (!FTy->getReturnType()->isIntegerTy() || + FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() || !FTy->getParamType(1)->isPointerTy() || !FTy->getParamType(2)->isPointerTy()) @@ -2723,8 +2724,10 @@ /// the code so we only look for a function with a single basic block, where /// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. static bool cxxDtorIsEmpty(const Function& Fn) { - if (Fn.empty()) - return true; + // FIXME: We could eliminate C++ destructors if they're readonly/readnone and + // unwind, but that doesn't seem worth doing. + if (Fn.isDeclaration()) + return false; if (++Fn.begin() != Fn.end()) return false; @@ -2738,6 +2741,10 @@ if (!CalledFn) return false; + // Don't treat recursive functions as empty. + if (CalledFn == &Fn) + return false; + if (!cxxDtorIsEmpty(*CalledFn)) return false; } else if (isa(*I)) @@ -2769,7 +2776,7 @@ for (Function::use_iterator I = CXAAtExitFn->use_begin(), E = CXAAtExitFn->use_end(); I != E;) { CallSite CS(*I++); - if (!CS.getInstruction()) + if (!CS) continue; Function *DtorFn = @@ -2781,7 +2788,9 @@ continue; // Just remove the call. - CS.getInstruction()->eraseFromParent(); + CS->replaceAllUsesWith(Constant::getNullValue(CS.getType())); + CS->eraseFromParent(); + ++NumCXXDtorsRemoved; Changed |= true; From andersca at mac.com Sun Mar 20 14:55:40 2011 From: andersca at mac.com (Anders Carlsson) Date: Sun, 20 Mar 2011 12:55:40 -0700 Subject: [llvm-commits] [llvm] r127970 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll In-Reply-To: References: <20110320175911.814CD2A6C12C@llvm.org> Message-ID: <5106BAF9-92F4-4F58-9309-A351120AA850@mac.com> On Mar 20, 2011, at 11:53 AM, Frits van Bommel wrote: > You're not checking the return type here; see below. > Fixed. > Fn.empty() is equivalent to Fn.isDeclaration(). Do you really want to > allow external destructors to be deleted? > > (Note: you can allow them if they're readonly/readnone and nounwind) Nope, I don't think we want them to be deleted. I added a FIXME for the readonly/readnone and nounwind case. > If the destructor is an infinite recursion at run-time, this turns it > into an infinite recursion at compile time... Fixed! >> + } else if (isa(*I)) >> + return true; >> + else >> + return false; > > I think you could allow arbitrary non-terminator instructions without > side-effects here too. These could be passed as parameters to the > calls, for instance. > In fact, that check could be moved up to filter out side-effect-free > function calls too. I intentionally wanted to make this as simple as possible to only catch what llvm-gcc and clang does. > > According to the comment above, __cxa_atexit returns an int. If it has > any uses, this leaves them dangling. > Since it should be safe to pretend that registering an empty > destructor is successful, you should call > "CS->replaceAllUsesWith(Constant::getNullValue(CS.getType()));" before > erasing __cxa_atexit calls that have uses. > You should probably also either check for non-void return type in > FindCXAAtExit(), or skip the RAUW if the return type is void. Added a check for an integer return type and used RUAW. > Also, note that 'CS.getInstruction()->' is equivalent to 'CS->' due to > operator overloading :). Doh! Fixed. (Everything is fixed in r127974). Thanks for the review! - Anders -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110320/a142a23f/attachment.html From fvbommel at gmail.com Sun Mar 20 15:09:12 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 20 Mar 2011 21:09:12 +0100 Subject: [llvm-commits] [llvm] r127974 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp In-Reply-To: <20110320195113.6A9492A6C12C@llvm.org> References: <20110320195113.6A9492A6C12C@llvm.org> Message-ID: On Sun, Mar 20, 2011 at 8:51 PM, Anders Carlsson wrote: > + ? ? ?// Don't treat recursive functions as empty. > + ? ? ?if (CalledFn == &Fn) > + ? ? ? ?return false; That only works for directly-recursive functions, not mutually-recursive functions. There could be an arbitrarily long call chain before the same function is called again. Simplest destructor that should fail now: X::~X() { foo(); } void foo() { bar(); } void bar() { foo(); } This is a problem solved in several places in LLVM already by using something like a SmallSet& parameter, containing the functions currently in the call stack. They tend to use RAII to clean up (to allow multiple successive calls to the same function). From andersca at mac.com Sun Mar 20 15:16:44 2011 From: andersca at mac.com (Anders Carlsson) Date: Sun, 20 Mar 2011 20:16:44 -0000 Subject: [llvm-commits] [llvm] r127975 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <20110320201644.223C22A6C12C@llvm.org> Author: andersca Date: Sun Mar 20 15:16:43 2011 New Revision: 127975 URL: http://llvm.org/viewvc/llvm-project?rev=127975&view=rev Log: Don't segfault on mutual recursion, as pointed out by Frits. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=127975&r1=127974&r2=127975&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Mar 20 15:16:43 2011 @@ -2723,7 +2723,8 @@ /// Note that we assume that other optimization passes have already simplified /// the code so we only look for a function with a single basic block, where /// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. -static bool cxxDtorIsEmpty(const Function& Fn) { +static bool cxxDtorIsEmpty(const Function &Fn, + SmallPtrSet &CalledFunctions) { // FIXME: We could eliminate C++ destructors if they're readonly/readnone and // unwind, but that doesn't seem worth doing. if (Fn.isDeclaration()) @@ -2742,10 +2743,10 @@ return false; // Don't treat recursive functions as empty. - if (CalledFn == &Fn) + if (!CalledFunctions.insert(CalledFn)) return false; - if (!cxxDtorIsEmpty(*CalledFn)) + if (!cxxDtorIsEmpty(*CalledFn, CalledFunctions)) return false; } else if (isa(*I)) return true; @@ -2784,7 +2785,8 @@ if (!DtorFn) continue; - if (!cxxDtorIsEmpty(*DtorFn)) + SmallPtrSet CalledFunctions; + if (!cxxDtorIsEmpty(*DtorFn, CalledFunctions)) continue; // Just remove the call. From andersca at mac.com Sun Mar 20 15:21:33 2011 From: andersca at mac.com (Anders Carlsson) Date: Sun, 20 Mar 2011 20:21:33 -0000 Subject: [llvm-commits] [llvm] r127976 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <20110320202133.A76252A6C12C@llvm.org> Author: andersca Date: Sun Mar 20 15:21:33 2011 New Revision: 127976 URL: http://llvm.org/viewvc/llvm-project?rev=127976&view=rev Log: Don't try to eliminate invokes to __cxa_atexit. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=127976&r1=127975&r2=127976&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Mar 20 15:21:33 2011 @@ -2780,6 +2780,12 @@ if (!CS) continue; + // We're only interested in calls. Theoretically, we could handle invoke + // instructions as well, but neither llvm-gcc nor clang generate invokes + // to __cxa_atexit. + if (!CS.isCall()) + continue; + Function *DtorFn = dyn_cast(CS.getArgument(0)->stripPointerCasts()); if (!DtorFn) From fvbommel at gmail.com Sun Mar 20 15:40:27 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 20 Mar 2011 21:40:27 +0100 Subject: [llvm-commits] [llvm] r127976 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp In-Reply-To: <20110320202133.A76252A6C12C@llvm.org> References: <20110320202133.A76252A6C12C@llvm.org> Message-ID: On Sun, Mar 20, 2011 at 9:21 PM, Anders Carlsson wrote: > + ? ?// We're only interested in calls. Theoretically, we could handle invoke > + ? ?// instructions as well, but neither llvm-gcc nor clang generate invokes > + ? ?// to __cxa_atexit. > + ? ?if (!CS.isCall()) > + ? ? ?continue; There's not much use for CallSite anymore, is there? Seems to me you could replace it with dyn_cast() now. From fvbommel at gmail.com Sun Mar 20 15:43:13 2011 From: fvbommel at gmail.com (Frits van Bommel) Date: Sun, 20 Mar 2011 21:43:13 +0100 Subject: [llvm-commits] [llvm] r127975 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp In-Reply-To: <20110320201644.223C22A6C12C@llvm.org> References: <20110320201644.223C22A6C12C@llvm.org> Message-ID: On Sun, Mar 20, 2011 at 9:16 PM, Anders Carlsson wrote: > Log: > Don't segfault on mutual recursion, as pointed out by Frits. Now it doesn't handle e.g.: X::~X() { foo(); foo(); } void foo() {} Probably not a huge issue though. From jasonwkim at google.com Sun Mar 20 15:43:56 2011 From: jasonwkim at google.com (Jason Kim) Date: Sun, 20 Mar 2011 13:43:56 -0700 Subject: [llvm-commits] [llvm] r127972 - in /llvm/trunk: lib/MC/ test/CodeGen/ARM/ test/MC/ARM/ test/MC/ELF/ In-Reply-To: <20110320184420.B5D5D2A6C12C@llvm.org> References: <20110320184420.B5D5D2A6C12C@llvm.org> Message-ID: On Sun, Mar 20, 2011 at 11:44 AM, Rafael Espindola wrote: > Author: rafael > Date: Sun Mar 20 13:44:20 2011 > New Revision: 127972 > > URL: http://llvm.org/viewvc/llvm-project?rev=127972&view=rev > Log: > Write the section table and the section data in the same order that > gun as does. This makes it a lot easier to compare the output of both > as the addresses are now a lot closer. Great! Thanks! -jason From baldrick at free.fr Sun Mar 20 16:08:54 2011 From: baldrick at free.fr (Duncan Sands) Date: Sun, 20 Mar 2011 21:08:54 -0000 Subject: [llvm-commits] [dragonegg] r127978 - /dragonegg/trunk/Constants.cpp Message-ID: <20110320210854.2A9832A6C12C@llvm.org> Author: baldrick Date: Sun Mar 20 16:08:54 2011 New Revision: 127978 URL: http://llvm.org/viewvc/llvm-project?rev=127978&view=rev Log: Change some places that used i8 to use the smallest addressable unit instead. Modified: dragonegg/trunk/Constants.cpp Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=127978&r1=127977&r2=127978&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Sun Mar 20 16:08:54 2011 @@ -1391,16 +1391,15 @@ /// AddressOfCOMPONENT_REF - Return the address of a field in a record. static Constant *AddressOfCOMPONENT_REF(tree exp) { - assert(!(BITS_PER_UNIT & 7) && "Unit size not a multiple of 8 bits!"); tree field_decl = TREE_OPERAND(exp, 1); - // Compute the field offset in octets from the start of the record. + // Compute the field offset in units from the start of the record. Constant *Offset; if (TREE_OPERAND(exp, 2)) { Offset = getAsInteger(TREE_OPERAND(exp, 2)); // At this point the offset is measured in units divided by (exactly) - // (DECL_OFFSET_ALIGN / BITS_PER_UNIT). Convert to octets. - unsigned factor = DECL_OFFSET_ALIGN(field_decl) / 8; + // (DECL_OFFSET_ALIGN / BITS_PER_UNIT). Convert to units. + unsigned factor = DECL_OFFSET_ALIGN(field_decl) / BITS_PER_UNIT; if (factor != 1) Offset = TheFolder->CreateMul(Offset, ConstantInt::get(Offset->getType(), @@ -1408,30 +1407,24 @@ } else { assert(DECL_FIELD_OFFSET(field_decl) && "Field offset not available!"); Offset = getAsInteger(DECL_FIELD_OFFSET(field_decl)); - // At this point the offset is measured in units. Convert to octets. - unsigned factor = BITS_PER_UNIT / 8; - if (factor != 1) - Offset = TheFolder->CreateMul(Offset, - ConstantInt::get(Offset->getType(), - factor)); } // Here BitStart gives the offset of the field in bits from Offset. uint64_t BitStart = getInt64(DECL_FIELD_BIT_OFFSET(field_decl), true); // Incorporate as much of it as possible into the pointer computation. - uint64_t ByteOffset = BitStart / 8; - if (ByteOffset > 0) { + uint64_t Units = BitStart / BITS_PER_UNIT; + if (Units > 0) { Offset = TheFolder->CreateAdd(Offset, ConstantInt::get(Offset->getType(), - ByteOffset)); - BitStart -= ByteOffset*8; + Units)); + BitStart -= Units * BITS_PER_UNIT; } assert(BitStart == 0 && "It's a bitfield reference or we didn't get to the field!"); - const Type *BytePtrTy = Type::getInt8PtrTy(Context); + const Type *UnitPtrTy = GetUnitPointerType(Context); Constant *StructAddr = AddressOf(TREE_OPERAND(exp, 0)); - Constant *FieldPtr = TheFolder->CreateBitCast(StructAddr, BytePtrTy); + Constant *FieldPtr = TheFolder->CreateBitCast(StructAddr, UnitPtrTy); FieldPtr = TheFolder->CreateInBoundsGetElementPtr(FieldPtr, &Offset, 1); return FieldPtr; @@ -1479,7 +1472,7 @@ switch (TREE_CODE(exp)) { default: debug_tree(exp); - assert(0 && "Unknown constant lvalue to convert!"); + assert(false && "Unknown constant to take the address of!"); abort(); case COMPLEX_CST: case FIXED_CST: @@ -1516,9 +1509,9 @@ // once here rather than in every AddressOf helper. const Type *Ty; if (VOID_TYPE_P(TREE_TYPE(exp))) - Ty = Type::getInt8Ty(Context); // void* -> i8*. + Ty = GetUnitPointerType(Context); // void* -> i8*. else - Ty = ConvertType(TREE_TYPE(exp)); + Ty = ConvertType(TREE_TYPE(exp))->getPointerTo(); - return TheFolder->CreateBitCast(Addr, Ty->getPointerTo()); + return TheFolder->CreateBitCast(Addr, Ty); } From baldrick at free.fr Sun Mar 20 16:10:16 2011 From: baldrick at free.fr (Duncan Sands) Date: Sun, 20 Mar 2011 21:10:16 -0000 Subject: [llvm-commits] [dragonegg] r127979 - in /dragonegg/trunk: Constants.cpp Constants.h Message-ID: <20110320211016.0E81C2A6C12C@llvm.org> Author: baldrick Date: Sun Mar 20 16:10:15 2011 New Revision: 127979 URL: http://llvm.org/viewvc/llvm-project?rev=127979&view=rev Log: Add some sanity checks on the constants returned by ConvertInitializer and correct the description of this method. Modified: dragonegg/trunk/Constants.cpp dragonegg/trunk/Constants.h Modified: dragonegg/trunk/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.cpp?rev=127979&r1=127978&r2=127979&view=diff ============================================================================== --- dragonegg/trunk/Constants.cpp (original) +++ dragonegg/trunk/Constants.cpp Sun Mar 20 16:10:15 2011 @@ -1294,27 +1294,61 @@ /// equal to or less than that of the original expression. Constant *ConvertInitializer(tree exp) { assert(TREE_CONSTANT(exp) && "Isn't a constant!"); + + Constant *Init; switch (TREE_CODE(exp)) { default: debug_tree(exp); assert(0 && "Unknown constant to convert!"); abort(); - case INTEGER_CST: return ConvertINTEGER_CST(exp); - case REAL_CST: return ConvertREAL_CST(exp); - case VECTOR_CST: return ConvertVECTOR_CST(exp); - case STRING_CST: return ConvertSTRING_CST(exp); - case COMPLEX_CST: return ConvertCOMPLEX_CST(exp); - case NOP_EXPR: return ConvertNOP_EXPR(exp); - case CONVERT_EXPR: return ConvertCONVERT_EXPR(exp); + case INTEGER_CST: + Init = ConvertINTEGER_CST(exp); + break; + case REAL_CST: + Init = ConvertREAL_CST(exp); + break; + case VECTOR_CST: + Init = ConvertVECTOR_CST(exp); + break; + case STRING_CST: + Init = ConvertSTRING_CST(exp); + break; + case COMPLEX_CST: + Init = ConvertCOMPLEX_CST(exp); + break; + case NOP_EXPR: + Init = ConvertNOP_EXPR(exp); + break; + case CONVERT_EXPR: + Init = ConvertCONVERT_EXPR(exp); + break; case PLUS_EXPR: - case MINUS_EXPR: return ConvertBinOp_CST(exp); - case CONSTRUCTOR: return ConvertCONSTRUCTOR(exp); - case VIEW_CONVERT_EXPR: return ConvertInitializer(TREE_OPERAND(exp, 0)); - case POINTER_PLUS_EXPR: return ConvertPOINTER_PLUS_EXPR(exp); + case MINUS_EXPR: + Init = ConvertBinOp_CST(exp); + break; + case CONSTRUCTOR: + Init = ConvertCONSTRUCTOR(exp); + break; + case VIEW_CONVERT_EXPR: + Init = ConvertInitializer(TREE_OPERAND(exp, 0)); + break; + case POINTER_PLUS_EXPR: + Init = ConvertPOINTER_PLUS_EXPR(exp); + break; case ADDR_EXPR: - return TheFolder->CreateBitCast(AddressOf(TREE_OPERAND(exp, 0)), + Init = TheFolder->CreateBitCast(AddressOf(TREE_OPERAND(exp, 0)), ConvertType(TREE_TYPE(exp))); + break; } + + assert((!ConvertType(TREE_TYPE(exp))->isSized() || + getTargetData().getTypeAllocSizeInBits(ConvertType(TREE_TYPE(exp))) <= + getTargetData().getTypeAllocSizeInBits(Init->getType())) && + "Constant too small for type!"); + assert(getTargetData().getABITypeAlignment(Init->getType()) * 8 <= + TYPE_ALIGN(TREE_TYPE(exp)) && "Constant over aligned!"); + + return Init; } Modified: dragonegg/trunk/Constants.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/Constants.h?rev=127979&r1=127978&r2=127979&view=diff ============================================================================== --- dragonegg/trunk/Constants.h (original) +++ dragonegg/trunk/Constants.h Sun Mar 20 16:10:15 2011 @@ -41,8 +41,12 @@ /// ConvertInitializer - Convert the initial value for a global variable to an /// equivalent LLVM constant. Also handles constant constructors. The type of /// the returned value may be pretty much anything. All that is guaranteed is -/// that it has the same alloc size as the original expression and has alignment -/// equal to or less than that of the original expression. +/// that its alloc size is equal to the size of the initial value and that its +/// alignment is less than or equal to the initial value's GCC type alignment. +/// Note that the GCC type may have variable size or no size, in which case the +/// size is determined by the initial value. When this happens the size of the +/// initial value may exceed the alloc size of the LLVM memory type generated +/// for the GCC type (see ConvertType); it is never smaller than the alloc size. extern llvm::Constant *ConvertInitializer(tree_node *exp); /// InterpretAsType - Interpret the bits of the given constant (starting from From Erik.Olofsson at hansoft.se Sun Mar 20 16:16:23 2011 From: Erik.Olofsson at hansoft.se (Erik Olofsson) Date: Sun, 20 Mar 2011 22:16:23 +0100 Subject: [llvm-commits] [PATCH] CMake option for enabling optimization for utilities in debug build In-Reply-To: <87r5aaqyq2.fsf@wanadoo.es> References: <97510B8DF78E714D91EB4A27850A17DA0C3EACC0DD@winserv02.hansoft.local> <871v2aslqt.fsf@wanadoo.es> <97510B8DF78E714D91EB4A27850A17DA0C3EACC0DE@winserv02.hansoft.local> <87r5aaqyq2.fsf@wanadoo.es> Message-ID: <7574AA29-3662-4C3A-BD6D-1B1120EDCA34@hansoft.se> On 14 mar 2011, at 02.26, ?scar Fuentes wrote: > Erik Olofsson writes: > >>>> This patch enables optimization for the utilities such as tblgen in >>>> the utils dir in Debug builds. This decreases the compile time of the >>>> debug build considerably on Visual Studio, and somewhat on OSX. >>> >>> There is one way of using an optimized tlbgen executable: configure setting >>> LLVM_TABLEGEN. You can point it to a tblgen.exe that still does not exist. >>> Supposing that you are using VS and your build directory is c:\build : >>> >>> cmake -DLLVM_TABLEGEN=c:/build/bin/Release/tblgen.exe >>> path/to/llvm/sources >>> >>> Now we build the tblgen target in Release mode. You can do that from the >>> IDE but with the command line is: >>> >>> cmake --build . --target tblgen --config Release >>> >>> Now you can build in Debug mode. The tblgen.exe generated above will be >>> used: >>> >>> cmake --build . --config Debug >> >> Yes, I suspected as much, but it's a lot of manual work each time you need to do it. > > One step more is not a lot of work, IMO, and the patch adds too much > complexity for the value of the feature it implements (again IMO). > > But there is another possibility. The current build already supports > building and using an external tblgen in Release mode. That was > implemented to be used while cross-compiling, but a quick look makes me > think that adapting it to your scenario would require just a few > lines. It was created with makefile generators in mind, so it must be > adapted to use with VS, which looks quite easy (if you build with the VS > IDE or msbuild.exe (i.e. MSVC_IDE is true) tblgen.exe ends on > bin/Release directory) Look for > > if( CMAKE_CROSSCOMPILING ) > > on the toplevel CMakeLists.txt and follow from there. > > [snip] I like to be able to just set it and forget it. When updating SVN or changing something in the source files the utils are dependent on it should just build it for me as part of the normal build process. As you said the CMAKE_CROSSCOMPILING does this but is dependent on make so it wasn't readily usable as is and only for tblgen. Applying the same solution to the other utils would require many changes as the executable path would have to be saved for each tool. I have attached a solution that is more flexible in that you can inherit the utils from another build directory with any desired options. It's all implemented in the scope of add_llvm_util. To set it up you would just do: cd buildutils cmake -DLLVM_UTILS_ONLY=ON ../llvm cd ../build cmake -DLLVM_UTILS_BUILD_DIR=../buildutils ../llvm [snip] Let me know what you think :) Regards, Erik -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: llvm-separate-utils-build-dir.patch.txt Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110320/5990eea4/attachment.txt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: benchmarks.txt Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110320/5990eea4/attachment-0001.txt From ofv at wanadoo.es Sun Mar 20 17:20:12 2011 From: ofv at wanadoo.es (=?utf-8?Q?=C3=93scar_Fuentes?=) Date: Sun, 20 Mar 2011 23:20:12 +0100 Subject: [llvm-commits] [PATCH] CMake option for enabling optimization for utilities in debug build In-Reply-To: <7574AA29-3662-4C3A-BD6D-1B1120EDCA34@hansoft.se> (Erik Olofsson's message of "Sun, 20 Mar 2011 22:16:23 +0100") References: <97510B8DF78E714D91EB4A27850A17DA0C3EACC0DD@winserv02.hansoft.local> <871v2aslqt.fsf@wanadoo.es> <97510B8DF78E714D91EB4A27850A17DA0C3EACC0DE@winserv02.hansoft.local> <87r5aaqyq2.fsf@wanadoo.es> <7574AA29-3662-4C3A-BD6D-1B1120EDCA34@hansoft.se> Message-ID: <871v211lk3.fsf@wanadoo.es> Hello Erik. I need to know something before we enter a deeper discussion about this issue: apart from tblgen, do we really benefit from using the other utilities compiled on release mode while working with a debug build? We know that using an optimized tblgen makes a difference, but I'll like to know about the other utils. Your attached benchmark does not show a significant gain for `make check-all' on OSX (only 7 seconds). OTOH, it improves 18 seconds the OSX build, which IMHO is not worthwhile. The real improvement is on VC++, but there you don't show the statistics for `check-all'. The speedup on build time are due to tblgen, which leaves us to... >>>> There is one way of using an optimized tlbgen executable: configure setting >>>> LLVM_TABLEGEN. You can point it to a tblgen.exe that still does not exist. >>>> Supposing that you are using VS and your build directory is c:\build : >>>> >>>> cmake -DLLVM_TABLEGEN=c:/build/bin/Release/tblgen.exe >>>> path/to/llvm/sources >>>> >>>> Now we build the tblgen target in Release mode. You can do that from the >>>> IDE but with the command line is: >>>> >>>> cmake --build . --target tblgen --config Release >>>> >>>> Now you can build in Debug mode. The tblgen.exe generated above will be >>>> used: >>>> >>>> cmake --build . --config Debug >>> >>> Yes, I suspected as much, but it's a lot of manual work each time you need to do it. You need to do that only once. Unless you delete and recreate your build directories very often (and in that case you would be using an script anyways) is the process described above so tiresome? > I like to be able to just set it and forget it. When updating SVN or changing something > in the source files the utils are dependent on it should just build it for me as part of > the normal build process. If the cross-compiling feature does not do that, it must be fixed. > As you said the CMAKE_CROSSCOMPILING does this but is dependent on make so > it wasn't readily usable as is and only for tblgen. The trivial change required for using CMAKE_CROSSCOMPILING with MSVC_IDE is, precisely, to use `cmake --build ...' instead of `make'. > Applying the same solution to the other utils would require many > changes as the executable path would have to be saved for each tool. I'm hoping that we don't really need to apply the same solution to the other utils. > I have attached a solution that is more flexible in that you can inherit the utils from > another build directory with any desired options. It's all implemented in the scope of > add_llvm_util. > > To set it up you would just do: > cd buildutils > cmake -DLLVM_UTILS_ONLY=ON ../llvm > cd ../build > cmake -DLLVM_UTILS_BUILD_DIR=../buildutils ../llvm And this is more convenient than setting LLVM_TABLEGEN how? > [snip] > > Let me know what you think :) 200+ lines of code for that feature? No way! :-) I think we can implement what you want with a simple modification to cmake/modules/CrossCompiling.cmake and configuring with cmake -DLLVM_TABLEGEN=buildit ... in that case it will act as if CMAKE_CROSSCOMPILING where active, build the external tblgen and set LLVM_TABLEGEN_EXE. I don't expect more than 15 lines for those tasks. If I had a decent Windows machine instead of a virtual one, it would already be done. Seeing that you really want to speedup the VC++ debug build, I'll reserve an hour this week to implement the feature :-) > +if( CMAKE_VERSION STRGREATER "2.8." ) We already require cmake >= 2.8 [snip] From evan.cheng at apple.com Sun Mar 20 20:19:09 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 21 Mar 2011 01:19:09 -0000 Subject: [llvm-commits] [llvm] r127981 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h lib/Transforms/Scalar/CodeGenPrepare.cpp Message-ID: <20110321011909.B352D2A6C12C@llvm.org> Author: evancheng Date: Sun Mar 20 20:19:09 2011 New Revision: 127981 URL: http://llvm.org/viewvc/llvm-project?rev=127981&view=rev Log: Re-apply r127953 with fixes: eliminate empty return block if it has no predecessors; update dominator tree if cfg is modified. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=127981&r1=127980&r2=127981&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Sun Mar 20 20:19:09 2011 @@ -1287,6 +1287,14 @@ return false; } + /// mayBeEmittedAsTailCall - Return true if the target may be able emit the + /// call instruction as a tail call. This is used by optimization passes to + /// determine if it's profitable to duplicate return instructions to enable + /// tailcall optimization. + virtual bool mayBeEmittedAsTailCall(CallInst *CI) const { + return false; + } + /// getTypeForExtArgOrReturn - Return the type that should be used to zero or /// sign extend a zeroext/signext integer argument or return value. /// FIXME: Most C calling convention requires the return type to be promoted, Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=127981&r1=127980&r2=127981&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Sun Mar 20 20:19:09 2011 @@ -1805,6 +1805,16 @@ return HasRet; } +bool ARMTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { + if (!EnableARMTailCalls) + return false; + + if (!CI->isTailCall()) + return false; + + return !Subtarget->isThumb1Only(); +} + // ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as // their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is // one of the above mentioned nodes. It has to be wrapped because otherwise Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=127981&r1=127980&r2=127981&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Sun Mar 20 20:19:09 2011 @@ -457,6 +457,8 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; + virtual bool mayBeEmittedAsTailCall(CallInst *CI) const; + SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &ARMcc, SelectionDAG &DAG, DebugLoc dl) const; SDValue getVFPCmp(SDValue LHS, SDValue RHS, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=127981&r1=127980&r2=127981&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sun Mar 20 20:19:09 2011 @@ -45,6 +45,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/VectorExtras.h" +#include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" @@ -1595,6 +1596,18 @@ return (CC == CallingConv::Fast || CC == CallingConv::GHC); } +bool X86TargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { + if (!CI->isTailCall()) + return false; + + CallSite CS(CI); + CallingConv::ID CalleeCC = CS.getCallingConv(); + if (!IsTailCallConvention(CalleeCC) && CalleeCC != CallingConv::C) + return false; + + return true; +} + /// FuncIsMadeTailCallSafe - Return true if the function is being made into /// a tailcall target by changing its ABI. static bool FuncIsMadeTailCallSafe(CallingConv::ID CC) { Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=127981&r1=127980&r2=127981&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Sun Mar 20 20:19:09 2011 @@ -843,6 +843,8 @@ virtual bool isUsedByReturnOnly(SDNode *N) const; + virtual bool mayBeEmittedAsTailCall(CallInst *CI) const; + virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, ISD::NodeType ExtendKind) const; Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=127981&r1=127980&r2=127981&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Sun Mar 20 20:19:09 2011 @@ -47,16 +47,17 @@ using namespace llvm::PatternMatch; STATISTIC(NumBlocksElim, "Number of blocks eliminated"); -STATISTIC(NumPHIsElim, "Number of trivial PHIs eliminated"); -STATISTIC(NumGEPsElim, "Number of GEPs converted to casts"); +STATISTIC(NumPHIsElim, "Number of trivial PHIs eliminated"); +STATISTIC(NumGEPsElim, "Number of GEPs converted to casts"); STATISTIC(NumCmpUses, "Number of uses of Cmp expressions replaced with uses of " "sunken Cmps"); STATISTIC(NumCastUses, "Number of uses of Cast expressions replaced with uses " "of sunken Casts"); STATISTIC(NumMemoryInsts, "Number of memory instructions whose address " "computations were sunk"); -STATISTIC(NumExtsMoved, "Number of [s|z]ext instructions combined with loads"); -STATISTIC(NumExtUses, "Number of uses of [s|z]ext instructions optimized"); +STATISTIC(NumExtsMoved, "Number of [s|z]ext instructions combined with loads"); +STATISTIC(NumExtUses, "Number of uses of [s|z]ext instructions optimized"); +STATISTIC(NumRetsDup, "Number of return instructions duplicated"); static cl::opt DisableBranchOpts( "disable-cgp-branch-opts", cl::Hidden, cl::init(false), @@ -75,11 +76,15 @@ /// update it. BasicBlock::iterator CurInstIterator; - // Keeps track of non-local addresses that have been sunk into a block. This - // allows us to avoid inserting duplicate code for blocks with multiple - // load/stores of the same address. + /// Keeps track of non-local addresses that have been sunk into a block. + /// This allows us to avoid inserting duplicate code for blocks with + /// multiple load/stores of the same address. DenseMap SunkAddrs; + /// UpdateDT - If CFG is modified in anyway, dominator tree may need to + /// be updated. + bool UpdateDT; + public: static char ID; // Pass identification, replacement for typeid explicit CodeGenPrepare(const TargetLowering *tli = 0) @@ -104,6 +109,7 @@ bool OptimizeCallInst(CallInst *CI); bool MoveExtToFormExtLoad(Instruction *I); bool OptimizeExtUses(Instruction *I); + bool DupRetToEnableTailCallOpts(ReturnInst *RI); }; } @@ -118,8 +124,10 @@ bool CodeGenPrepare::runOnFunction(Function &F) { bool EverMadeChange = false; + UpdateDT = false; DT = getAnalysisIfAvailable(); PFI = getAnalysisIfAvailable(); + // First pass, eliminate blocks that contain only PHI nodes and an // unconditional branch. EverMadeChange |= EliminateMostlyEmptyBlocks(F); @@ -127,8 +135,10 @@ bool MadeChange = true; while (MadeChange) { MadeChange = false; - for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (Function::iterator I = F.begin(), E = F.end(); I != E; ) { + BasicBlock *BB = I++; MadeChange |= OptimizeBlock(*BB); + } EverMadeChange |= MadeChange; } @@ -139,11 +149,14 @@ for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) MadeChange |= ConstantFoldTerminator(BB); - if (MadeChange && DT) - DT->DT->recalculate(F); + if (MadeChange) + UpdateDT = true; EverMadeChange |= MadeChange; } + if (UpdateDT && DT) + DT->DT->recalculate(F); + return EverMadeChange; } @@ -547,6 +560,102 @@ return Simplifier.fold(CI, TD); } +/// DupRetToEnableTailCallOpts - Look for opportunities to duplicate return +/// instructions to the predecessor to enable tail call optimizations. The +/// case it is currently looking for is: +/// bb0: +/// %tmp0 = tail call i32 @f0() +/// br label %return +/// bb1: +/// %tmp1 = tail call i32 @f1() +/// br label %return +/// bb2: +/// %tmp2 = tail call i32 @f2() +/// br label %return +/// return: +/// %retval = phi i32 [ %tmp0, %bb0 ], [ %tmp1, %bb1 ], [ %tmp2, %bb2 ] +/// ret i32 %retval +/// +/// => +/// +/// bb0: +/// %tmp0 = tail call i32 @f0() +/// ret i32 %tmp0 +/// bb1: +/// %tmp1 = tail call i32 @f1() +/// ret i32 %tmp1 +/// bb2: +/// %tmp2 = tail call i32 @f2() +/// ret i32 %tmp2 +/// +bool CodeGenPrepare::DupRetToEnableTailCallOpts(ReturnInst *RI) { + Value *V = RI->getReturnValue(); + if (!V) + return false; + + if (PHINode *PN = dyn_cast(V)) { + BasicBlock *BB = RI->getParent(); + if (PN->getParent() != BB) + return false; + + // It's not safe to eliminate the sign / zero extension of the return value. + // See llvm::isInTailCallPosition(). + const Function *F = BB->getParent(); + unsigned CallerRetAttr = F->getAttributes().getRetAttributes(); + if ((CallerRetAttr & Attribute::ZExt) || (CallerRetAttr & Attribute::SExt)) + return false; + + // Make sure there are no instructions between PHI and return. + BasicBlock::iterator BI = PN; + do { ++BI; } while (isa(BI)); + if (&*BI != RI) + return false; + + /// Only dup the ReturnInst if the CallInst is likely to be emitted as a + /// tail call. + SmallVector TailCalls; + for (unsigned I = 0, E = PN->getNumIncomingValues(); I != E; ++I) { + CallInst *CI = dyn_cast(PN->getIncomingValue(I)); + // Make sure the phi value is indeed produced by the tail call. + if (CI && CI->hasOneUse() && CI->getParent() == PN->getIncomingBlock(I) && + TLI->mayBeEmittedAsTailCall(CI)) + TailCalls.push_back(CI); + } + + bool Changed = false; + for (unsigned i = 0, e = TailCalls.size(); i != e; ++i) { + CallInst *CI = TailCalls[i]; + CallSite CS(CI); + + // Conservatively require the attributes of the call to match those of + // the return. Ignore noalias because it doesn't affect the call sequence. + unsigned CalleeRetAttr = CS.getAttributes().getRetAttributes(); + if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias) + continue; + + // Make sure the call instruction is followed by an unconditional branch + // to the return block. + BasicBlock *CallBB = CI->getParent(); + BranchInst *BI = dyn_cast(CallBB->getTerminator()); + if (!BI || !BI->isUnconditional() || BI->getSuccessor(0) != BB) + continue; + + // Duplicate the return into CallBB. + (void)FoldReturnIntoUncondBranch(RI, BB, CallBB); + UpdateDT = Changed = true; + ++NumRetsDup; + } + + // If we eliminated all predecessors of the block, delete the block now. + if (Changed && pred_begin(BB) == pred_end(BB)) + BB->eraseFromParent(); + + return Changed; + } + + return false; +} + //===----------------------------------------------------------------------===// // Memory Optimization //===----------------------------------------------------------------------===// @@ -970,6 +1079,9 @@ if (CallInst *CI = dyn_cast(I)) return OptimizeCallInst(CI); + if (ReturnInst *RI = dyn_cast(I)) + return DupRetToEnableTailCallOpts(RI); + return false; } From eli.friedman at gmail.com Sun Mar 20 20:33:03 2011 From: eli.friedman at gmail.com (Eli Friedman) Date: Mon, 21 Mar 2011 01:33:03 -0000 Subject: [llvm-commits] [llvm] r127982 - /llvm/trunk/lib/Target/README.txt Message-ID: <20110321013303.769482A6C12C@llvm.org> Author: efriedma Date: Sun Mar 20 20:33:03 2011 New Revision: 127982 URL: http://llvm.org/viewvc/llvm-project?rev=127982&view=rev Log: This README entry was fixed recently. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=127982&r1=127981&r2=127982&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sun Mar 20 20:33:03 2011 @@ -392,34 +392,6 @@ //===---------------------------------------------------------------------===// -LSR should know what GPR types a target has from TargetData. This code: - -volatile short X, Y; // globals - -void foo(int N) { - int i; - for (i = 0; i < N; i++) { X = i; Y = i*4; } -} - -produces two near identical IV's (after promotion) on PPC/ARM: - -LBB1_2: - ldr r3, LCPI1_0 - ldr r3, [r3] - strh r2, [r3] - ldr r3, LCPI1_1 - ldr r3, [r3] - strh r1, [r3] - add r1, r1, #4 - add r2, r2, #1 <- [0,+,1] - sub r0, r0, #1 <- [0,-,1] - cmp r0, #0 - bne LBB1_2 - -LSR should reuse the "+" IV for the exit test. - -//===---------------------------------------------------------------------===// - Tail call elim should be more aggressive, checking to see if the call is followed by an uncond branch to an exit block. From nicholas at mxc.ca Sun Mar 20 21:26:02 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 21 Mar 2011 02:26:02 -0000 Subject: [llvm-commits] [llvm] r127984 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <20110321022602.16FF92A6C12C@llvm.org> Author: nicholas Date: Sun Mar 20 21:26:01 2011 New Revision: 127984 URL: http://llvm.org/viewvc/llvm-project?rev=127984&view=rev Log: Fix comments Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=127984&r1=127983&r2=127984&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Mar 20 21:26:01 2011 @@ -2726,7 +2726,7 @@ static bool cxxDtorIsEmpty(const Function &Fn, SmallPtrSet &CalledFunctions) { // FIXME: We could eliminate C++ destructors if they're readonly/readnone and - // unwind, but that doesn't seem worth doing. + // nounwind, but that doesn't seem worth doing. if (Fn.isDeclaration()) return false; @@ -2768,7 +2768,7 @@ /// This registration, e.g. __cxa_atexit(f,p,d), is intended to cause the /// call f(p) when DSO d is unloaded, before all such termination calls /// registered before this one. It returns zero if registration is - /// successful, nonzero on failure. + /// successful, nonzero on failure. // This pass will look for calls to __cxa_atexit where the function is trivial // and remove them. From nicholas at mxc.ca Sun Mar 20 21:32:50 2011 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 20 Mar 2011 19:32:50 -0700 Subject: [llvm-commits] [llvm] r127970 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll In-Reply-To: <20110320175911.814CD2A6C12C@llvm.org> References: <20110320175911.814CD2A6C12C@llvm.org> Message-ID: <4D86B8D2.4010806@mxc.ca> Anders Carlsson wrote: > Author: andersca > Date: Sun Mar 20 12:59:11 2011 > New Revision: 127970 > > URL: http://llvm.org/viewvc/llvm-project?rev=127970&view=rev > Log: > Add an optimization to GlobalOpt that eliminates calls to __cxa_atexit, if the function passed is empty. Very cool! I think you should also skip debugging intrinsics when determining whether the destructor is empty. Those may be left behind after the contents of a destructor was optimized away, and in general we want '-g -O2' to degrade the debug info without impacting the optimizers. Nick > > Added: > llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll > Modified: > llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp > > Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=127970&r1=127969&r2=127970&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) > +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Mar 20 12:59:11 2011 > @@ -54,6 +54,7 @@ > STATISTIC(NumNestRemoved , "Number of nest attributes removed"); > STATISTIC(NumAliasesResolved, "Number of global aliases resolved"); > STATISTIC(NumAliasesRemoved, "Number of global aliases eliminated"); > +STATISTIC(NumCXXDtorsRemoved, "Number of global C++ destructors removed"); > > namespace { > struct GlobalStatus; > @@ -77,6 +78,7 @@ > bool ProcessInternalGlobal(GlobalVariable *GV,Module::global_iterator&GVI, > const SmallPtrSet &PHIUsers, > const GlobalStatus&GS); > + bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn); > }; > } > > @@ -2696,12 +2698,106 @@ > return Changed; > } > > +static Function *FindCXAAtExit(Module&M) { > + Function *Fn = M.getFunction("__cxa_atexit"); > + > + if (!Fn) > + return 0; > + > + const FunctionType *FTy = Fn->getFunctionType(); > + > + // Checking that the function has the right number of parameters and that they > + // all have pointer types should be enough. > + if (FTy->getNumParams() != 3 || > + !FTy->getParamType(0)->isPointerTy() || > + !FTy->getParamType(1)->isPointerTy() || > + !FTy->getParamType(2)->isPointerTy()) > + return 0; > + > + return Fn; > +} > + > +/// cxxDtorIsEmpty - Returns whether the given function is an empty C++ > +/// destructor and can therefore be eliminated. > +/// Note that we assume that other optimization passes have already simplified > +/// the code so we only look for a function with a single basic block, where > +/// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. > +static bool cxxDtorIsEmpty(const Function& Fn) { > + if (Fn.empty()) > + return true; > + > + if (++Fn.begin() != Fn.end()) > + return false; > + > + const BasicBlock&EntryBlock = Fn.getEntryBlock(); > + for (BasicBlock::const_iterator I = EntryBlock.begin(), E = EntryBlock.end(); > + I != E; ++I) { > + if (const CallInst *CI = dyn_cast(I)) { > + const Function *CalledFn = CI->getCalledFunction(); > + > + if (!CalledFn) > + return false; > + > + if (!cxxDtorIsEmpty(*CalledFn)) > + return false; > + } else if (isa(*I)) > + return true; > + else > + return false; > + } > + > + return false; > +} > + > +bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) { > + /// Itanium C++ ABI p3.3.5: > + /// > + /// After constructing a global (or local static) object, that will require > + /// destruction on exit, a termination function is registered as follows: > + /// > + /// extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); > + /// > + /// This registration, e.g. __cxa_atexit(f,p,d), is intended to cause the > + /// call f(p) when DSO d is unloaded, before all such termination calls > + /// registered before this one. It returns zero if registration is > + /// successful, nonzero on failure. > + > + // This pass will look for calls to __cxa_atexit where the function is trivial > + // and remove them. > + bool Changed = false; > + > + for (Function::use_iterator I = CXAAtExitFn->use_begin(), > + E = CXAAtExitFn->use_end(); I != E;) { > + CallSite CS(*I++); > + if (!CS.getInstruction()) > + continue; > + > + Function *DtorFn = > + dyn_cast(CS.getArgument(0)->stripPointerCasts()); > + if (!DtorFn) > + continue; > + > + if (!cxxDtorIsEmpty(*DtorFn)) > + continue; > + > + // Just remove the call. > + CS.getInstruction()->eraseFromParent(); > + ++NumCXXDtorsRemoved; > + > + Changed |= true; > + } > + > + return Changed; > +} > + > bool GlobalOpt::runOnModule(Module&M) { > bool Changed = false; > > // Try to find the llvm.globalctors list. > GlobalVariable *GlobalCtors = FindGlobalCtors(M); > > + Function *CXAAtExitFn = FindCXAAtExit(M); > + > bool LocalChange = true; > while (LocalChange) { > LocalChange = false; > @@ -2718,6 +2814,11 @@ > > // Resolve aliases, when possible. > LocalChange |= OptimizeGlobalAliases(M); > + > + // Try to remove trivial global destructors. > + if (CXAAtExitFn) > + LocalChange |= OptimizeEmptyGlobalCXXDtors(CXAAtExitFn); > + > Changed |= LocalChange; > } > > > Added: llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll?rev=127970&view=auto > ============================================================================== > --- llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll (added) > +++ llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll Sun Mar 20 12:59:11 2011 > @@ -0,0 +1,31 @@ > +; RUN: opt< %s -globalopt -S | FileCheck %s > + > +%0 = type { i32, void ()* } > +%struct.A = type { i8 } > + > + at a = global %struct.A zeroinitializer, align 1 > + at __dso_handle = external global i8* > + at llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I_a }] > + > +; CHECK-NOT: call i32 @__cxa_atexit > + > +define internal void @__cxx_global_var_init() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { > + %1 = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) > + ret void > +} > + > +define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 { > + call void @_ZN1AD2Ev(%struct.A* %this) > + ret void > +} > + > +declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) > + > +define linkonce_odr void @_ZN1AD2Ev(%struct.A* %this) nounwind align 2 { > + ret void > +} > + > +define internal void @_GLOBAL__I_a() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { > + call void @__cxx_global_var_init() > + ret void > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From andersca at mac.com Sun Mar 20 21:42:28 2011 From: andersca at mac.com (Anders Carlsson) Date: Mon, 21 Mar 2011 02:42:28 -0000 Subject: [llvm-commits] [llvm] r127985 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <20110321024228.28FDC2A6C12C@llvm.org> Author: andersca Date: Sun Mar 20 21:42:27 2011 New Revision: 127985 URL: http://llvm.org/viewvc/llvm-project?rev=127985&view=rev Log: As suggested by Nick Lewycky, ignore debugging intrinsics when trying to decide whether a destructor is empty or not. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=127985&r1=127984&r2=127985&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Mar 20 21:42:27 2011 @@ -2742,6 +2742,13 @@ if (!CalledFn) return false; + if (unsigned IntrinsicID = CalledFn->getIntrinsicID()) { + // Ignore debug intrinsics. + if (IntrinsicID == llvm::Intrinsic::dbg_declare || + IntrinsicID == llvm::Intrinsic::dbg_value) + continue; + } + // Don't treat recursive functions as empty. if (!CalledFunctions.insert(CalledFn)) return false; From isanbard at gmail.com Sun Mar 20 23:13:46 2011 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 21 Mar 2011 04:13:46 -0000 Subject: [llvm-commits] [llvm] r127986 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/ lib/MC/MCDisassembler/ lib/Target/ARM/ lib/Target/ARM/InstPrinter/ lib/Target/MBlaze/ lib/Target/MBlaze/InstPrinter/ lib/Target/MSP430/ lib/Target/MSP430/InstPrinter/ lib/Target/PowerPC/ lib/Target/PowerPC/InstPrinter/ lib/Target/X86/ lib/Target/X86/InstPrinter/ tools/llvm-mc/ tools/llvm-objdump/ Message-ID: <20110321041346.B81EE2A6C12C@llvm.org> Author: void Date: Sun Mar 20 23:13:46 2011 New Revision: 127986 URL: http://llvm.org/viewvc/llvm-project?rev=127986&view=rev Log: We need to pass the TargetMachine object to the InstPrinter if we are printing the alias of an InstAlias instead of the thing being aliased. Because we need to know the features that are valid for an InstAlias. This is part of a work-in-progress. Modified: llvm/trunk/include/llvm/Target/TargetRegistry.h llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h llvm/trunk/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h llvm/trunk/lib/Target/MBlaze/MBlazeAsmPrinter.cpp llvm/trunk/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp llvm/trunk/tools/llvm-mc/Disassembler.cpp llvm/trunk/tools/llvm-mc/Disassembler.h llvm/trunk/tools/llvm-mc/llvm-mc.cpp llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Modified: llvm/trunk/include/llvm/Target/TargetRegistry.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegistry.h?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegistry.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegistry.h Sun Mar 20 23:13:46 2011 @@ -78,6 +78,7 @@ TargetMachine &TM); typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, + TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI); typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T, @@ -286,11 +287,12 @@ return MCDisassemblerCtorFn(*this); } - MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, + MCInstPrinter *createMCInstPrinter(TargetMachine &TM, + unsigned SyntaxVariant, const MCAsmInfo &MAI) const { if (!MCInstPrinterCtorFn) return 0; - return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI); + return MCInstPrinterCtorFn(*this, TM, SyntaxVariant, MAI); } Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Sun Mar 20 23:13:46 2011 @@ -133,7 +133,7 @@ default: return true; case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = - getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI); + getTarget().createMCInstPrinter(*this, MAI.getAssemblerDialect(), MAI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; Modified: llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp (original) +++ llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp Sun Mar 20 23:13:46 2011 @@ -193,7 +193,8 @@ InstString.reset(new std::string); InstStream.reset(new raw_string_ostream(*InstString)); - InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo)); + InstPrinter.reset(Tgt->createMCInstPrinter(*TargetMachine, LLVMSyntaxVariant, + *AsmInfo)); if (!InstPrinter) return; Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Sun Mar 20 23:13:46 2011 @@ -1791,10 +1791,11 @@ //===----------------------------------------------------------------------===// static MCInstPrinter *createARMMCInstPrinter(const Target &T, + TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI) { if (SyntaxVariant == 0) - return new ARMInstPrinter(MAI); + return new ARMInstPrinter(TM, MAI); return 0; } Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Sun Mar 20 23:13:46 2011 @@ -17,11 +17,14 @@ #include "llvm/MC/MCInstPrinter.h" namespace llvm { - class MCOperand; + +class MCOperand; +class TargetMachine; class ARMInstPrinter : public MCInstPrinter { public: - ARMInstPrinter(const MCAsmInfo &MAI) : MCInstPrinter(MAI) {} + ARMInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) + : MCInstPrinter(MAI) {} virtual void printInst(const MCInst *MI, raw_ostream &O); virtual StringRef getOpcodeName(unsigned Opcode) const; Modified: llvm/trunk/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h (original) +++ llvm/trunk/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h Sun Mar 20 23:13:46 2011 @@ -18,11 +18,12 @@ namespace llvm { class MCOperand; + class TargetMachine; class MBlazeInstPrinter : public MCInstPrinter { public: - MBlazeInstPrinter(const MCAsmInfo &MAI) : MCInstPrinter(MAI) { - } + MBlazeInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) + : MCInstPrinter(MAI) {} virtual void printInst(const MCInst *MI, raw_ostream &O); Modified: llvm/trunk/lib/Target/MBlaze/MBlazeAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeAsmPrinter.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeAsmPrinter.cpp Sun Mar 20 23:13:46 2011 @@ -319,10 +319,11 @@ } static MCInstPrinter *createMBlazeMCInstPrinter(const Target &T, + TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI) { if (SyntaxVariant == 0) - return new MBlazeInstPrinter(MAI); + return new MBlazeInstPrinter(TM, MAI); return 0; } Modified: llvm/trunk/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h (original) +++ llvm/trunk/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h Sun Mar 20 23:13:46 2011 @@ -18,11 +18,12 @@ namespace llvm { class MCOperand; + class TargetMachine; class MSP430InstPrinter : public MCInstPrinter { public: - MSP430InstPrinter(const MCAsmInfo &MAI) : MCInstPrinter(MAI) { - } + MSP430InstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) + : MCInstPrinter(MAI) {} virtual void printInst(const MCInst *MI, raw_ostream &O); Modified: llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp Sun Mar 20 23:13:46 2011 @@ -164,10 +164,11 @@ } static MCInstPrinter *createMSP430MCInstPrinter(const Target &T, + TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI) { if (SyntaxVariant == 0) - return new MSP430InstPrinter(MAI); + return new MSP430InstPrinter(TM, MAI); return 0; } Modified: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h (original) +++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h Sun Mar 20 23:13:46 2011 @@ -17,13 +17,16 @@ #include "llvm/MC/MCInstPrinter.h" namespace llvm { - class MCOperand; + +class MCOperand; +class TargetMachine; class PPCInstPrinter : public MCInstPrinter { // 0 -> AIX, 1 -> Darwin. unsigned SyntaxVariant; public: - PPCInstPrinter(const MCAsmInfo &MAI, unsigned syntaxVariant) + PPCInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI, + unsigned syntaxVariant) : MCInstPrinter(MAI), SyntaxVariant(syntaxVariant) {} bool isDarwinSyntax() const { Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Sun Mar 20 23:13:46 2011 @@ -680,9 +680,10 @@ } static MCInstPrinter *createPPCMCInstPrinter(const Target &T, + TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI) { - return new PPCInstPrinter(MAI, SyntaxVariant); + return new PPCInstPrinter(TM, MAI, SyntaxVariant); } Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h (original) +++ llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h Sun Mar 20 23:13:46 2011 @@ -17,12 +17,14 @@ #include "llvm/MC/MCInstPrinter.h" namespace llvm { - class MCOperand; + +class MCOperand; +class TargetMachine; class X86ATTInstPrinter : public MCInstPrinter { public: - X86ATTInstPrinter(const MCAsmInfo &MAI) : MCInstPrinter(MAI) {} - + X86ATTInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) + : MCInstPrinter(MAI) {} virtual void printInst(const MCInst *MI, raw_ostream &OS); virtual StringRef getOpcodeName(unsigned Opcode) const; Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h (original) +++ llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h Sun Mar 20 23:13:46 2011 @@ -18,11 +18,13 @@ #include "llvm/Support/raw_ostream.h" namespace llvm { - class MCOperand; + +class MCOperand; +class TargetMachine; class X86IntelInstPrinter : public MCInstPrinter { public: - X86IntelInstPrinter(const MCAsmInfo &MAI) + X86IntelInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) : MCInstPrinter(MAI) {} virtual void printInst(const MCInst *MI, raw_ostream &OS); Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Sun Mar 20 23:13:46 2011 @@ -709,12 +709,13 @@ //===----------------------------------------------------------------------===// static MCInstPrinter *createX86MCInstPrinter(const Target &T, + TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI) { if (SyntaxVariant == 0) - return new X86ATTInstPrinter(MAI); + return new X86ATTInstPrinter(TM, MAI); if (SyntaxVariant == 1) - return new X86IntelInstPrinter(MAI); + return new X86IntelInstPrinter(TM, MAI); return 0; } Modified: llvm/trunk/tools/llvm-mc/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/Disassembler.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/tools/llvm-mc/Disassembler.cpp (original) +++ llvm/trunk/tools/llvm-mc/Disassembler.cpp Sun Mar 20 23:13:46 2011 @@ -127,7 +127,8 @@ return false; } -int Disassembler::disassemble(const Target &T, const std::string &Triple, +int Disassembler::disassemble(const Target &T, TargetMachine &TM, + const std::string &Triple, MemoryBuffer &Buffer, raw_ostream &Out) { // Set up disassembler. @@ -145,7 +146,7 @@ } int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); - OwningPtr IP(T.createMCInstPrinter(AsmPrinterVariant, + OwningPtr IP(T.createMCInstPrinter(TM, AsmPrinterVariant, *AsmInfo)); if (!IP) { errs() << "error: no instruction printer for target " << Triple << '\n'; Modified: llvm/trunk/tools/llvm-mc/Disassembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/Disassembler.h?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/tools/llvm-mc/Disassembler.h (original) +++ llvm/trunk/tools/llvm-mc/Disassembler.h Sun Mar 20 23:13:46 2011 @@ -19,13 +19,15 @@ namespace llvm { -class Target; class MemoryBuffer; +class Target; +class TargetMachine; class raw_ostream; class Disassembler { public: - static int disassemble(const Target &target, + static int disassemble(const Target &target, + TargetMachine &TM, const std::string &tripleString, MemoryBuffer &buffer, raw_ostream &Out); Modified: llvm/trunk/tools/llvm-mc/llvm-mc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/llvm-mc.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/tools/llvm-mc/llvm-mc.cpp (original) +++ llvm/trunk/tools/llvm-mc/llvm-mc.cpp Sun Mar 20 23:13:46 2011 @@ -342,7 +342,7 @@ // FIXME: There is a bit of code duplication with addPassesToEmitFile. if (FileType == OFT_AssemblyFile) { MCInstPrinter *IP = - TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI); + TheTarget->createMCInstPrinter(*TM, OutputAsmVariant, *MAI); MCCodeEmitter *CE = 0; TargetAsmBackend *TAB = 0; if (ShowEncoding) { @@ -403,12 +403,34 @@ return 1; int Res; - if (Enhanced) + if (Enhanced) { Res = Disassembler::disassembleEnhanced(TripleName, *Buffer.take(), Out->os()); - else - Res = Disassembler::disassemble(*TheTarget, TripleName, + } else { + // Package up features to be passed to target/subtarget + std::string FeaturesStr; + if (MCPU.size()) { + SubtargetFeatures Features; + Features.setCPU(MCPU); + FeaturesStr = Features.getString(); + } + + // FIXME: We shouldn't need to do this (and link in codegen). + // When we split this out, we should do it in a way that makes + // it straightforward to switch subtargets on the fly (.e.g, + // the .cpu and .code16 directives). + OwningPtr TM(TheTarget->createTargetMachine(TripleName, + FeaturesStr)); + + if (!TM) { + errs() << ProgName << ": error: could not create target for triple '" + << TripleName << "'.\n"; + return 1; + } + + Res = Disassembler::disassemble(*TheTarget, *TM, TripleName, *Buffer.take(), Out->os()); + } // Keep output if no errors. if (Res == 0) Out->keep(); Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=127986&r1=127985&r2=127986&view=diff ============================================================================== --- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original) +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Sun Mar 20 23:13:46 2011 @@ -38,6 +38,7 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetSelect.h" #include @@ -182,9 +183,21 @@ return; } + // FIXME: We shouldn't need to do this (and link in codegen). + // When we split this out, we should do it in a way that makes + // it straightforward to switch subtargets on the fly (.e.g, + // the .cpu and .code16 directives). + std::string FeaturesStr; + OwningPtr TM(TheTarget->createTargetMachine(TripleName, + FeaturesStr)); + if (!TM) { + errs() << "error: could not create target for triple " << TripleName << "\n"; + return; + } + int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); OwningPtr IP(TheTarget->createMCInstPrinter( - AsmPrinterVariant, *AsmInfo)); + *TM, AsmPrinterVariant, *AsmInfo)); if (!IP) { errs() << "error: no instruction printer for target " << TripleName << '\n'; return; From Erik.Olofsson at hansoft.se Sun Mar 20 23:25:46 2011 From: Erik.Olofsson at hansoft.se (Erik Olofsson) Date: Mon, 21 Mar 2011 05:25:46 +0100 Subject: [llvm-commits] [PATCH] CMake option for enabling optimization for utilities in debug build In-Reply-To: <871v211lk3.fsf@wanadoo.es> References: <97510B8DF78E714D91EB4A27850A17DA0C3EACC0DD@winserv02.hansoft.local> <871v2aslqt.fsf@wanadoo.es> <97510B8DF78E714D91EB4A27850A17DA0C3EACC0DE@winserv02.hansoft.local> <87r5aaqyq2.fsf@wanadoo.es> <7574AA29-3662-4C3A-BD6D-1B1120EDCA34@hansoft.se> <871v211lk3.fsf@wanadoo.es> Message-ID: <17AFC884-BDAF-419B-9912-72D132697713@hansoft.se> On 20 mar 2011, at 23.20, ?scar Fuentes wrote: > Hello Erik. > > I need to know something before we enter a deeper discussion about this > issue: apart from tblgen, do we really benefit from using the other > utilities compiled on release mode while working with a debug build? We > know that using an optimized tblgen makes a difference, but I'll like to > know about the other utils. Your attached benchmark does not show a > significant gain for `make check-all' on OSX (only 7 seconds). OTOH, it > improves 18 seconds the OSX build, which IMHO is not worthwhile. The > real improvement is on VC++, but there you don't show the statistics for > `check-all'. The speedup on build time are due to tblgen, which leaves > us to... No, actually on Windows it turned out to make no difference at all on test time. [snip] > 200+ lines of code for that feature? No way! :-) > > I think we can implement what you want with a simple modification to > cmake/modules/CrossCompiling.cmake and configuring with > > cmake -DLLVM_TABLEGEN=buildit ... > > in that case it will act as if CMAKE_CROSSCOMPILING where active, build > the external tblgen and set LLVM_TABLEGEN_EXE. > > I don't expect more than 15 lines for those tasks. If I had a decent > Windows machine instead of a virtual one, it would already be > done. Seeing that you really want to speedup the VC++ debug build, I'll > reserve an hour this week to implement the feature :-) So i tried this solution and it turned out that all kinds of dependencies were broken when doing this on Visual Studio. When you set LLVM_TABLEGEN_EXE to something else CMake will omit adding dependencies to tblgen on all projects that should have it as dependency. I added those manually. Many of the changes to CrossCompileLLVM.cmake was needed to make it not compile and compile again creating a new tblgen.exe that caused all Tablegenning to be run each build. I also had to add the source files as dependencies so it would actually run again when something in tblgen changed. This could probably be fixed by changing the dependency on tblgen to NativeTableGen on all projects, then reverse the dependencies between tblgen and NativeTableGen. Then you just needs a DEPENDS on the output of tblgen to get the correct dependency checking for when NativeTableGen is supposed to rebuild. See attached patches and new benchmarks. All in all the patch is almost as large as the last one and touches more files :) Regards, Erik -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: benchmarks.txt Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110321/c0ff8a60/attachment.txt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: llvm-release-tblgen.patch.txt Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110321/c0ff8a60/attachment-0001.txt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: clang-release-tblgen.patch.txt Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110321/c0ff8a60/attachment-0002.txt