]> granicus.if.org Git - llvm/commitdiff
[InstCombine] fixed to propagate 'exact' on lshr
authorSanjay Patel <spatel@rotateright.com>
Mon, 30 Jan 2017 16:53:03 +0000 (16:53 +0000)
committerSanjay Patel <spatel@rotateright.com>
Mon, 30 Jan 2017 16:53:03 +0000 (16:53 +0000)
The original shift is bigger, so this may qualify as 'obvious',
but here's an attempt at an Alive-based proof:

Name: exact
Pre: (C1 u< C2)
%a = shl i8 %x, C1
%b = lshr exact i8 %a, C2
  =>
%c = lshr exact i8 %x, C2 - C1
%b = and i8 %c, ((1 << width(C1)) - 1) u>> C2

Optimization is correct!

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

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

index 6cf64c261724c00744dcdf55121675fa7b02de80..55b37f0fe62aa189834da4d40e8194d71e638517 100644 (file)
@@ -773,7 +773,7 @@ Instruction *InstCombiner::visitLShr(BinaryOperator &I) {
           return NewLShr;
         }
         // (X << C1) >>u C2  --> (X >>u (C2 - C1)) & (-1 >> C2)
-        Value *NewLShr = Builder->CreateLShr(X, ShiftDiff);
+        Value *NewLShr = Builder->CreateLShr(X, ShiftDiff, "", I.isExact());
         APInt Mask(APInt::getLowBitsSet(BitWidth, BitWidth - ShAmt));
         return BinaryOperator::CreateAnd(NewLShr, ConstantInt::get(Ty, Mask));
       }
index ac9b7e1c37fa720ddb4e117544eb518d125a47b9..5e8b4cb3250f899b28192b23b4870e5eda68849c 100644 (file)
@@ -937,7 +937,7 @@ define <2 x i32> @test51_splat_vec(<2 x i32> %x) {
 
 define i32 @test51_no_nuw(i32 %x) {
 ; CHECK-LABEL: @test51_no_nuw(
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 %x, 2
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 %x, 2
 ; CHECK-NEXT:    [[B:%.*]] = and i32 [[TMP1]], 536870911
 ; CHECK-NEXT:    ret i32 [[B]]
 ;