[llvm] r228503 - ValueTracking: Make isBytewiseValue simpler and more powerful at the same time.
Benjamin Kramer
benny.kra at googlemail.com
Sat Feb 7 11:29:03 PST 2015
Author: d0k
Date: Sat Feb 7 13:29:02 2015
New Revision: 228503
URL: http://llvm.org/viewvc/llvm-project?rev=228503&view=rev
Log:
ValueTracking: Make isBytewiseValue simpler and more powerful at the same time.
Turns out there is a simpler way of checking that all bytes in a word are equal
than binary decomposition.
Modified:
llvm/trunk/lib/Analysis/ValueTracking.cpp
llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=228503&r1=228502&r2=228503&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Sat Feb 7 13:29:02 2015
@@ -2121,26 +2121,16 @@ Value *llvm::isBytewiseValue(Value *V) {
// Don't handle long double formats, which have strange constraints.
}
- // We can handle constant integers that are power of two in size and a
- // multiple of 8 bits.
+ // We can handle constant integers that are multiple of 8 bits.
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
- unsigned Width = CI->getBitWidth();
- if (isPowerOf2_32(Width) && Width > 8) {
- // We can handle this value if the recursive binary decomposition is the
- // same at all levels.
- APInt Val = CI->getValue();
- APInt Val2;
- while (Val.getBitWidth() != 8) {
- unsigned NextWidth = Val.getBitWidth()/2;
- Val2 = Val.lshr(NextWidth);
- Val2 = Val2.trunc(Val.getBitWidth()/2);
- Val = Val.trunc(Val.getBitWidth()/2);
+ if (CI->getBitWidth() % 8 == 0) {
+ assert(CI->getBitWidth() > 8 && "8 bits should be handled above!");
- // If the top/bottom halves aren't the same, reject it.
- if (Val != Val2)
- return nullptr;
- }
- return ConstantInt::get(V->getContext(), Val);
+ // We can check that all bytes of an integer are equal by making use of a
+ // little trick: rotate by 8 and check if it's still the same value.
+ if (CI->getValue() != CI->getValue().rotl(8))
+ return nullptr;
+ return ConstantInt::get(V->getContext(), CI->getValue().trunc(8));
}
}
Modified: llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll?rev=228503&r1=228502&r2=228503&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll (original)
+++ llvm/trunk/test/Transforms/MemCpyOpt/form-memset.ll Sat Feb 7 13:29:02 2015
@@ -284,3 +284,18 @@ define void @test10(i8* nocapture %P) no
; CHECK-NOT: memset
; CHECK: ret void
}
+
+; Memset followed by odd store.
+define void @test11(i32* nocapture %P) nounwind ssp {
+entry:
+ %add.ptr = getelementptr inbounds i32* %P, i64 3
+ %0 = bitcast i32* %add.ptr to i8*
+ tail call void @llvm.memset.p0i8.i64(i8* %0, i8 1, i64 11, i32 1, i1 false)
+ %arrayidx = getelementptr inbounds i32* %P, i64 0
+ %arrayidx.cast = bitcast i32* %arrayidx to i96*
+ store i96 310698676526526814092329217, i96* %arrayidx.cast, align 4
+ ret void
+; CHECK-LABEL: @test11(
+; CHECK-NOT: store
+; CHECK: call void @llvm.memset.p0i8.i64(i8* %1, i8 1, i64 23, i32 4, i1 false)
+}
More information about the llvm-commits
mailing list