Skip to content

Commit f8d4018

Browse files
committedMar 28, 2017
[PPC] In PPCBoolRetToInt change the bool value to i64 if the target is ppc64
In PPCBoolRetToInt bool value is changed to i32 type. On ppc64 it may introduce an extra zero extension for the return value. This patch changes the integer type to i64 to avoid the zero extension on ppc64. This patch fixed PR32442. Differential Revision: https://reviews.llvm.org/D31407 llvm-svn: 298955
1 parent a41a5c2 commit f8d4018

File tree

5 files changed

+71
-33
lines changed

5 files changed

+71
-33
lines changed
 

‎llvm/lib/Target/PowerPC/PPC.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ namespace llvm {
4444
FunctionPass *createPPCQPXLoadSplatPass();
4545
FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
4646
FunctionPass *createPPCTLSDynamicCallPass();
47-
FunctionPass *createPPCBoolRetToIntPass();
47+
FunctionPass *createPPCBoolRetToIntPass(PPCTargetMachine *TM);
4848
FunctionPass *createPPCExpandISELPass();
4949
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
5050
AsmPrinter &AP, bool isDarwin);

‎llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp

+35-17
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
//
88
//===----------------------------------------------------------------------===//
99
//
10-
// This file implements converting i1 values to i32 if they could be more
10+
// This file implements converting i1 values to i32/i64 if they could be more
1111
// profitably allocated as GPRs rather than CRs. This pass will become totally
1212
// unnecessary if Register Bank Allocation and Global Instruction Selection ever
1313
// go upstream.
1414
//
15-
// Presently, the pass converts i1 Constants, and Arguments to i32 if the
15+
// Presently, the pass converts i1 Constants, and Arguments to i32/i64 if the
1616
// transitive closure of their uses includes only PHINodes, CallInsts, and
1717
// ReturnInsts. The rational is that arguments are generally passed and returned
18-
// in GPRs rather than CRs, so casting them to i32 at the LLVM IR level will
18+
// in GPRs rather than CRs, so casting them to i32/i64 at the LLVM IR level will
1919
// actually save casts at the Machine Instruction level.
2020
//
2121
// It might be useful to expand this pass to add bit-wise operations to the list
@@ -33,6 +33,7 @@
3333
//===----------------------------------------------------------------------===//
3434

3535
#include "PPC.h"
36+
#include "PPCTargetMachine.h"
3637
#include "llvm/ADT/DenseMap.h"
3738
#include "llvm/ADT/SmallPtrSet.h"
3839
#include "llvm/ADT/SmallVector.h"
@@ -87,17 +88,19 @@ class PPCBoolRetToInt : public FunctionPass {
8788
return Defs;
8889
}
8990

