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

Reply via email to