Loading llvm/lib/Target/CBackend/CBackend.cpp +46 −20 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ namespace { void writeOperand(Value *Operand); void writeOperandRaw(Value *Operand); void writeInstComputationInline(Instruction &I); void writeOperandInternal(Value *Operand); void writeOperandWithCast(Value* Operand, unsigned Opcode); void writeOperandWithCast(Value* Operand, const ICmpInst &I); Loading Loading @@ -1217,12 +1218,32 @@ std::string CWriter::GetValueName(const Value *Operand) { return Name; } /// writeInstComputationInline - Emit the computation for the specified /// instruction inline, with no destination provided. void CWriter::writeInstComputationInline(Instruction &I) { // If this is a non-trivial bool computation, make sure to truncate down to // a 1 bit value. This is important because we want "add i1 x, y" to return // "0" when x and y are true, not "2" for example. bool NeedBoolTrunc = false; if (I.getType() == Type::Int1Ty && !isa<ICmpInst>(I) && !isa<FCmpInst>(I)) NeedBoolTrunc = true; if (NeedBoolTrunc) Out << "(("; visit(I); if (NeedBoolTrunc) Out << ")&1)"; } void CWriter::writeOperandInternal(Value *Operand) { if (Instruction *I = dyn_cast<Instruction>(Operand)) if (isInlinableInst(*I) && !isDirectAlloca(I)) { // Should we inline this instruction to build a tree? if (isInlinableInst(*I) && !isDirectAlloca(I)) { Out << '('; visit(*I); writeInstComputationInline(*I); Out << ')'; return; } Loading Loading @@ -2146,12 +2167,12 @@ void CWriter::printBasicBlock(BasicBlock *BB) { outputLValue(II); else Out << " "; visit(*II); writeInstComputationInline(*II); Out << ";\n"; } } // Don't emit prefix or suffix for the terminator... // Don't emit prefix or suffix for the terminator. visit(*BB->getTerminator()); } Loading Loading @@ -2475,21 +2496,27 @@ static const char * getFloatBitCastField(const Type *Ty) { void CWriter::visitCastInst(CastInst &I) { const Type *DstTy = I.getType(); const Type *SrcTy = I.getOperand(0)->getType(); Out << '('; if (isFPIntBitCast(I)) { Out << '('; // These int<->float and long<->double casts need to be handled specially Out << GetValueName(&I) << "__BITCAST_TEMPORARY." << getFloatBitCastField(I.getOperand(0)->getType()) << " = "; writeOperand(I.getOperand(0)); Out << ", " << GetValueName(&I) << "__BITCAST_TEMPORARY." << getFloatBitCastField(I.getType()); } else { Out << ')'; return; } Out << '('; printCast(I.getOpcode(), SrcTy, DstTy); if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) { // Make sure we really get a sext from bool by subtracing the bool from 0 // Make a sext from i1 work by subtracting the i1 from 0 (an int). if (SrcTy == Type::Int1Ty && I.getOpcode() == Instruction::SExt) Out << "0-"; } writeOperand(I.getOperand(0)); if (DstTy == Type::Int1Ty && (I.getOpcode() == Instruction::Trunc || I.getOpcode() == Instruction::FPToUI || Loading @@ -2498,7 +2525,6 @@ void CWriter::visitCastInst(CastInst &I) { // Make sure we really get a trunc to bool by anding the operand with 1 Out << "&1u"; } } Out << ')'; } Loading llvm/test/CodeGen/CBackend/2008-05-31-BoolOverflow.ll 0 → 100644 +14 −0 Original line number Diff line number Diff line ; RUN: llvm-as < %s | llc -march=c | grep {llvm_cbe_t.*&1} define i32 @test(i32 %r) { %s = icmp eq i32 %r, 0 %t = add i1 %s, %s %u = zext i1 %t to i32 br i1 %t, label %A, label %B A: ret i32 %u B: %v = select i1 %t, i32 %r, i32 %u ret i32 %v } Loading
llvm/lib/Target/CBackend/CBackend.cpp +46 −20 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ namespace { void writeOperand(Value *Operand); void writeOperandRaw(Value *Operand); void writeInstComputationInline(Instruction &I); void writeOperandInternal(Value *Operand); void writeOperandWithCast(Value* Operand, unsigned Opcode); void writeOperandWithCast(Value* Operand, const ICmpInst &I); Loading Loading @@ -1217,12 +1218,32 @@ std::string CWriter::GetValueName(const Value *Operand) { return Name; } /// writeInstComputationInline - Emit the computation for the specified /// instruction inline, with no destination provided. void CWriter::writeInstComputationInline(Instruction &I) { // If this is a non-trivial bool computation, make sure to truncate down to // a 1 bit value. This is important because we want "add i1 x, y" to return // "0" when x and y are true, not "2" for example. bool NeedBoolTrunc = false; if (I.getType() == Type::Int1Ty && !isa<ICmpInst>(I) && !isa<FCmpInst>(I)) NeedBoolTrunc = true; if (NeedBoolTrunc) Out << "(("; visit(I); if (NeedBoolTrunc) Out << ")&1)"; } void CWriter::writeOperandInternal(Value *Operand) { if (Instruction *I = dyn_cast<Instruction>(Operand)) if (isInlinableInst(*I) && !isDirectAlloca(I)) { // Should we inline this instruction to build a tree? if (isInlinableInst(*I) && !isDirectAlloca(I)) { Out << '('; visit(*I); writeInstComputationInline(*I); Out << ')'; return; } Loading Loading @@ -2146,12 +2167,12 @@ void CWriter::printBasicBlock(BasicBlock *BB) { outputLValue(II); else Out << " "; visit(*II); writeInstComputationInline(*II); Out << ";\n"; } } // Don't emit prefix or suffix for the terminator... // Don't emit prefix or suffix for the terminator. visit(*BB->getTerminator()); } Loading Loading @@ -2475,21 +2496,27 @@ static const char * getFloatBitCastField(const Type *Ty) { void CWriter::visitCastInst(CastInst &I) { const Type *DstTy = I.getType(); const Type *SrcTy = I.getOperand(0)->getType(); Out << '('; if (isFPIntBitCast(I)) { Out << '('; // These int<->float and long<->double casts need to be handled specially Out << GetValueName(&I) << "__BITCAST_TEMPORARY." << getFloatBitCastField(I.getOperand(0)->getType()) << " = "; writeOperand(I.getOperand(0)); Out << ", " << GetValueName(&I) << "__BITCAST_TEMPORARY." << getFloatBitCastField(I.getType()); } else { Out << ')'; return; } Out << '('; printCast(I.getOpcode(), SrcTy, DstTy); if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) { // Make sure we really get a sext from bool by subtracing the bool from 0 // Make a sext from i1 work by subtracting the i1 from 0 (an int). if (SrcTy == Type::Int1Ty && I.getOpcode() == Instruction::SExt) Out << "0-"; } writeOperand(I.getOperand(0)); if (DstTy == Type::Int1Ty && (I.getOpcode() == Instruction::Trunc || I.getOpcode() == Instruction::FPToUI || Loading @@ -2498,7 +2525,6 @@ void CWriter::visitCastInst(CastInst &I) { // Make sure we really get a trunc to bool by anding the operand with 1 Out << "&1u"; } } Out << ')'; } Loading
llvm/test/CodeGen/CBackend/2008-05-31-BoolOverflow.ll 0 → 100644 +14 −0 Original line number Diff line number Diff line ; RUN: llvm-as < %s | llc -march=c | grep {llvm_cbe_t.*&1} define i32 @test(i32 %r) { %s = icmp eq i32 %r, 0 %t = add i1 %s, %s %u = zext i1 %t to i32 br i1 %t, label %A, label %B A: ret i32 %u B: %v = select i1 %t, i32 %r, i32 %u ret i32 %v }