90-
// Translate a i1 value to an equivalent i32 value:
91-
static Value *translate(Value *V) {
92-
Type *Int32Ty = Type::getInt32Ty(V->getContext());
91+
// Translate a i1 value to an equivalent i32/i64 value:
92+
Value *translate(Value *V) {
93+
Type *IntTy = ST->isPPC64() ? Type::getInt64Ty(V->getContext())
94+
: Type::getInt32Ty(V->getContext());
95+
9396
if (auto *C = dyn_cast<Constant>(V))
94-
return ConstantExpr::getZExt(C, Int32Ty);
97+
return ConstantExpr::getZExt(C, IntTy);
9598
if (auto *P = dyn_cast<PHINode>(V)) {
9699
// Temporarily set the operands to 0. We'll fix this later in
97100
// runOnUse.
98-
Value *Zero = Constant::getNullValue(Int32Ty);
101+
Value *Zero = Constant::getNullValue(IntTy);
99102
PHINode *Q =
100-
PHINode::Create(Int32Ty, P->getNumIncomingValues(), P->getName(), P);
103+
PHINode::Create(IntTy, P->getNumIncomingValues(), P->getName(), P);
101104
for (unsigned i = 0; i < P->getNumOperands(); ++i)
102105
Q->addIncoming(Zero, P->getIncomingBlock(i));
103106
return Q;
@@ -109,7 +112,7 @@ class PPCBoolRetToInt : public FunctionPass {
109112

110113
auto InstPt =
111114
A ? &*A->getParent()->getEntryBlock().begin() : I->getNextNode();
112-
return new ZExtInst(V, Int32Ty, "", InstPt);
115+
return new ZExtInst(V, IntTy, "", InstPt);
113116
}
114117

115118
typedef SmallPtrSet<const PHINode *, 8> PHINodeSet;
@@ -177,14 +180,22 @@ class PPCBoolRetToInt : public FunctionPass {
177180
public:
178181
static char ID;
179182

180-
PPCBoolRetToInt() : FunctionPass(ID) {
183+
PPCBoolRetToInt() : FunctionPass(ID), TM(nullptr) {
184+
initializePPCBoolRetToIntPass(*PassRegistry::getPassRegistry());
185+
}
186+
187+
PPCBoolRetToInt(TargetMachine *&TM) : FunctionPass(ID), TM(TM) {
181188
initializePPCBoolRetToIntPass(*PassRegistry::getPassRegistry());
182189
}
183190

184191
bool runOnFunction(Function &F) override {
185192
if (skipFunction(F))
186193
return false;
187194

195+
if (!TM)
196+
return false;
197+
ST = ((PPCTargetMachine*)TM)->getSubtargetImpl(F);
198+
188199
PHINodeSet PromotablePHINodes = getPromotablePHINodes(F);
189200
B2IMap Bool2IntMap;
190201
bool Changed = false;
@@ -205,7 +216,7 @@ class PPCBoolRetToInt : public FunctionPass {
205216
return Changed;
206217
}
207218

208-
static bool runOnUse(Use &U, const PHINodeSet &PromotablePHINodes,
219+
bool runOnUse(Use &U, const PHINodeSet &PromotablePHINodes,
209220
B2IMap &BoolToIntMap) {
210221
auto Defs = findAllDefs(U);
211222

@@ -262,13 +273,20 @@ class PPCBoolRetToInt : public FunctionPass {
262273
AU.addPreserved<DominatorTreeWrapperPass>();
263274
FunctionPass::getAnalysisUsage(AU);
264275
}
276+
277+
private:
278+
const PPCSubtarget *ST;
279+
TargetMachine *TM;
265280
};
266281

267282
} // end anonymous namespace
268283

269284
char PPCBoolRetToInt::ID = 0;
270-
INITIALIZE_PASS(PPCBoolRetToInt, "bool-ret-to-int",
271-
"Convert i1 constants to i32 if they are returned",
272-
false, false)
273-
274-
FunctionPass *llvm::createPPCBoolRetToIntPass() { return new PPCBoolRetToInt(); }
285+
INITIALIZE_TM_PASS(PPCBoolRetToInt, "bool-ret-to-int",
286+
"Convert i1 constants to i32/i64 if they are returned",
287+
false, false)
288+
289+
FunctionPass *llvm::createPPCBoolRetToIntPass(PPCTargetMachine *TM) {
290+
TargetMachine *pTM = TM;
291+
return new PPCBoolRetToInt(pTM);
292+
}

‎llvm/lib/Target/PowerPC/PPCTargetMachine.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) {
323323

324324
void PPCPassConfig::addIRPasses() {
325325
if (TM->getOptLevel() != CodeGenOpt::None)
326-
addPass(createPPCBoolRetToIntPass());
326+
addPass(createPPCBoolRetToIntPass(&getPPCTargetMachine()));
327327
addPass(createAtomicExpandPass(&getPPCTargetMachine()));
328328

329329
// For the BG/Q (or if explicitly requested), add explicit data prefetch
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llc -mtriple=powerpc64le-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
2+
3+
; https://bugs.llvm.org/show_bug.cgi?id=32442
4+
; Don't generate zero extension for the return value.
5+
; CHECK-NOT: clrldi
6+
7+
define zeroext i1 @foo(i32 signext %i, i32* %p) {
8+
entry:
9+
%cmp = icmp eq i32 %i, 0
10+
br i1 %cmp, label %return, label %if.end
11+
12+
if.end:
13+
store i32 %i, i32* %p, align 4
14+
br label %return
15+
16+
return:
17+
%retval = phi i1 [ true, %if.end ], [ false, %entry ]
18+
ret i1 %retval
19+
}
20+

‎llvm/test/CodeGen/PowerPC/BoolRetToIntTest.ll

+14-14
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ for.body: ; preds = %for.body.preheader,
3131
br i1 %call, label %cleanup.loopexit, label %for.cond
3232

3333
cleanup.loopexit: ; preds = %for.body, %for.cond
34-
; CHECK: [[PHI:%.+]] = phi i32 [ 1, %for.body ], [ 0, %for.cond ]
34+
; CHECK: [[PHI:%.+]] = phi i64 [ 1, %for.body ], [ 0, %for.cond ]
3535
%cleanup.dest.slot.0.ph = phi i1 [ true, %for.body ], [ false, %for.cond ]
3636
br label %cleanup
3737

3838
cleanup: ; preds = %cleanup.loopexit, %entry
39-
; CHECK: = phi i32 [ 0, %entry ], [ [[PHI]], %cleanup.loopexit ]
39+
; CHECK: = phi i64 [ 0, %entry ], [ [[PHI]], %cleanup.loopexit ]
4040
%cleanup.dest.slot.0 = phi i1 [ false, %entry ], [ %cleanup.dest.slot.0.ph, %cleanup.loopexit ]
41-
; CHECK: [[REG:%.+]] = trunc i32 {{%.+}} to i1
41+
; CHECK: [[REG:%.+]] = trunc i64 {{%.+}} to i1
4242
; CHECK: ret i1 [[REG]]
4343
ret i1 %cleanup.dest.slot.0
4444
}
@@ -78,14 +78,14 @@ for.body: ; preds = %for.body.preheader,
7878
br i1 %call, label %cleanup.loopexit, label %for.cond
7979

8080
cleanup.loopexit: ; preds = %for.body, %for.cond
81-
; CHECK: [[PHI:%.+]] = phi i32 [ 1, %for.body ], [ 0, %for.cond ]
81+
; CHECK: [[PHI:%.+]] = phi i64 [ 1, %for.body ], [ 0, %for.cond ]
8282
%cleanup.dest.slot.0.ph = phi i1 [ true, %for.body ], [ false, %for.cond ]
8383
br label %cleanup
8484

8585
cleanup: ; preds = %cleanup.loopexit, %entry
86-
; CHECK: = phi i32 [ 0, %entry ], [ [[PHI]], %cleanup.loopexit ]
86+
; CHECK: = phi i64 [ 0, %entry ], [ [[PHI]], %cleanup.loopexit ]
8787
%cleanup.dest.slot.0 = phi i1 [ false, %entry ], [ %cleanup.dest.slot.0.ph, %cleanup.loopexit ]
88-
; CHECK: [[REG:%.+]] = trunc i32 {{%.+}} to i1
88+
; CHECK: [[REG:%.+]] = trunc i64 {{%.+}} to i1
8989
; CHECK: call void %cont(i1 [[REG]]
9090
tail call void %cont(i1 %cleanup.dest.slot.0)
9191
ret void
@@ -112,17 +112,17 @@ for.body: ; preds = %for.body.preheader,
112112
br i1 %call, label %cleanup.loopexit, label %for.cond
113113

114114
cleanup.loopexit: ; preds = %for.body, %for.cond
115-
; CHECK: [[PHI:%.+]] = phi i32 [ 1, %for.body ], [ 0, %for.cond ]
115+
; CHECK: [[PHI:%.+]] = phi i64 [ 1, %for.body ], [ 0, %for.cond ]
116116
%cleanup.dest.slot.0.ph = phi i1 [ true, %for.body ], [ false, %for.cond ]
117117
br label %cleanup
118118

119119
cleanup: ; preds = %cleanup.loopexit, %entry
120-
; CHECK: = phi i32 [ 0, %entry ], [ [[PHI]], %cleanup.loopexit ]
120+
; CHECK: = phi i64 [ 0, %entry ], [ [[PHI]], %cleanup.loopexit ]
121121
%cleanup.dest.slot.0 = phi i1 [ false, %entry ], [ %cleanup.dest.slot.0.ph, %cleanup.loopexit ]
122-
; CHECK: [[REG:%.+]] = trunc i32 {{%.+}} to i1
122+
; CHECK: [[REG:%.+]] = trunc i64 {{%.+}} to i1
123123
; CHECK: call void %cont(i1 [[REG]]
124124
tail call void %cont(i1 %cleanup.dest.slot.0)
125-
; CHECK: [[REG:%.+]] = trunc i32 {{%.+}} to i1
125+
; CHECK: [[REG:%.+]] = trunc i64 {{%.+}} to i1
126126
; CHECK: ret i1 [[REG]]
127127
ret i1 %cleanup.dest.slot.0
128128
}
@@ -136,7 +136,7 @@ foo:
136136
br label %cleanup
137137

138138
cleanup:
139-
; CHECK: [[REG:%.+]] = trunc i32 {{%.+}} to i1
139+
; CHECK: [[REG:%.+]] = trunc i64 {{%.+}} to i1
140140
; CHECK: ret i1 [[REG]]
141141
%result = phi i1 [ false, %foo ], [ %operand, %entry ]
142142
ret i1 %result
@@ -186,7 +186,7 @@ foo:
186186

187187
; CHECK-LABEL: cleanup
188188
cleanup:
189-
; CHECK: [[REG:%.+]] = trunc i32 {{%.+}} to i1
189+
; CHECK: [[REG:%.+]] = trunc i64 {{%.+}} to i1
190190
; CHECK: ret i1 [[REG]]
191191
%result = phi i1 [ %bar, %foo], [ %operand, %entry ]
192192
ret i1 %result
@@ -198,8 +198,8 @@ declare zeroext i1 @return_i1()
198198
define zeroext i1 @call_test() {
199199
; CHECK: [[REG:%.+]] = call i1
200200
%result = call i1 @return_i1()
201-
; CHECK: [[REG:%.+]] = zext i1 {{%.+}} to i32
202-
; CHECK: [[REG:%.+]] = trunc i32 {{%.+}} to i1
201+
; CHECK: [[REG:%.+]] = zext i1 {{%.+}} to i64
202+
; CHECK: [[REG:%.+]] = trunc i64 {{%.+}} to i1
203203
; CHECK: ret i1 [[REG]]
204204
ret i1 %result
205205
}

0 commit comments

Comments
 (0)
Please sign in to comment.