llvm.org GIT mirror llvm / f7ff467
Merging r246900: ------------------------------------------------------------------------ r246900 | hfinkel | 2015-09-04 20:02:59 -0400 (Fri, 04 Sep 2015) | 14 lines [PowerPC] Fix and(or(x, c1), c2) -> rlwimi generation PPCISelDAGToDAG has a transformation that generates a rlwimi instruction from an input pattern that looks like this: and(or(x, c1), c2) but the associated logic does not work if there are bits that are 1 in c1 but 0 in c2 (these are normally canonicalized away, but that can't happen if the 'or' has other users. Make sure we abort the transformation if such bits are discovered. Fixes PR24704. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_37@252480 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 3 years ago
2 changed file(s) with 42 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
25692569 return nullptr;
25702570 }
25712571 // ISD::OR doesn't get all the bitfield insertion fun.
2572 // (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) is a bitfield insert
2572 // (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) might be a
2573 // bitfield insert.
25732574 if (isInt32Immediate(N->getOperand(1), Imm) &&
25742575 N->getOperand(0).getOpcode() == ISD::OR &&
25752576 isInt32Immediate(N->getOperand(0).getOperand(1), Imm2)) {
2577 // The idea here is to check whether this is equivalent to:
2578 // (c1 & m) | (x & ~m)
2579 // where m is a run-of-ones mask. The logic here is that, for each bit in
2580 // c1 and c2:
2581 // - if both are 1, then the output will be 1.
2582 // - if both are 0, then the output will be 0.
2583 // - if the bit in c1 is 0, and the bit in c2 is 1, then the output will
2584 // come from x.
2585 // - if the bit in c1 is 1, and the bit in c2 is 0, then the output will
2586 // be 0.
2587 // If that last condition is never the case, then we can form m from the
2588 // bits that are the same between c1 and c2.
25762589 unsigned MB, ME;
2577 Imm = ~(Imm^Imm2);
2578 if (isRunOfOnes(Imm, MB, ME)) {
2590 if (isRunOfOnes(~(Imm^Imm2), MB, ME) && !(~Imm & Imm2)) {
25792591 SDValue Ops[] = { N->getOperand(0).getOperand(0),
25802592 N->getOperand(0).getOperand(1),
25812593 getI32Imm(0, dl), getI32Imm(MB, dl),
0 ; RUN: llc < %s | FileCheck %s
1 target datalayout = "E-m:e-i64:64-n32:64"
2 target triple = "powerpc64-unknown-linux-gnu"
3
4 @m = external global i32, align 4
5
6 ; Function Attrs: nounwind
7 define signext i32 @main() #0 {
8 entry:
9
10 ; CHECK-LABEL: @main
11 ; CHECK-NOT: rlwimi
12 ; CHECK: andi
13
14 %0 = load i32, i32* @m, align 4
15 %or = or i32 %0, 250
16 store i32 %or, i32* @m, align 4
17 %and = and i32 %or, 249
18 %sub.i = sub i32 %and, 0
19 %sext = shl i32 %sub.i, 24
20 %conv = ashr exact i32 %sext, 24
21 ret i32 %conv
22 }
23
24 attributes #0 = { nounwind "target-cpu"="pwr7" }
25 attributes #1 = { nounwind }
26