std::vector<llvm::Type *> ArgElemTypes;
std::vector<llvm::Value*> Args;
llvm::BitVector ResultTypeRequiresCast;
+ llvm::BitVector ResultRegIsFlagReg;
// Keep track of inout constraints.
std::string InOutConstraints;
ResultRegQualTys.push_back(QTy);
ResultRegDests.push_back(Dest);
+ bool IsFlagReg = llvm::StringRef(OutputConstraint).startswith("{@cc");
+ ResultRegIsFlagReg.push_back(IsFlagReg);
+
llvm::Type *Ty = ConvertTypeForMem(QTy);
const bool RequiresCast = Info.allowsRegister() &&
(getTargetHooks().isScalarizableAsmOperand(*this, Ty) ||
// ResultRegDests can be also populated by addReturnRegisterOutputs() above,
// in which case its size may grow.
assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+ assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
llvm::Value *Tmp = RegResults[i];
llvm::Type *TruncTy = ResultTruncRegTypes[i];
+ if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+ // Target must guarantee the Value `Tmp` here is lowered to a boolean
+ // value.
+ llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+ llvm::Value *IsBooleanValue =
+ Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+ llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+ Builder.CreateCall(FnAssume, IsBooleanValue);
+ }
+
// If the result type of the LLVM IR asm doesn't match the result type of
// the expression, do the conversion.
if (ResultRegTypes[i] != ResultTruncRegTypes[i]) {
: "cx");
return b;
}
+
+int test_assume_boolean_flag(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_assume_boolean_flag
+ //CHECK: %0 = tail call { i32, i32 } asm "cmp $2,$1", "={@cca},={@ccae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr)
+ //CHECK: [[RES1:%.*]] = extractvalue { i32, i32 } %0, 0
+ //CHECK: [[RES2:%.*]] = extractvalue { i32, i32 } %0, 1
+ //CHECK: %1 = icmp ult i32 [[RES1]], 2
+ //CHECK: tail call void @llvm.assume(i1 %1)
+ //CHECK: %2 = icmp ult i32 [[RES2]], 2
+ //CHECK: tail call void @llvm.assume(i1 %2)
+ int x,y;
+ asm("cmp %2,%1"
+ : "=@cca"(x), "=@ccae"(y), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}