The attached patch unify the handle of shifts when the shift amount is greater or equal the bit width.
Nowadays, LLVM evaluates shl(i32 X,32) to 0 in some places and to undef in other places. For compatibility purpose, this patch implements the gcc behavior. This fix the miscompilation of the file ffmpeg/libavformat/mpeg.c. Proposed behavior: === shl(X,N) ===== if (N<bitwidth(X)) result = X << N if (N>=bitwidth(X)) result = 0; === Lshr(X,N) ===== if (N<bitwidth(X)) result = X >> N if (N>=bitwidth(X)) result = 0; === Ashr(X,N) ===== if (N<bitwidth(X)) result = X >> N if (N>=bitwidth(X) && X<0) result = -1; if (N>=bitwidth(X) && X>=0) result = 0; Lauro
? NightlyTestAccept.php ? NightlyTestAccept.php.1 ? NightlyTestAccept.php.2 ? build ? patch ? docs/patch ? lib/Target/ARM/patch ? projects/llvm-test/antigos.fail ? projects/llvm-test/novo.fail ? projects/llvm-test/patch ? projects/llvm-test/resultados.antigo ? projects/llvm-test/resultados.novo ? projects/llvm-test/MultiSource/Applications/SIBsim4/Output ? projects/llvm-test/MultiSource/Applications/minisat/Output ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/.dir ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gdevmem.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gdevs.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gp_unix.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.cbe ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.cbe.c ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.diff-cbe ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.diff-jit ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.diff-llc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.linked.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.linked.rbc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.llc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.llc.s ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.llvm ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.llvm.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.native ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.out-cbe ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.out-cbe.time ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.out-jit ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.out-jit.time ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.out-llc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.out-llc.time ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.out-nat ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gs.out-nat.time ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gschar.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gscolor.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gscoord.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsdevice.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsfile.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsfont.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsim2out.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsimage.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsline.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsmain.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsmatrix.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsmisc.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gspaint.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gspath.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gspath2.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gsstate.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gstype1.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxcache.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxcolor.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxdither.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxdraw.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxfill.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxht.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxpath.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxpath2.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/gxstroke.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/ialloc.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/idebug.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/idict.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/iinit.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/iname.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/interp.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/iscan.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/iutil.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/stream.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/utrace.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zarith.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zarray.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zchar.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zcolor.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zcontrol.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zdevice.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zdict.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zfile.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zfont.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zgeneric.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zgstate.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zht.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zmath.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zmatrix.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zmisc.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zpacked.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zpaint.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zpath.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zpath2.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zrelbit.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zstack.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zstring.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/ztype.bc ? projects/llvm-test/MultiSource/Benchmarks/MallocBench/gs/Output/zvmem.bc ? projects/llvm-test/MultiSource/Benchmarks/MiBench/automotive-basicmath/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/automotive-bitcount/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/automotive-susan/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/consumer-jpeg/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/consumer-lame/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/consumer-typeset/large.lout.ldx ? projects/llvm-test/MultiSource/Benchmarks/MiBench/consumer-typeset/lout.li ? projects/llvm-test/MultiSource/Benchmarks/MiBench/consumer-typeset/lout.lix ? projects/llvm-test/MultiSource/Benchmarks/MiBench/network-dijkstra/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/network-patricia/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/office-ispell/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/office-stringsearch/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/security-blowfish/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/security-rijndael/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/security-sha/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/telecomm-CRC32/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/telecomm-FFT/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/telecomm-adpcm/Output ? projects/llvm-test/MultiSource/Benchmarks/MiBench/telecomm-gsm/Output ? projects/llvm-test/MultiSource/Benchmarks/tramp3d-v4/Output ? projects/llvm-test/SingleSource/Benchmarks/McGill/patch ? projects/llvm-test/SingleSource/UnitTests/Threads/Output ? test/CodeGen/ARM/a.out ? tools/bugpoint/patch ? utils/patch Index: lib/Support/APInt.cpp =================================================================== RCS file: /var/cvs/llvm/llvm/lib/Support/APInt.cpp,v retrieving revision 1.86 diff -u -r1.86 APInt.cpp --- lib/Support/APInt.cpp 19 May 2007 00:29:55 -0000 1.86 +++ lib/Support/APInt.cpp 12 Jun 2007 19:54:17 -0000 @@ -1053,32 +1053,27 @@ /// Arithmetic right-shift this APInt by shiftAmt. /// @brief Arithmetic right-shift function. APInt APInt::ashr(uint32_t shiftAmt) const { - assert(shiftAmt <= BitWidth && "Invalid shift amount"); // Handle a degenerate case if (shiftAmt == 0) return *this; - // Handle single word shifts with built-in ashr - if (isSingleWord()) { - if (shiftAmt == BitWidth) - return APInt(BitWidth, 0); // undefined - else { - uint32_t SignBit = APINT_BITS_PER_WORD - BitWidth; - return APInt(BitWidth, - (((int64_t(VAL) << SignBit) >> SignBit) >> shiftAmt)); - } - } - // If all the bits were shifted out, the result is, technically, undefined. // We return -1 if it was negative, 0 otherwise. We check this early to avoid // issues in the algorithm below. - if (shiftAmt == BitWidth) { + if (shiftAmt >= BitWidth) { if (isNegative()) return APInt(BitWidth, -1ULL); else return APInt(BitWidth, 0); } + // Handle single word shifts with built-in ashr + if (isSingleWord()) { + uint32_t SignBit = APINT_BITS_PER_WORD - BitWidth; + return APInt(BitWidth, + (((int64_t(VAL) << SignBit) >> SignBit) >> shiftAmt)); + } + // Create some space for the result. uint64_t * val = new uint64_t[getNumWords()]; @@ -1136,24 +1131,20 @@ /// Logical right-shift this APInt by shiftAmt. /// @brief Logical right-shift function. APInt APInt::lshr(uint32_t shiftAmt) const { - if (isSingleWord()) { - if (shiftAmt == BitWidth) - return APInt(BitWidth, 0); - else - return APInt(BitWidth, this->VAL >> shiftAmt); - } + // If none of the bits are shifted out, the result is *this. This avoids + // issues with shifting byt he size of the integer type, which produces + // undefined results in the code below. This is also an optimization. + if (shiftAmt == 0) + return *this; // If all the bits were shifted out, the result is 0. This avoids issues // with shifting by the size of the integer type, which produces undefined // results. We define these "undefined results" to always be 0. - if (shiftAmt == BitWidth) + if (shiftAmt >= BitWidth) return APInt(BitWidth, 0); - // If none of the bits are shifted out, the result is *this. This avoids - // issues with shifting byt he size of the integer type, which produces - // undefined results in the code below. This is also an optimization. - if (shiftAmt == 0) - return *this; + if (isSingleWord()) + return APInt(BitWidth, this->VAL >> shiftAmt); // Create some space for the result. uint64_t * val = new uint64_t[getNumWords()]; @@ -1198,24 +1189,20 @@ /// Left-shift this APInt by shiftAmt. /// @brief Left-shift function. APInt APInt::shl(uint32_t shiftAmt) const { - assert(shiftAmt <= BitWidth && "Invalid shift amount"); - if (isSingleWord()) { - if (shiftAmt == BitWidth) - return APInt(BitWidth, 0); // avoid undefined shift results - return APInt(BitWidth, VAL << shiftAmt); - } + // If none of the bits are shifted out, the result is *this. This avoids a + // lshr by the words size in the loop below which can produce incorrect + // results. It also avoids the expensive computation below for a common case. + if (shiftAmt == 0) + return *this; // If all the bits were shifted out, the result is 0. This avoids issues // with shifting by the size of the integer type, which produces undefined // results. We define these "undefined results" to always be 0. - if (shiftAmt == BitWidth) + if (shiftAmt >= BitWidth) return APInt(BitWidth, 0); - // If none of the bits are shifted out, the result is *this. This avoids a - // lshr by the words size in the loop below which can produce incorrect - // results. It also avoids the expensive computation below for a common case. - if (shiftAmt == 0) - return *this; + if (isSingleWord()) + return APInt(BitWidth, VAL << shiftAmt); // Create some space for the result. uint64_t * val = new uint64_t[getNumWords()]; Index: lib/VMCore/ConstantFold.cpp =================================================================== RCS file: /var/cvs/llvm/llvm/lib/VMCore/ConstantFold.cpp,v retrieving revision 1.150 diff -u -r1.150 ConstantFold.cpp --- lib/VMCore/ConstantFold.cpp 26 Mar 2007 20:09:02 -0000 1.150 +++ lib/VMCore/ConstantFold.cpp 12 Jun 2007 19:54:18 -0000 @@ -631,26 +631,12 @@ case Instruction::Xor: return ConstantInt::get(C1V ^ C2V); case Instruction::Shl: - if (uint32_t shiftAmt = C2V.getZExtValue()) - if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.shl(shiftAmt)); - else - return UndefValue::get(C1->getType()); // too big shift is undef - return const_cast<ConstantInt*>(CI1); // Zero shift is identity + return ConstantInt::get(C1V.shl(C2V.getZExtValue())); case Instruction::LShr: - if (uint32_t shiftAmt = C2V.getZExtValue()) - if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.lshr(shiftAmt)); - else - return UndefValue::get(C1->getType()); // too big shift is undef - return const_cast<ConstantInt*>(CI1); // Zero shift is identity + return ConstantInt::get(C1V.lshr(C2V.getZExtValue())); case Instruction::AShr: - if (uint32_t shiftAmt = C2V.getZExtValue()) - if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.ashr(shiftAmt)); - else - return UndefValue::get(C1->getType()); // too big shift is undef - return const_cast<ConstantInt*>(CI1); // Zero shift is identity + return ConstantInt::get(C1V.ashr(C2V.getZExtValue())); + } } } else if (const ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) {
_______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits