[llvm-commits] [llvm] r94943 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineAddSub.cpp test/Transforms/InstCombine/signext.ll

Eli Friedman eli.friedman at gmail.com
Sat Jan 30 20:29:17 PST 2010


Author: efriedma
Date: Sat Jan 30 22:29:12 2010
New Revision: 94943

URL: http://llvm.org/viewvc/llvm-project?rev=94943&view=rev
Log:
Simplify/generalize the xor+add->sign-extend instcombine.


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/trunk/test/Transforms/InstCombine/signext.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp?rev=94943&r1=94942&r2=94943&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp Sat Jan 30 22:29:12 2010
@@ -121,42 +121,26 @@
         match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) {
       uint32_t TySizeBits = I.getType()->getScalarSizeInBits();
       const APInt& RHSVal = cast<ConstantInt>(RHSC)->getValue();
-      
-      uint32_t Size = TySizeBits / 2;
-      APInt C0080Val(APInt(TySizeBits, 1ULL).shl(Size - 1));
-      APInt CFF80Val(-C0080Val);
-      do {
-        if (TySizeBits > Size) {
-          // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
-          // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext.
-          if ((RHSVal == CFF80Val && XorRHS->getValue() == C0080Val) ||
-              (RHSVal == C0080Val && XorRHS->getValue() == CFF80Val)) {
-            // This is a sign extend if the top bits are known zero.
-            if (!MaskedValueIsZero(XorLHS, 
-                   APInt::getHighBitsSet(TySizeBits, TySizeBits - Size)))
-              Size = 0;  // Not a sign ext, but can't be any others either.
-            break;
-          }
-        }
-        Size >>= 1;
-        C0080Val = APIntOps::lshr(C0080Val, Size);
-        CFF80Val = APIntOps::ashr(CFF80Val, Size);
-      } while (Size >= 1);
-      
-      // FIXME: This shouldn't be necessary. When the backends can handle types
-      // with funny bit widths then this switch statement should be removed. It
-      // is just here to get the size of the "middle" type back up to something
-      // that the back ends can handle.
-      const Type *MiddleType = 0;
-      switch (Size) {
-        default: break;
-        case 32:
-        case 16:
-        case  8: MiddleType = IntegerType::get(I.getContext(), Size); break;
-      }
-      if (MiddleType) {
-        Value *NewTrunc = Builder->CreateTrunc(XorLHS, MiddleType, "sext");
-        return new SExtInst(NewTrunc, I.getType(), I.getName());
+      unsigned ExtendAmt = 0;
+      // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
+      // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext.
+      if (XorRHS->getValue() == -RHSVal) {
+        if (RHSVal.isPowerOf2())
+          ExtendAmt = TySizeBits - RHSVal.logBase2() - 1;
+        else if (XorRHS->getValue().isPowerOf2())
+          ExtendAmt = TySizeBits - XorRHS->getValue().logBase2() - 1;
+      }
+
+      if (ExtendAmt) {
+        APInt Mask = APInt::getHighBitsSet(TySizeBits, ExtendAmt);
+        if (!MaskedValueIsZero(XorLHS, Mask))
+          ExtendAmt = 0;
+      }
+
+      if (ExtendAmt) {
+        Constant *ShAmt = ConstantInt::get(I.getType(), ExtendAmt);
+        Value *NewShl = Builder->CreateShl(XorLHS, ShAmt, "sext");
+        return BinaryOperator::CreateAShr(NewShl, ShAmt);
       }
     }
   }

Modified: llvm/trunk/test/Transforms/InstCombine/signext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/signext.ll?rev=94943&r1=94942&r2=94943&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/signext.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/signext.ll Sat Jan 30 22:29:12 2010
@@ -8,8 +8,8 @@
         %tmp.3 = add i32 %tmp.2, 32768          ; <i32> [#uses=1]
         ret i32 %tmp.3
 ; CHECK: @test1
-; CHECK: %sext1 = shl i32 %x, 16
-; CHECK: %tmp.3 = ashr i32 %sext1, 16
+; CHECK: %sext = shl i32 %x, 16
+; CHECK: %tmp.3 = ashr i32 %sext, 16
 ; CHECK: ret i32 %tmp.3
 }
 
@@ -19,8 +19,8 @@
         %tmp.3 = add i32 %tmp.2, -32768         ; <i32> [#uses=1]
         ret i32 %tmp.3
 ; CHECK: @test2
-; CHECK: %sext1 = shl i32 %x, 16
-; CHECK: %tmp.3 = ashr i32 %sext1, 16
+; CHECK: %sext = shl i32 %x, 16
+; CHECK: %tmp.3 = ashr i32 %sext, 16
 ; CHECK: ret i32 %tmp.3
 }
 
@@ -50,8 +50,8 @@
         %tmp.3 = add i32 %tmp.2, -128           ; <i32> [#uses=1]
         ret i32 %tmp.3
 ; CHECK: @test5
-; CHECK: %sext1 = shl i32 %x, 24
-; CHECK: %tmp.3 = ashr i32 %sext1, 24
+; CHECK: %sext = shl i32 %x, 24
+; CHECK: %tmp.3 = ashr i32 %sext, 24
 ; CHECK: ret i32 %tmp.3
 }
 
@@ -74,3 +74,14 @@
 ; CHECK: %tmp.5 = sext i16 %P to i32
 ; CHECK: ret i32 %tmp.5
 }
+
+define i32 @test8(i32 %x) nounwind readnone {
+entry:
+  %shr = lshr i32 %x, 5                           ; <i32> [#uses=1]
+  %xor = xor i32 %shr, 67108864                   ; <i32> [#uses=1]
+  %sub = add i32 %xor, -67108864                  ; <i32> [#uses=1]
+  ret i32 %sub
+; CHECK: @test8
+; CHECK: %sub = ashr i32 %x, 5
+; CHECK: ret i32 %sub
+}





More information about the llvm-commits mailing list