[llvm-commits] [llvm] r54408 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/sext-misc.ll

Chris Lattner sabre at nondot.org
Wed Aug 6 00:35:53 PDT 2008


Author: lattner
Date: Wed Aug  6 02:35:52 2008
New Revision: 54408

URL: http://llvm.org/viewvc/llvm-project?rev=54408&view=rev
Log:
optimize a common idiom generated by clang for bitfield access, PR2638.

Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/sext-misc.ll

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=54408&r1=54407&r2=54408&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed Aug  6 02:35:52 2008
@@ -7666,7 +7666,37 @@
         return new TruncInst(Op, CI.getType(), "tmp");
     }
   }
-      
+
+  // If the input is a shl/ashr pair of a same constant, then this is a sign
+  // extension from a smaller value.  If we could trust arbitrary bitwidth
+  // integers, we could turn this into a truncate to the smaller bit and then
+  // use a sext for the whole extension.  Since we don't, look deeper and check
+  // for a truncate.  If the source and dest are the same type, eliminate the
+  // trunc and extend and just do shifts.  For example, turn:
+  //   %a = trunc i32 %i to i8
+  //   %b = shl i8 %a, 6
+  //   %c = ashr i8 %b, 6
+  //   %d = sext i8 %c to i32
+  // into:
+  //   %a = shl i32 %i, 30
+  //   %d = ashr i32 %a, 30
+  Value *A = 0;
+  ConstantInt *BA = 0, *CA = 0;
+  if (match(Src, m_AShr(m_Shl(m_Value(A), m_ConstantInt(BA)),
+                        m_ConstantInt(CA))) &&
+      BA == CA && isa<TruncInst>(A)) {
+    Value *I = cast<TruncInst>(A)->getOperand(0);
+    if (I->getType() == CI.getType()) {
+      unsigned MidSize = Src->getType()->getPrimitiveSizeInBits();
+      unsigned SrcDstSize = CI.getType()->getPrimitiveSizeInBits();
+      unsigned ShAmt = CA->getZExtValue()+SrcDstSize-MidSize;
+      Constant *ShAmtV = ConstantInt::get(CI.getType(), ShAmt);
+      I = InsertNewInstBefore(BinaryOperator::CreateShl(I, ShAmtV,
+                                                        CI.getName()), CI);
+      return BinaryOperator::CreateAShr(I, ShAmtV);
+    }
+  }
+  
   return 0;
 }
 

Modified: llvm/trunk/test/Transforms/InstCombine/sext-misc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sext-misc.ll?rev=54408&r1=54407&r2=54408&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/sext-misc.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/sext-misc.ll Wed Aug  6 02:35:52 2008
@@ -63,3 +63,13 @@
 	ret i16 %W
 }
 
+; PR2638
+define i32 @test2(i32 %i) nounwind  {
+entry:
+        %tmp12 = trunc i32 %i to i8             ; <i8> [#uses=1]
+        %tmp16 = shl i8 %tmp12, 6               ; <i8> [#uses=1]
+        %a = ashr i8 %tmp16, 6            ; <i8> [#uses=1]
+        %b = sext i8 %a to i32            ; <i32> [#uses=1]
+        ret i32 %b
+}
+





More information about the llvm-commits mailing list