@@ -155,6 +155,7 @@ namespace {
155
155
156
156
void writeOperand (Value *Operand);
157
157
void writeOperandRaw (Value *Operand);
158
+ void writeInstComputationInline (Instruction &I);
158
159
void writeOperandInternal (Value *Operand);
159
160
void writeOperandWithCast (Value* Operand, unsigned Opcode);
160
161
void writeOperandWithCast (Value* Operand, const ICmpInst &I);
@@ -1217,12 +1218,32 @@ std::string CWriter::GetValueName(const Value *Operand) {
1217
1218
return Name;
1218
1219
}
1219
1220
1221
+ // / writeInstComputationInline - Emit the computation for the specified
1222
+ // / instruction inline, with no destination provided.
1223
+ void CWriter::writeInstComputationInline (Instruction &I) {
1224
+ // If this is a non-trivial bool computation, make sure to truncate down to
1225
+ // a 1 bit value. This is important because we want "add i1 x, y" to return
1226
+ // "0" when x and y are true, not "2" for example.
1227
+ bool NeedBoolTrunc = false ;
1228
+ if (I.getType () == Type::Int1Ty && !isa<ICmpInst>(I) && !isa<FCmpInst>(I))
1229
+ NeedBoolTrunc = true ;
1230
+
1231
+ if (NeedBoolTrunc)
1232
+ Out << " ((" ;
1233
+
1234
+ visit (I);
1235
+
1236
+ if (NeedBoolTrunc)
1237
+ Out << " )&1)" ;
1238
+ }
1239
+
1240
+
1220
1241
void CWriter::writeOperandInternal (Value *Operand) {
1221
1242
if (Instruction *I = dyn_cast<Instruction>(Operand))
1243
+ // Should we inline this instruction to build a tree?
1222
1244
if (isInlinableInst (*I) && !isDirectAlloca (I)) {
1223
- // Should we inline this instruction to build a tree?
1224
1245
Out << ' (' ;
1225
- visit (*I);
1246
+ writeInstComputationInline (*I);
1226
1247
Out << ' )' ;
1227
1248
return ;
1228
1249
}
@@ -2146,12 +2167,12 @@ void CWriter::printBasicBlock(BasicBlock *BB) {
2146
2167
outputLValue (II);
2147
2168
else
2148
2169
Out << " " ;
2149
- visit (*II);
2170
+ writeInstComputationInline (*II);
2150
2171
Out << " ;\n " ;
2151
2172
}
2152
2173
}
2153
2174
2154
- // Don't emit prefix or suffix for the terminator...
2175
+ // Don't emit prefix or suffix for the terminator.
2155
2176
visit (*BB->getTerminator ());
2156
2177
}
2157
2178
@@ -2475,29 +2496,34 @@ static const char * getFloatBitCastField(const Type *Ty) {
2475
2496
void CWriter::visitCastInst (CastInst &I) {
2476
2497
const Type *DstTy = I.getType ();
2477
2498
const Type *SrcTy = I.getOperand (0 )->getType ();
2478
- Out << ' (' ;
2479
2499
if (isFPIntBitCast (I)) {
2500
+ Out << ' (' ;
2480
2501
// These int<->float and long<->double casts need to be handled specially
2481
2502
Out << GetValueName (&I) << " __BITCAST_TEMPORARY."
2482
2503
<< getFloatBitCastField (I.getOperand (0 )->getType ()) << " = " ;
2483
2504
writeOperand (I.getOperand (0 ));
2484
2505
Out << " , " << GetValueName (&I) << " __BITCAST_TEMPORARY."
2485
2506
<< getFloatBitCastField (I.getType ());
2486
- } else {
2487
- printCast (I.getOpcode (), SrcTy, DstTy);
2488
- if (I.getOpcode () == Instruction::SExt && SrcTy == Type::Int1Ty) {
2489
- // Make sure we really get a sext from bool by subtracing the bool from 0
2490
- Out << " 0-" ;
2491
- }
2492
- writeOperand (I.getOperand (0 ));
2493
- if (DstTy == Type::Int1Ty &&
2494
- (I.getOpcode () == Instruction::Trunc ||
2495
- I.getOpcode () == Instruction::FPToUI ||
2496
- I.getOpcode () == Instruction::FPToSI ||
2497
- I.getOpcode () == Instruction::PtrToInt)) {
2498
- // Make sure we really get a trunc to bool by anding the operand with 1
2499
- Out << " &1u" ;
2500
- }
2507
+ Out << ' )' ;
2508
+ return ;
2509
+ }
2510
+
2511
+ Out << ' (' ;
2512
+ printCast (I.getOpcode (), SrcTy, DstTy);
2513
+
2514
+ // Make a sext from i1 work by subtracting the i1 from 0 (an int).
2515
+ if (SrcTy == Type::Int1Ty && I.getOpcode () == Instruction::SExt)
2516
+ Out << " 0-" ;
2517
+
2518
+ writeOperand (I.getOperand (0 ));
2519
+
2520
+ if (DstTy == Type::Int1Ty &&
2521
+ (I.getOpcode () == Instruction::Trunc ||
2522
+ I.getOpcode () == Instruction::FPToUI ||
2523
+ I.getOpcode () == Instruction::FPToSI ||
2524
+ I.getOpcode () == Instruction::PtrToInt)) {
2525
+ // Make sure we really get a trunc to bool by anding the operand with 1
2526
+ Out << " &1u" ;
2501
2527
}
2502
2528
Out << ' )' ;
2503
2529
}
0 commit comments