From bf188aeae7a579fb71480be7d32a2edc4d56d827 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 15 Jun 2011 01:12:31 +0000 Subject: [PATCH] PerformBFICombine - (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff the bits being cleared by the AND are not demanded by the BFI. The previous BFI dag combine rule was actually incorrect (or used to be correct until BFI representation changed). rdar://9609030 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133034 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 11 +++++++---- test/CodeGen/ARM/bfi.ll | 13 +++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index c4513fd97d1..358eb597ccd 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -5976,8 +5976,8 @@ static SDValue PerformORCombine(SDNode *N, return SDValue(); } -/// PerformBFICombine - (bfi A, (and B, C1), C2) -> (bfi A, B, C2) iff -/// C1 & C2 == C1. +/// PerformBFICombine - (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff +/// the bits being cleared by the AND are not demanded by the BFI. static SDValue PerformBFICombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) { SDValue N1 = N->getOperand(1); @@ -5985,9 +5985,12 @@ static SDValue PerformBFICombine(SDNode *N, ConstantSDNode *N11C = dyn_cast(N1.getOperand(1)); if (!N11C) return SDValue(); - unsigned Mask = cast(N->getOperand(2))->getZExtValue(); + unsigned InvMask = cast(N->getOperand(2))->getZExtValue(); + unsigned LSB = CountTrailingZeros_32(~InvMask); + unsigned Width = (32 - CountLeadingZeros_32(~InvMask)) - LSB; + unsigned Mask = (1 << Width)-1; unsigned Mask2 = N11C->getZExtValue(); - if ((Mask & Mask2) == Mask2) + if ((Mask & (~Mask2)) == 0) return DCI.DAG.getNode(ARMISD::BFI, N->getDebugLoc(), N->getValueType(0), N->getOperand(0), N1.getOperand(0), N->getOperand(2)); diff --git a/test/CodeGen/ARM/bfi.ll b/test/CodeGen/ARM/bfi.ll index c94b096d9cc..84f3813975a 100644 --- a/test/CodeGen/ARM/bfi.ll +++ b/test/CodeGen/ARM/bfi.ll @@ -61,3 +61,16 @@ entry: %3 = or i32 %2, %0 ret i32 %3 } + +; rdar://9609030 +define i32 @f6(i32 %a, i32 %b) nounwind readnone { +entry: +; CHECK: f6: +; CHECK-NOT: bic +; CHECK: bfi r0, r1, #8, #9 + %and = and i32 %a, -130817 + %and2 = shl i32 %b, 8 + %shl = and i32 %and2, 130816 + %or = or i32 %shl, %and + ret i32 %or +} -- 2.34.1