From zhousheng00 at gmail.com Mon Mar 12 00:45:09 2007 From: zhousheng00 at gmail.com (Zhou Sheng) Date: Mon, 12 Mar 2007 00:45:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200703120545.l2C5j9vc010100@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.652 -> 1.653 --- Log message: In function ComputeMaskedBits(): 1. Replace getSignedMinValue() with getSignBit() for better code readability. 2. Replace APIntOps::shl() with operator<<= for convenience. 3. Make APInt construction more effective. --- Diffs of the changes: (+6 -6) InstructionCombining.cpp | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.652 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.653 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.652 Thu Mar 8 09:15:18 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 12 00:44:52 2007 @@ -695,7 +695,7 @@ // If the sign bit of the input is known set or clear, then we know the // top bits of the result. - APInt InSignBit(APInt::getSignedMinValue(SrcTy->getBitWidth())); + APInt InSignBit(APInt::getSignBit(SrcTy->getBitWidth())); InSignBit.zextOrTrunc(BitWidth); if ((KnownZero & InSignBit) != 0) { // Input sign bit known zero KnownZero |= NewBits; @@ -716,8 +716,8 @@ Mask = APIntOps::lshr(Mask, ShiftAmt); ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - KnownZero = APIntOps::shl(KnownZero, ShiftAmt); - KnownOne = APIntOps::shl(KnownOne, ShiftAmt); + KnownZero <<= ShiftAmt; + KnownOne <<= ShiftAmt; KnownZero |= APInt(BitWidth, 1ULL).shl(ShiftAmt)-1; // low bits known zero. return; } @@ -730,7 +730,7 @@ APInt HighBits(APInt::getAllOnesValue(BitWidth).shl(BitWidth-ShiftAmt)); // Unsigned shift right. - Mask = APIntOps::shl(Mask, ShiftAmt); + Mask <<= ShiftAmt; ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1); assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?"); KnownZero = APIntOps::lshr(KnownZero, ShiftAmt); @@ -747,14 +747,14 @@ APInt HighBits(APInt::getAllOnesValue(BitWidth).shl(BitWidth-ShiftAmt)); // Signed shift right. - Mask = APIntOps::shl(Mask, ShiftAmt); + Mask <<= ShiftAmt; ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1); assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?"); KnownZero = APIntOps::lshr(KnownZero, ShiftAmt); KnownOne = APIntOps::lshr(KnownOne, ShiftAmt); // Handle the sign bits and adjust to where it is now in the mask. - APInt SignBit = APInt::getSignedMinValue(BitWidth).lshr(ShiftAmt); + APInt SignBit(APInt::getSignBit(BitWidth).lshr(ShiftAmt)); if ((KnownZero & SignBit) != 0) { // New bits are known zero. KnownZero |= HighBits; From nicolas.geoffray at lip6.fr Mon Mar 12 09:57:06 2007 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 12 Mar 2007 15:57:06 +0100 Subject: [llvm-commits] llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp In-Reply-To: References: <45E46A95.5000500@lip6.fr> <061382E6-AE05-4A71-899F-098B91E14DA3@apple.com> <45E7F5A0.2000604@lip6.fr> <45E98679.2000908@lip6.fr> <45EBDBCD.7070509@lip6.fr> Message-ID: <45F56A42.40803@lip6.fr> Hi Chris, Chris Lattner wrote: > Ahhh, ok. I think I understand now what is going on. Thank you for > the very clear explanation. > > In this case, it seems like a clearly good thing to just call > CreateFixedObject unconditionally early on (e.g.) when lowering the > arguments. > Unconditionally? I can do that, but do you mean without any check if R31 is actually used as frame pointer or we're compiling for linux/ppc? Nicolas From nicolas.geoffray at lip6.fr Mon Mar 12 10:36:31 2007 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 12 Mar 2007 16:36:31 +0100 Subject: [llvm-commits] Stack and register alignment in linux/ppc calls In-Reply-To: <856FC03F-5F37-4D10-9115-40A7C050051B@apple.com> References: <45EDACD4.5050407@lip6.fr> <856FC03F-5F37-4D10-9115-40A7C050051B@apple.com> Message-ID: <45F5737F.2050807@lip6.fr> Here's the final patch with the modifications you suggested. Thx a lot for your reviewing Chris. If everything's OK I'm checking this in soon. Cheers, Nicolas Chris Lattner wrote: > > On Mar 6, 2007, at 10:03 AM, Nicolas Geoffray wrote: >> This patch corrects arguments passing alignment for linux/ppc calls >> (ELF ABI). >> It affects LowerFORMAL_ARGUMENTS and LowerCALL of PPCISelLowering.cpp. > > Sure, sorry for the delay. Please add some high-level comments that > explain what is going on here (what the ABI says). I would eventually > like to switch PPC over to using autogenerated callingconv code, but I > haven't had a chance to finish argument passing. > >> @@ -1164,24 +1165,34 @@ static SDOperand LowerFORMAL_ARGUMENTS(S >> SDOperand ArgVal; >> bool needsLoad = false; >> MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); >> unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; >> unsigned ArgSize = ObjSize; >> + unsigned Flags = >> cast(Op.getOperand(ArgNo+3))->getValue(); >> + // See if next argument requires stack alignment in ELF >> + unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 < e) && >> + (cast(Op.getOperand(ArgNo+4))->getValue() & (1 >> << 27)) && >> + (!(Flags & (1 << 27)))); > > Please update this to use the enums that anton recently added for > decoding the flags values. > >> unsigned CurArgOffset = ArgOffset; >> switch (ObjectVT) { >> default: assert(0 && "Unhandled argument type!"); >> case MVT::i32: >> + // Double word align in ELF >> + if (Expand && !isELF_ABI && !isPPC64) GPR_idx += (GPR_idx % 2); > > This says "!isELF_ABI", shouldn't it be "isELF_ABI"? If not, you're > modifying the Darwin/PPC ABI. > >> - >> + unsigned Flags = >> cast(Op.getOperand(5+2*i+1))->getValue(); >> + // See if next argument requires stack alignment in ELF >> + unsigned Expand = (Arg.getValueType() == MVT::f64) || >> + ((i + 1 < NumOps) && >> + (cast(Op.getOperand(5+2*(i+1)+1))->getValue() >> + & (1 << >> 27)) && >> + (!(Flags & (1 << 27)))); > > Likewise, plz use enums here. Also, there is some funky indentation > going on here. Perhaps making a "ConstantSDNode *Tmp" would make this > more natural. > >> // PtrOff will be used to store the current argument to the >> stack if a >> // register cannot be found for it. >> - SDOperand PtrOff = DAG.getConstant(ArgOffset, >> StackPtr.getValueType()); >> + SDOperand PtrOff; >> + >> + // Stack align in ELF >> + if (isELF_ABI && Expand && !isPPC64) >> + PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * >> PtrByteSize, >> + StackPtr.getValueType()); >> + else >> + PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); >> + > > Funky indentation. Statements should be indented by 2. > Subexpressions (StackPtr.getValueType() should be aligned to the (. > > Otherwise, looks great, thanks! > > -Chris -------------- next part -------------- A non-text attachment was scrubbed... Name: calling-conv-ELF.patch Type: text/x-patch Size: 7811 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070312/19417c7f/attachment.bin From alenhar2 at cs.uiuc.edu Mon Mar 12 11:41:45 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 12 Mar 2007 11:41:45 -0500 Subject: [llvm-commits] [see] CVS: llvm-poolalloc/lib/DSA/Local.cpp Message-ID: <200703121641.l2CGfjI5027435@apoc.cs.uiuc.edu> Changes in directory llvm-poolalloc/lib/DSA: Local.cpp updated: 1.158.2.4.2.4 -> 1.158.2.4.2.5 --- Log message: this could be bad, but it doesn't trigger --- Diffs of the changes: (+27 -0) Local.cpp | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+) Index: llvm-poolalloc/lib/DSA/Local.cpp diff -u llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.4 llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.5 --- llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.4 Fri Mar 9 11:27:51 2007 +++ llvm-poolalloc/lib/DSA/Local.cpp Mon Mar 12 11:41:06 2007 @@ -1451,6 +1451,33 @@ EliminateUsesOfECGlobals(*I->second, ECGlobals); } +#ifdef LLVA_KERNEL + + // Ugly hack. kmem_cache_allocs are in the same pool also if the kmem_cache_t's are the same + // this only works on global kmem_cache_ts + Function* KMA = M.getNamedFunction("kmem_cache_alloc"); + if (KMA) { + for (Value::use_iterator ii = KMA->use_begin(), ee = KMA->use_end(); + ii != ee; ++ii) { + std::map locs; + if (CallInst* CI = dyn_cast(*ii)) { + if (CI->getCalledFunction() == KMA && isa(CI->getOperand(1))) { + Value* V = CI->getOperand(1); //the kmem_cache_alloc + DSNodeHandle DSH = DSInfo[CI->getParent()->getParent()]->getNodeForValue(CI); + MetaPoolHandle L(locs[V]), N(DSH.getNode()->getMP()); + if (L.getPool() != N.getPool()) { + std::cerr << "kmem_cache_alloc recovered merge\n"; + MetaPoolHandle L(locs[V]), N(DSH.getNode()->getMP()); + locs[V]->merge(DSH.getNode()->getMP()); + } + locs[V] = DSH.getNode()->getMP(); + } + } + } + } + +#endif + return false; } From zhousheng00 at gmail.com Mon Mar 12 11:55:13 2007 From: zhousheng00 at gmail.com (Zhou Sheng) Date: Mon, 12 Mar 2007 11:55:13 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200703121655.l2CGtDCv022175@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.653 -> 1.654 --- Log message: Avoid to assert on "(KnownZero & KnownOne) == 0". --- Diffs of the changes: (+1 -1) InstructionCombining.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.653 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.654 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.653 Mon Mar 12 00:44:52 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 12 11:54:56 2007 @@ -979,7 +979,7 @@ /// this predicate to simplify operations downstream. Mask is known to be zero /// for bits that V cannot have. static bool MaskedValueIsZero(Value *V, const APInt& Mask, unsigned Depth = 0) { - APInt KnownZero(Mask), KnownOne(Mask); + APInt KnownZero(Mask.getBitWidth(), 0), KnownOne(Mask.getBitWidth(), 0); ComputeMaskedBits(V, Mask, KnownZero, KnownOne, Depth); assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); return (KnownZero & Mask) == Mask; From reid at x10sys.com Mon Mar 12 12:15:27 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 12 Mar 2007 12:15:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200703121715.l2CHFRSI022625@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.654 -> 1.655 --- Log message: Add an APInt version of ShrinkDemandedConstant. Patch by Zhou Sheng. --- Diffs of the changes: (+24 -0) InstructionCombining.cpp | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.654 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.655 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.654 Mon Mar 12 11:54:56 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 12 12:15:10 2007 @@ -1004,6 +1004,30 @@ return true; } +/// ShrinkDemandedConstant - Check to see if the specified operand of the +/// specified instruction is a constant integer. If so, check to see if there +/// are any bits set in the constant that are not demanded. If so, shrink the +/// constant and return true. +static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo, + APInt Demanded) { + assert(I && "No instruction?"); + assert(OpNo < I->getNumOperands() && "Operand index too large"); + + // If the operand is not a constant integer, nothing to do. + ConstantInt *OpC = dyn_cast(I->getOperand(OpNo)); + if (!OpC) return false; + + // If there are no bits set that aren't demanded, nothing to do. + Demanded.zextOrTrunc(OpC->getValue().getBitWidth()); + if ((~Demanded & OpC->getValue()) == 0) + return false; + + // This instruction is producing bits that are not demanded. Shrink the RHS. + Demanded &= OpC->getValue(); + I->setOperand(OpNo, ConstantInt::get(Demanded)); + return true; +} + // ComputeSignedMinMaxValuesFromKnownBits - Given a signed integer type and a // set of known zero and one bits, compute the maximum and minimum values that // could have the specified known zero and known one bits, returning them in From reid at x10sys.com Mon Mar 12 12:26:19 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 12 Mar 2007 12:26:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200703121726.l2CHQJXI022870@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.655 -> 1.656 --- Log message: Add an APInt version of SimplifyDemandedBits. Patch by Zhou Sheng. --- Diffs of the changes: (+524 -1) InstructionCombining.cpp | 525 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 524 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.655 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.656 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.655 Mon Mar 12 12:15:10 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 12 12:25:59 2007 @@ -319,10 +319,14 @@ /// most-complex to least-complex order. bool SimplifyCompare(CmpInst &I); - bool SimplifyDemandedBits(Value *V, uint64_t Mask, + bool SimplifyDemandedBits(Value *V, uint64_t DemandedMask, uint64_t &KnownZero, uint64_t &KnownOne, unsigned Depth = 0); + bool SimplifyDemandedBits(Value *V, APInt DemandedMask, + APInt& KnownZero, APInt& KnownOne, + unsigned Depth = 0); + Value *SimplifyDemandedVectorElts(Value *V, uint64_t DemandedElts, uint64_t &UndefElts, unsigned Depth = 0); @@ -1545,6 +1549,525 @@ return false; } +/// SimplifyDemandedBits - This function attempts to replace V with a simpler +/// value based on the demanded bits. When this function is called, it is known +/// that only the bits set in DemandedMask of the result of V are ever used +/// downstream. Consequently, depending on the mask and V, it may be possible +/// to replace V with a constant or one of its operands. In such cases, this +/// function does the replacement and returns true. In all other cases, it +/// returns false after analyzing the expression and setting KnownOne and known +/// to be one in the expression. KnownZero contains all the bits that are known +/// to be zero in the expression. These are provided to potentially allow the +/// caller (which might recursively be SimplifyDemandedBits itself) to simplify +/// the expression. KnownOne and KnownZero always follow the invariant that +/// KnownOne & KnownZero == 0. That is, a bit can't be both 1 and 0. Note that +/// the bits in KnownOne and KnownZero may only be accurate for those bits set +/// in DemandedMask. Note also that the bitwidth of V, DemandedMask, KnownZero +/// and KnownOne must all be the same. +bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, + APInt& KnownZero, APInt& KnownOne, + unsigned Depth) { + assert(V != 0 && "Null pointer of Value???"); + assert(Depth <= 6 && "Limit Search Depth"); + uint32_t BitWidth = DemandedMask.getBitWidth(); + const IntegerType *VTy = cast(V->getType()); + assert(VTy->getBitWidth() == BitWidth && + KnownZero.getBitWidth() == BitWidth && + KnownOne.getBitWidth() == BitWidth && + "Value *V, DemandedMask, KnownZero and KnownOne \ + must have same BitWidth"); + if (ConstantInt *CI = dyn_cast(V)) { + // We know all of the bits for a constant! + KnownOne = CI->getValue() & DemandedMask; + KnownZero = ~KnownOne & DemandedMask; + return false; + } + + //KnownZero.clear(); + //KnownOne.clear(); + if (!V->hasOneUse()) { // Other users may use these bits. + if (Depth != 0) { // Not at the root. + // Just compute the KnownZero/KnownOne bits to simplify things downstream. + ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth); + return false; + } + // If this is the root being simplified, allow it to have multiple uses, + // just set the DemandedMask to all bits. + DemandedMask = APInt::getAllOnesValue(BitWidth); + } else if (DemandedMask == 0) { // Not demanding any bits from V. + if (V != UndefValue::get(VTy)) + return UpdateValueUsesWith(V, UndefValue::get(VTy)); + return false; + } else if (Depth == 6) { // Limit search depth. + return false; + } + + Instruction *I = dyn_cast(V); + if (!I) return false; // Only analyze instructions. + + DemandedMask &= APInt::getAllOnesValue(BitWidth); + + APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); + APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne; + switch (I->getOpcode()) { + default: break; + case Instruction::And: + // If either the LHS or the RHS are Zero, the result is zero. + if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + + // If something is known zero on the RHS, the bits aren't demanded on the + // LHS. + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~RHSKnownZero, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + assert((LHSKnownZero & LHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + + // If all of the demanded bits are known 1 on one side, return the other. + // These bits cannot contribute to the result of the 'and'. + if ((DemandedMask & ~LHSKnownZero & RHSKnownOne) == + (DemandedMask & ~LHSKnownZero)) + return UpdateValueUsesWith(I, I->getOperand(0)); + if ((DemandedMask & ~RHSKnownZero & LHSKnownOne) == + (DemandedMask & ~RHSKnownZero)) + return UpdateValueUsesWith(I, I->getOperand(1)); + + // If all of the demanded bits in the inputs are known zeros, return zero. + if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask) + return UpdateValueUsesWith(I, Constant::getNullValue(VTy)); + + // If the RHS is a constant, see if we can simplify it. + if (ShrinkDemandedConstant(I, 1, DemandedMask & ~LHSKnownZero)) + return UpdateValueUsesWith(I, I); + + // Output known-1 bits are only known if set in both the LHS & RHS. + RHSKnownOne &= LHSKnownOne; + // Output known-0 are known to be clear if zero in either the LHS | RHS. + RHSKnownZero |= LHSKnownZero; + break; + case Instruction::Or: + // If either the LHS or the RHS are One, the result is One. + if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + // If something is known one on the RHS, the bits aren't demanded on the + // LHS. + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~RHSKnownOne, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + assert((LHSKnownZero & LHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + + // If all of the demanded bits are known zero on one side, return the other. + // These bits cannot contribute to the result of the 'or'. + if ((DemandedMask & ~LHSKnownOne & RHSKnownZero) == + (DemandedMask & ~LHSKnownOne)) + return UpdateValueUsesWith(I, I->getOperand(0)); + if ((DemandedMask & ~RHSKnownOne & LHSKnownZero) == + (DemandedMask & ~RHSKnownOne)) + return UpdateValueUsesWith(I, I->getOperand(1)); + + // If all of the potentially set bits on one side are known to be set on + // the other side, just use the 'other' side. + if ((DemandedMask & (~RHSKnownZero) & LHSKnownOne) == + (DemandedMask & (~RHSKnownZero))) + return UpdateValueUsesWith(I, I->getOperand(0)); + if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) == + (DemandedMask & (~LHSKnownZero))) + return UpdateValueUsesWith(I, I->getOperand(1)); + + // If the RHS is a constant, see if we can simplify it. + if (ShrinkDemandedConstant(I, 1, DemandedMask)) + return UpdateValueUsesWith(I, I); + + // Output known-0 bits are only known if clear in both the LHS & RHS. + RHSKnownZero &= LHSKnownZero; + // Output known-1 are known to be set if set in either the LHS | RHS. + RHSKnownOne |= LHSKnownOne; + break; + case Instruction::Xor: { + if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + assert((LHSKnownZero & LHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + + // If all of the demanded bits are known zero on one side, return the other. + // These bits cannot contribute to the result of the 'xor'. + if ((DemandedMask & RHSKnownZero) == DemandedMask) + return UpdateValueUsesWith(I, I->getOperand(0)); + if ((DemandedMask & LHSKnownZero) == DemandedMask) + return UpdateValueUsesWith(I, I->getOperand(1)); + + // Output known-0 bits are known if clear or set in both the LHS & RHS. + APInt KnownZeroOut = (RHSKnownZero & LHSKnownZero) | + (RHSKnownOne & LHSKnownOne); + // Output known-1 are known to be set if set in only one of the LHS, RHS. + APInt KnownOneOut = (RHSKnownZero & LHSKnownOne) | + (RHSKnownOne & LHSKnownZero); + + // If all of the demanded bits are known to be zero on one side or the + // other, turn this into an *inclusive* or. + // e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 + if ((DemandedMask & ~RHSKnownZero & ~LHSKnownZero) == 0) { + Instruction *Or = + BinaryOperator::createOr(I->getOperand(0), I->getOperand(1), + I->getName()); + InsertNewInstBefore(Or, *I); + return UpdateValueUsesWith(I, Or); + } + + // If all of the demanded bits on one side are known, and all of the set + // bits on that side are also known to be set on the other side, turn this + // into an AND, as we know the bits will be cleared. + // e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2 + if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask) { + // all known + if ((RHSKnownOne & LHSKnownOne) == RHSKnownOne) { + Constant *AndC = ConstantInt::get(~RHSKnownOne & DemandedMask); + Instruction *And = + BinaryOperator::createAnd(I->getOperand(0), AndC, "tmp"); + InsertNewInstBefore(And, *I); + return UpdateValueUsesWith(I, And); + } + } + + // If the RHS is a constant, see if we can simplify it. + // FIXME: for XOR, we prefer to force bits to 1 if they will make a -1. + if (ShrinkDemandedConstant(I, 1, DemandedMask)) + return UpdateValueUsesWith(I, I); + + RHSKnownZero = KnownZeroOut; + RHSKnownOne = KnownOneOut; + break; + } + case Instruction::Select: + if (SimplifyDemandedBits(I->getOperand(2), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; + if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + assert((LHSKnownZero & LHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + + // If the operands are constants, see if we can simplify them. + if (ShrinkDemandedConstant(I, 1, DemandedMask)) + return UpdateValueUsesWith(I, I); + if (ShrinkDemandedConstant(I, 2, DemandedMask)) + return UpdateValueUsesWith(I, I); + + // Only known if known in both the LHS and RHS. + RHSKnownOne &= LHSKnownOne; + RHSKnownZero &= LHSKnownZero; + break; + case Instruction::Trunc: { + uint32_t truncBf = + cast(I->getOperand(0)->getType())->getBitWidth(); + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.zext(truncBf), + RHSKnownZero.zext(truncBf), RHSKnownOne.zext(truncBf), Depth+1)) + return true; + DemandedMask.trunc(BitWidth); + RHSKnownZero.trunc(BitWidth); + RHSKnownOne.trunc(BitWidth); + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + break; + } + case Instruction::BitCast: + if (!I->getOperand(0)->getType()->isInteger()) + return false; + + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + break; + case Instruction::ZExt: { + // Compute the bits in the result that are not present in the input. + const IntegerType *SrcTy = cast(I->getOperand(0)->getType()); + APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy->getBitWidth())); + + DemandedMask &= SrcTy->getMask().zext(BitWidth); + uint32_t zextBf = SrcTy->getBitWidth(); + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.trunc(zextBf), + RHSKnownZero.trunc(zextBf), RHSKnownOne.trunc(zextBf), Depth+1)) + return true; + DemandedMask.zext(BitWidth); + RHSKnownZero.zext(BitWidth); + RHSKnownOne.zext(BitWidth); + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + // The top bits are known to be zero. + RHSKnownZero |= NewBits; + break; + } + case Instruction::SExt: { + // Compute the bits in the result that are not present in the input. + const IntegerType *SrcTy = cast(I->getOperand(0)->getType()); + APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy->getBitWidth())); + + // Get the sign bit for the source type + APInt InSignBit(APInt::getSignBit(SrcTy->getPrimitiveSizeInBits())); + InSignBit.zext(BitWidth); + APInt InputDemandedBits = DemandedMask & + SrcTy->getMask().zext(BitWidth); + + // If any of the sign extended bits are demanded, we know that the sign + // bit is demanded. + if ((NewBits & DemandedMask) != 0) + InputDemandedBits |= InSignBit; + + uint32_t sextBf = SrcTy->getBitWidth(); + if (SimplifyDemandedBits(I->getOperand(0), InputDemandedBits.trunc(sextBf), + RHSKnownZero.trunc(sextBf), RHSKnownOne.trunc(sextBf), Depth+1)) + return true; + InputDemandedBits.zext(BitWidth); + RHSKnownZero.zext(BitWidth); + RHSKnownOne.zext(BitWidth); + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + + // If the sign bit of the input is known set or clear, then we know the + // top bits of the result. + + // If the input sign bit is known zero, or if the NewBits are not demanded + // convert this into a zero extension. + if ((RHSKnownZero & InSignBit) != 0 || (NewBits & ~DemandedMask) == NewBits) + { + // Convert to ZExt cast + CastInst *NewCast = new ZExtInst(I->getOperand(0), VTy, I->getName(), I); + return UpdateValueUsesWith(I, NewCast); + } else if ((RHSKnownOne & InSignBit) != 0) { // Input sign bit known set + RHSKnownOne |= NewBits; + RHSKnownZero &= ~NewBits; + } else { // Input sign bit unknown + RHSKnownZero &= ~NewBits; + RHSKnownOne &= ~NewBits; + } + break; + } + case Instruction::Add: { + // Figure out what the input bits are. If the top bits of the and result + // are not demanded, then the add doesn't demand them from its input + // either. + unsigned NLZ = DemandedMask.countLeadingZeros(); + + // If there is a constant on the RHS, there are a variety of xformations + // we can do. + if (ConstantInt *RHS = dyn_cast(I->getOperand(1))) { + // If null, this should be simplified elsewhere. Some of the xforms here + // won't work if the RHS is zero. + if (RHS->isZero()) + break; + + // If the top bit of the output is demanded, demand everything from the + // input. Otherwise, we demand all the input bits except NLZ top bits. + APInt InDemandedBits(APInt::getAllOnesValue(BitWidth).lshr(NLZ)); + + // Find information about known zero/one bits in the input. + if (SimplifyDemandedBits(I->getOperand(0), InDemandedBits, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + + // If the RHS of the add has bits set that can't affect the input, reduce + // the constant. + if (ShrinkDemandedConstant(I, 1, InDemandedBits)) + return UpdateValueUsesWith(I, I); + + // Avoid excess work. + if (LHSKnownZero == 0 && LHSKnownOne == 0) + break; + + // Turn it into OR if input bits are zero. + if ((LHSKnownZero & RHS->getValue()) == RHS->getValue()) { + Instruction *Or = + BinaryOperator::createOr(I->getOperand(0), I->getOperand(1), + I->getName()); + InsertNewInstBefore(Or, *I); + return UpdateValueUsesWith(I, Or); + } + + // We can say something about the output known-zero and known-one bits, + // depending on potential carries from the input constant and the + // unknowns. For example if the LHS is known to have at most the 0x0F0F0 + // bits set and the RHS constant is 0x01001, then we know we have a known + // one mask of 0x00001 and a known zero mask of 0xE0F0E. + + // To compute this, we first compute the potential carry bits. These are + // the bits which may be modified. I'm not aware of a better way to do + // this scan. + APInt RHSVal(RHS->getValue()); + + bool CarryIn = false; + APInt CarryBits(BitWidth, 0); + const uint64_t *LHSKnownZeroRawVal = LHSKnownZero.getRawData(), + *RHSRawVal = RHSVal.getRawData(); + for (uint32_t i = 0; i != RHSVal.getNumWords(); ++i) { + uint64_t AddVal = ~LHSKnownZeroRawVal[i] + RHSRawVal[i], + XorVal = ~LHSKnownZeroRawVal[i] ^ RHSRawVal[i]; + uint64_t WordCarryBits = AddVal ^ XorVal + CarryIn; + if (AddVal < RHSRawVal[i]) + CarryIn = true; + else + CarryIn = false; + CarryBits.setWordToValue(i, WordCarryBits); + } + + // Now that we know which bits have carries, compute the known-1/0 sets. + + // Bits are known one if they are known zero in one operand and one in the + // other, and there is no input carry. + RHSKnownOne = ((LHSKnownZero & RHSVal) | + (LHSKnownOne & ~RHSVal)) & ~CarryBits; + + // Bits are known zero if they are known zero in both operands and there + // is no input carry. + RHSKnownZero = LHSKnownZero & ~RHSVal & ~CarryBits; + } else { + // If the high-bits of this ADD are not demanded, then it does not demand + // the high bits of its LHS or RHS. + if ((DemandedMask & APInt::getSignBit(BitWidth)) == 0) { + // Right fill the mask of bits for this ADD to demand the most + // significant bit and all those below it. + APInt DemandedFromOps = APInt::getAllOnesValue(BitWidth).lshr(NLZ); + if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + if (SimplifyDemandedBits(I->getOperand(1), DemandedFromOps, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + } + } + break; + } + case Instruction::Sub: + // If the high-bits of this SUB are not demanded, then it does not demand + // the high bits of its LHS or RHS. + if ((DemandedMask & APInt::getSignBit(BitWidth)) == 0) { + // Right fill the mask of bits for this SUB to demand the most + // significant bit and all those below it. + unsigned NLZ = DemandedMask.countLeadingZeros(); + APInt DemandedFromOps(APInt::getAllOnesValue(BitWidth).lshr(NLZ)); + if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + if (SimplifyDemandedBits(I->getOperand(1), DemandedFromOps, + LHSKnownZero, LHSKnownOne, Depth+1)) + return true; + } + break; + case Instruction::Shl: + if (ConstantInt *SA = dyn_cast(I->getOperand(1))) { + uint64_t ShiftAmt = SA->getZExtValue(); + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask.lshr(ShiftAmt), + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + RHSKnownZero <<= ShiftAmt; + RHSKnownOne <<= ShiftAmt; + // low bits known zero. + RHSKnownZero |= APInt::getAllOnesValue(ShiftAmt).zext(BitWidth); + } + break; + case Instruction::LShr: + // For a logical shift right + if (ConstantInt *SA = dyn_cast(I->getOperand(1))) { + unsigned ShiftAmt = SA->getZExtValue(); + + APInt TypeMask(APInt::getAllOnesValue(BitWidth)); + // Unsigned shift right. + if (SimplifyDemandedBits(I->getOperand(0), + (DemandedMask.shl(ShiftAmt)) & TypeMask, + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + // Compute the new bits that are at the top now. + APInt HighBits(APInt::getAllOnesValue(ShiftAmt).zext(BitWidth).shl( + BitWidth - ShiftAmt)); + RHSKnownZero &= TypeMask; + RHSKnownOne &= TypeMask; + RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt); + RHSKnownOne = APIntOps::lshr(RHSKnownOne, ShiftAmt); + RHSKnownZero |= HighBits; // high bits known zero. + } + break; + case Instruction::AShr: + // If this is an arithmetic shift right and only the low-bit is set, we can + // always convert this into a logical shr, even if the shift amount is + // variable. The low bit of the shift cannot be an input sign bit unless + // the shift amount is >= the size of the datatype, which is undefined. + if (DemandedMask == 1) { + // Perform the logical shift right. + Value *NewVal = BinaryOperator::createLShr( + I->getOperand(0), I->getOperand(1), I->getName()); + InsertNewInstBefore(cast(NewVal), *I); + return UpdateValueUsesWith(I, NewVal); + } + + if (ConstantInt *SA = dyn_cast(I->getOperand(1))) { + unsigned ShiftAmt = SA->getZExtValue(); + + APInt TypeMask(APInt::getAllOnesValue(BitWidth)); + // Signed shift right. + if (SimplifyDemandedBits(I->getOperand(0), + (DemandedMask.shl(ShiftAmt)) & TypeMask, + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; + assert((RHSKnownZero & RHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + // Compute the new bits that are at the top now. + APInt HighBits(APInt::getAllOnesValue(ShiftAmt).zext(BitWidth).shl( + BitWidth - ShiftAmt)); + RHSKnownZero &= TypeMask; + RHSKnownOne &= TypeMask; + RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt); + RHSKnownOne = APIntOps::lshr(RHSKnownOne, ShiftAmt); + + // Handle the sign bits. + APInt SignBit(APInt::getSignBit(BitWidth)); + // Adjust to where it is now in the mask. + SignBit = APIntOps::lshr(SignBit, ShiftAmt); + + // If the input sign bit is known to be zero, or if none of the top bits + // are demanded, turn this into an unsigned shift right. + if ((RHSKnownZero & SignBit) != 0 || + (HighBits & ~DemandedMask) == HighBits) { + // Perform the logical shift right. + Value *NewVal = BinaryOperator::createLShr( + I->getOperand(0), SA, I->getName()); + InsertNewInstBefore(cast(NewVal), *I); + return UpdateValueUsesWith(I, NewVal); + } else if ((RHSKnownOne & SignBit) != 0) { // New bits are known one. + RHSKnownOne |= HighBits; + } + } + break; + } + + // If the client is only demanding bits that we know, return the known + // constant. + if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask) + return UpdateValueUsesWith(I, ConstantInt::get(RHSKnownOne)); + return false; +} + /// SimplifyDemandedVectorElts - The specified value producecs a vector with /// 64 or fewer elements. DemandedElts contains the set of elements that are From zhousheng00 at gmail.com Mon Mar 12 12:48:02 2007 From: zhousheng00 at gmail.com (Zhou Sheng) Date: Mon, 12 Mar 2007 12:48:02 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/APInt.cpp Message-ID: <200703121748.l2CHm2IR023224@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: APInt.cpp updated: 1.69 -> 1.70 --- Log message: For APInt::z/sext(width), if width == BitWidth, just return *this. --- Diffs of the changes: (+4 -0) APInt.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Support/APInt.cpp diff -u llvm/lib/Support/APInt.cpp:1.69 llvm/lib/Support/APInt.cpp:1.70 --- llvm/lib/Support/APInt.cpp:1.69 Sun Mar 4 18:00:42 2007 +++ llvm/lib/Support/APInt.cpp Mon Mar 12 12:47:45 2007 @@ -921,6 +921,8 @@ // Sign extend to a new width. APInt &APInt::sext(uint32_t width) { + if (width == BitWidth) + return *this; assert(width > BitWidth && "Invalid APInt SignExtend request"); assert(width <= IntegerType::MAX_INT_BITS && "Too many bits"); // If the sign bit isn't set, this is the same as zext. @@ -969,6 +971,8 @@ // Zero extend to a new width. APInt &APInt::zext(uint32_t width) { + if (width == BitWidth) + return *this; assert(width > BitWidth && "Invalid APInt ZeroExtend request"); assert(width <= IntegerType::MAX_INT_BITS && "Too many bits"); uint32_t wordsBefore = getNumWords(); From reid at x10sys.com Mon Mar 12 13:37:42 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 12 Mar 2007 13:37:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/APInt.cpp Message-ID: <200703121837.l2CIbgsm024275@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: APInt.cpp updated: 1.70 -> 1.71 --- Log message: Revert the last patch as it violates the conditions of sext/zext. --- Diffs of the changes: (+0 -4) APInt.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/Support/APInt.cpp diff -u llvm/lib/Support/APInt.cpp:1.70 llvm/lib/Support/APInt.cpp:1.71 --- llvm/lib/Support/APInt.cpp:1.70 Mon Mar 12 12:47:45 2007 +++ llvm/lib/Support/APInt.cpp Mon Mar 12 13:37:25 2007 @@ -921,8 +921,6 @@ // Sign extend to a new width. APInt &APInt::sext(uint32_t width) { - if (width == BitWidth) - return *this; assert(width > BitWidth && "Invalid APInt SignExtend request"); assert(width <= IntegerType::MAX_INT_BITS && "Too many bits"); // If the sign bit isn't set, this is the same as zext. @@ -971,8 +969,6 @@ // Zero extend to a new width. APInt &APInt::zext(uint32_t width) { - if (width == BitWidth) - return *this; assert(width > BitWidth && "Invalid APInt ZeroExtend request"); assert(width <= IntegerType::MAX_INT_BITS && "Too many bits"); uint32_t wordsBefore = getNumWords(); From rspencer at reidspencer.com Mon Mar 12 13:38:25 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Mon, 12 Mar 2007 11:38:25 -0700 Subject: [llvm-commits] CVS: llvm/lib/Support/APInt.cpp In-Reply-To: <200703121748.l2CHm2IR023224@zion.cs.uiuc.edu> References: <200703121748.l2CHm2IR023224@zion.cs.uiuc.edu> Message-ID: <1173724705.13912.29.camel@bashful.x10sys.com> On Mon, 2007-03-12 at 12:48 -0500, Zhou Sheng wrote: > > Changes in directory llvm/lib/Support: > > APInt.cpp updated: 1.69 -> 1.70 > --- > Log message: > > For APInt::z/sext(width), if width == BitWidth, just return *this. Sheng, this is incorrect. It is not legal to use sext/zext with a bit width that is equal to the bit width of the APInt. Please see the definition of sext/zext in the language reference. APInt must implement the same operations (and restrictions on them) as the instructions do. In the future, please consult with me before making this kind of change. I have reverted this patch. Reid. > > > --- > Diffs of the changes: (+4 -0) > > APInt.cpp | 4 ++++ > 1 files changed, 4 insertions(+) > > > Index: llvm/lib/Support/APInt.cpp > diff -u llvm/lib/Support/APInt.cpp:1.69 llvm/lib/Support/APInt.cpp:1.70 > --- llvm/lib/Support/APInt.cpp:1.69 Sun Mar 4 18:00:42 2007 > +++ llvm/lib/Support/APInt.cpp Mon Mar 12 12:47:45 2007 > @@ -921,6 +921,8 @@ > > // Sign extend to a new width. > APInt &APInt::sext(uint32_t width) { > + if (width == BitWidth) > + return *this; > assert(width > BitWidth && "Invalid APInt SignExtend request"); > assert(width <= IntegerType::MAX_INT_BITS && "Too many bits"); > // If the sign bit isn't set, this is the same as zext. > @@ -969,6 +971,8 @@ > > // Zero extend to a new width. > APInt &APInt::zext(uint32_t width) { > + if (width == BitWidth) > + return *this; > assert(width > BitWidth && "Invalid APInt ZeroExtend request"); > assert(width <= IntegerType::MAX_INT_BITS && "Too many bits"); > uint32_t wordsBefore = getNumWords(); > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From alenhar2 at cs.uiuc.edu Mon Mar 12 14:51:06 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 12 Mar 2007 14:51:06 -0500 Subject: [llvm-commits] [see] CVS: llvm-poolalloc/lib/DSA/Local.cpp Message-ID: <200703121951.l2CJp6qN002256@apoc.cs.uiuc.edu> Changes in directory llvm-poolalloc/lib/DSA: Local.cpp updated: 1.158.2.4.2.5 -> 1.158.2.4.2.6 --- Log message: add these --- Diffs of the changes: (+2 -0) Local.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm-poolalloc/lib/DSA/Local.cpp diff -u llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.5 llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.6 --- llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.5 Mon Mar 12 11:41:06 2007 +++ llvm-poolalloc/lib/DSA/Local.cpp Mon Mar 12 14:50:27 2007 @@ -1408,6 +1408,8 @@ AllocList.push_back("kmalloc"); AllocList.push_back("__vmalloc"); AllocList.push_back("kmem_cache_alloc"); + FreeList.push_back("kfree"); + FreeList.push_back("vfree"); #endif const TargetData &TD = getAnalysis(); From baldrick at free.fr Mon Mar 12 15:48:38 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 12 Mar 2007 21:48:38 +0100 Subject: [llvm-commits] llvm-gcc: emit switch cases with a wide range as a conditional branch Message-ID: <200703122148.39018.baldrick@free.fr> In gcc, a switch case is a range of values that branch to a label, for example 1 .. 17 -> label. These are emitted as individual LLVM switch cases: 1 -> label, 2 -> label, ..., 17 -> label. This works well except, for example, when the range is INT_MIN .. 0 -> label, in which case you can say goodbye to all your memory! This patch causes ranges with more than 64 elements (128 on 64 bit machines) to be emitted as explicit "if" statements. For example, the following gcc switch (from the Ada testcase) INT_MIN .. -1 -> block_neg 0 -> block_zero default -> block_default is emitted as switch i32 %n, label %0 [ i32 0, label %block_zero ] ;