[llvm-commits] [llvm] r93145 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCasts.cpp test/Transforms/InstCombine/cast.ll

Chris Lattner sabre at nondot.org
Sun Jan 10 20:05:13 PST 2010


Author: lattner
Date: Sun Jan 10 22:05:13 2010
New Revision: 93145

URL: http://llvm.org/viewvc/llvm-project?rev=93145&view=rev
Log:
Extend CanEvaluateZExtd to handle and/or/xor more aggressively in the
BitsToClear case.  This allows it to promote expressions which have an
and/or/xor after the lshr, promoting cases like test2 (from PR4216) 
and test3 (random extample extracted from a spec benchmark).

clang now compiles the code in PR4216 into:

_test_bitfield:                                             ## @test_bitfield
	movl	%edi, %eax
	orl	$194, %eax
	movl	$4294902010, %ecx
	andq	%rax, %rcx
	orl	$32768, %edi
	andq	$39936, %rdi
	movq	%rdi, %rax
	orq	%rcx, %rax
	ret

instead of:

_test_bitfield:                                             ## @test_bitfield
	movl	%edi, %eax
	orl	$194, %eax
	movl	$4294902010, %ecx
	andq	%rax, %rcx
	shrl	$8, %edi
	orl	$128, %edi
	shlq	$8, %rdi
	andq	$39936, %rdi
	movq	%rdi, %rax
	orq	%rcx, %rax
	ret

which is still not great, but is progress.


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/test/Transforms/InstCombine/cast.ll

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

==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Sun Jan 10 22:05:13 2010
@@ -634,6 +634,20 @@
     if (BitsToClear == 0 && Tmp == 0)
       return true;
       
+    // If the operation is an AND/OR/XOR and the bits to clear are zero in the
+    // other side, BitsToClear is ok.
+    if (Tmp == 0 &&
+        (Opc == Instruction::And || Opc == Instruction::Or ||
+         Opc == Instruction::Xor)) {
+      // We use MaskedValueIsZero here for generality, but the case we care
+      // about the most is constant RHS.
+      unsigned VSize = V->getType()->getScalarSizeInBits();
+      if (MaskedValueIsZero(I->getOperand(1),
+                            APInt::getHighBitsSet(VSize, BitsToClear)))
+        return true;
+    }
+      
+    // Otherwise, we don't know how to analyze this BitsToClear case yet.
     return false;
       
   case Instruction::LShr:
@@ -652,6 +666,8 @@
   case Instruction::Select:
     if (!CanEvaluateZExtd(I->getOperand(1), Ty, Tmp) ||
         !CanEvaluateZExtd(I->getOperand(2), Ty, BitsToClear) ||
+        // TODO: If important, we could handle the case when the BitsToClear are
+        // known zero in the disagreeing side.
         Tmp != BitsToClear)
       return false;
     return true;
@@ -665,6 +681,8 @@
       return false;
     for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
       if (!CanEvaluateZExtd(PN->getIncomingValue(i), Ty, Tmp) ||
+          // TODO: If important, we could handle the case when the BitsToClear
+          // are known zero in the disagreeing input.
           Tmp != BitsToClear)
         return false;
     return true;

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

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/cast.ll Sun Jan 10 22:05:13 2010
@@ -572,3 +572,34 @@
 ; CHECK-NEXT: %E = and i64 %C, 16777215
 ; CHECK-NEXT: ret i64 %E
 }
+
+define i64 @test58(i64 %A) nounwind {
+ %B = trunc i64 %A to i32
+ %C = lshr i32 %B, 8
+ %D = or i32 %C, 128
+ %E = zext i32 %D to i64
+ ret i64 %E
+ 
+; CHECK: @test58
+; CHECK-NEXT:   %C = lshr i64 %A, 8
+; CHECK-NEXT:   %D = or i64 %C, 128
+; CHECK-NEXT:   %E = and i64 %D, 16777215
+; CHECK-NEXT:   ret i64 %E
+}
+
+define i64 @test59(i8 %A, i8 %B) nounwind {
+  %C = zext i8 %A to i32
+  %D = shl i32 %C, 4
+  %E = and i32 %D, 48
+  %F = zext i8 %B to i32
+  %G = lshr i32 %F, 4
+  %H = or i32 %G, %E
+  %I = zext i32 %H to i64
+  ret i64 %I
+; CHECK: @test59
+; CHECK-NEXT:   %C = zext i8 %A to i64
+; CHECK-NOT: i32
+; CHECK:   %F = zext i8 %B to i64
+; CHECK-NOT: i32
+; CHECK:   ret i64 %H
+}





More information about the llvm-commits mailing list