Fixes a problem in instruction selection with testing whether or not the
authorJoel Jones <joel_k_jones@apple.com>
Tue, 17 Apr 2012 22:23:10 +0000 (22:23 +0000)
committerJoel Jones <joel_k_jones@apple.com>
Tue, 17 Apr 2012 22:23:10 +0000 (22:23 +0000)
transformation:

(X op C1) ^ C2 --> (X op C1) & ~C2 iff (C1&C2) == C2

should be done.

This change has been tested:
 Using a debug+asserts build:
   on the specific test case that brought this bug to light
   make check-all
   lnt nt
   using this clang to build a release version of clang
 Using the release+asserts clang-with-clang build:
   on the specific test case that brought this bug to light
   make check-all
   lnt nt

Checking in because Evan wants it checked in.  Test case forthcoming after
scrubbing.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154955 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/TargetLowering.cpp

index 09a2b1f3d7a5da16fc314eb4e7ccd27093dc6d28..e341e15e41ad4bfa47698a8d007a661f4c3dac6f 100644 (file)
@@ -1367,8 +1367,9 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
     // 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 ((NewMask & (KnownZero|KnownOne)) == NewMask) { // all known
-      if ((KnownOne & KnownOne2) == KnownOne) {
+    // NB: it is okay if more bits are known than are requested
+    if ((NewMask & (KnownZero|KnownOne)) == NewMask) { // all known on one side 
+      if (KnownOne == KnownOne2) { // set bits are the same on both sides
         EVT VT = Op.getValueType();
         SDValue ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, VT);
         return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, dl, VT,