[llvm-commits] [llvm] r130405 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp test/Transforms/InstCombine/merge-icmp.ll
Benjamin Kramer
benny.kra at googlemail.com
Thu Apr 28 09:58:40 PDT 2011
Author: d0k
Date: Thu Apr 28 11:58:40 2011
New Revision: 130405
URL: http://llvm.org/viewvc/llvm-project?rev=130405&view=rev
Log:
InstCombine: Merge "(trunc x) == C1 & (and x, CA) == C2" into a single and+icmp.
This happens when GVN widens loads. Part of PR6627.
Added:
llvm/trunk/test/Transforms/InstCombine/merge-icmp.ll
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=130405&r1=130404&r2=130405&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Thu Apr 28 11:58:40 2011
@@ -769,6 +769,42 @@
return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
}
}
+
+ // (trunc x) == C1 & (and x, CA) == C2 -> (and CA|CMAX) == C1|C2
+ // where CMAX is the all ones value for the truncated type,
+ // iff the lower bits of CA are zero.
+ if (LHSCC == RHSCC && ICmpInst::isEquality(LHSCC) &&
+ LHS->hasOneUse() && RHS->hasOneUse()) {
+ Value *V;
+ ConstantInt *AndCst, *SmallCst = 0, *BigCst = 0;
+
+ // (trunc x) == C1 & (and x, CA) == C2
+ if (match(Val2, m_Trunc(m_Value(V))) &&
+ match(Val, m_And(m_Specific(V), m_ConstantInt(AndCst)))) {
+ SmallCst = RHSCst;
+ BigCst = LHSCst;
+ }
+ // (and x, CA) == C2 & (trunc x) == C1
+ else if (match(Val, m_Trunc(m_Value(V))) &&
+ match(Val2, m_And(m_Specific(V), m_ConstantInt(AndCst)))) {
+ SmallCst = LHSCst;
+ BigCst = RHSCst;
+ }
+
+ if (SmallCst && BigCst) {
+ unsigned BigBitSize = BigCst->getType()->getBitWidth();
+ unsigned SmallBitSize = SmallCst->getType()->getBitWidth();
+
+ // Check that the low bits are zero.
+ APInt Low = APInt::getLowBitsSet(BigBitSize, SmallBitSize);
+ if ((Low & AndCst->getValue()) == 0) {
+ Value *NewAnd = Builder->CreateAnd(V, Low | AndCst->getValue());
+ APInt N = SmallCst->getValue().zext(BigBitSize) | BigCst->getValue();
+ Value *NewVal = ConstantInt::get(AndCst->getType()->getContext(), N);
+ return Builder->CreateICmp(LHSCC, NewAnd, NewVal);
+ }
+ }
+ }
// From here on, we only handle:
// (icmp1 A, C1) & (icmp2 A, C2) --> something simpler.
Added: llvm/trunk/test/Transforms/InstCombine/merge-icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/merge-icmp.ll?rev=130405&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/merge-icmp.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/merge-icmp.ll Thu Apr 28 11:58:40 2011
@@ -0,0 +1,29 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+define i1 @test1(i16* %x) {
+ %load = load i16* %x, align 4
+ %trunc = trunc i16 %load to i8
+ %cmp1 = icmp eq i8 %trunc, 127
+ %and = and i16 %load, -256
+ %cmp2 = icmp eq i16 %and, 17664
+ %or = and i1 %cmp1, %cmp2
+ ret i1 %or
+; CHECK: @test1
+; CHECK-NEXT: load i16
+; CHECK-NEXT: icmp eq i16 %load, 17791
+; CHECK-NEXT: ret i1
+}
+
+define i1 @test2(i16* %x) {
+ %load = load i16* %x, align 4
+ %and = and i16 %load, -256
+ %cmp1 = icmp eq i16 %and, 32512
+ %trunc = trunc i16 %load to i8
+ %cmp2 = icmp eq i8 %trunc, 69
+ %or = and i1 %cmp1, %cmp2
+ ret i1 %or
+; CHECK: @test2
+; CHECK-NEXT: load i16
+; CHECK-NEXT: icmp eq i16 %load, 32581
+; CHECK-NEXT: ret i1
+}
More information about the llvm-commits
mailing list