InstCombine: turn (C1 << A) << C2) into (C1 << C2) << A)
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 29 Apr 2011 08:15:41 +0000 (08:15 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 29 Apr 2011 08:15:41 +0000 (08:15 +0000)
Fixes PR9809.

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

lib/Transforms/InstCombine/InstCombineShifts.cpp
test/Transforms/InstCombine/shift.ll

index a7f800587bb65a129f36e76f7a5166df1ae5adc2..8143b257b303d404fc8b52745b4be29a99ca66a1 100644 (file)
@@ -644,7 +644,14 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) {
       return &I;
     }
   }
-  
+
+  // (C1 << A) << C2) -> (C1 << C2) << A)
+  Constant *C1, *C2;
+  Value *A;
+  if (match(I.getOperand(0), m_OneUse(m_Shl(m_Constant(C1), m_Value(A)))) &&
+      match(I.getOperand(1), m_Constant(C2)))
+    return BinaryOperator::CreateShl(ConstantExpr::getShl(C1, C2), A);
+
   return 0;    
 }
 
index 7fab1d2cab54b03915b0ed9ba7eedab6667506a2..bded68ac4755840cba6e238ce36bb0b24f2ba6c7 100644 (file)
@@ -485,3 +485,24 @@ entry:
 ; CHECK: ret i8 %tmp551
   ret i8 %tmp55
 }
+
+; PR9809
+define i32 @test40(i32 %a, i32 %b) nounwind {
+  %shl1 = shl i32 1, %b
+  %shl2 = shl i32 %shl1, 2
+  %div = udiv i32 %a, %shl2
+  ret i32 %div
+; CHECK: @test40
+; CHECK-NEXT: add i32 %b, 2
+; CHECK-NEXT: lshr i32 %a
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test41(i32 %a, i32 %b) nounwind {
+  %1 = shl i32 1, %b
+  %2 = shl i32 %1, 3
+  ret i32 %2
+; CHECK: @test41
+; CHECK-NEXT: shl i32 8, %b
+; CHECK-NEXT: ret i32
+}