Generate unsigned ICmp instructions for builtin comparison operators for Char. (#2875)
This commit is contained in:
committed by
SvyatoslavScherbina
parent
a9a8559410
commit
aae53cfda9
+2
@@ -493,7 +493,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
|||||||
fun icmpLe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSLE, arg0, arg1, name)!!
|
fun icmpLe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSLE, arg0, arg1, name)!!
|
||||||
fun icmpNe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntNE, arg0, arg1, name)!!
|
fun icmpNe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntNE, arg0, arg1, name)!!
|
||||||
fun icmpULt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntULT, arg0, arg1, name)!!
|
fun icmpULt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntULT, arg0, arg1, name)!!
|
||||||
|
fun icmpULe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntULE, arg0, arg1, name)!!
|
||||||
fun icmpUGt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntUGT, arg0, arg1, name)!!
|
fun icmpUGt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntUGT, arg0, arg1, name)!!
|
||||||
|
fun icmpUGe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntUGE, arg0, arg1, name)!!
|
||||||
|
|
||||||
/* floating-point comparisons */
|
/* floating-point comparisons */
|
||||||
fun fcmpEq(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOEQ, arg0, arg1, name)!!
|
fun fcmpEq(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOEQ, arg0, arg1, name)!!
|
||||||
|
|||||||
+39
-19
@@ -2116,26 +2116,46 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
|
|
||||||
with(functionGenerationContext) {
|
with(functionGenerationContext) {
|
||||||
val functionSymbol = function.symbol
|
val functionSymbol = function.symbol
|
||||||
return when {
|
return when (functionSymbol) {
|
||||||
functionSymbol == ib.eqeqeqSymbol -> icmpEq(args[0], args[1])
|
ib.eqeqeqSymbol -> icmpEq(args[0], args[1])
|
||||||
functionSymbol == ib.booleanNotSymbol -> icmpNe(args[0], kTrue)
|
ib.booleanNotSymbol -> icmpNe(args[0], kTrue)
|
||||||
functionSymbol.isComparisonFunction(ib.greaterFunByOperandType) -> {
|
else -> {
|
||||||
if (args[0].type.isFloatingPoint()) fcmpGt(args[0], args[1])
|
val isFloatingPoint = args[0].type.isFloatingPoint()
|
||||||
else icmpGt(args[0], args[1])
|
// LLVM does not distinguish between signed/unsigned integers, so we must check
|
||||||
|
// the parameter type.
|
||||||
|
val shouldUseUnsignedComparison = function.valueParameters[0].type.isChar()
|
||||||
|
when {
|
||||||
|
functionSymbol.isComparisonFunction(ib.greaterFunByOperandType) -> {
|
||||||
|
when {
|
||||||
|
isFloatingPoint -> fcmpGt(args[0], args[1])
|
||||||
|
shouldUseUnsignedComparison -> icmpUGt(args[0], args[1])
|
||||||
|
else -> icmpGt(args[0], args[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
functionSymbol.isComparisonFunction(ib.greaterOrEqualFunByOperandType) -> {
|
||||||
|
when {
|
||||||
|
isFloatingPoint -> fcmpGe(args[0], args[1])
|
||||||
|
shouldUseUnsignedComparison -> icmpUGe(args[0], args[1])
|
||||||
|
else -> icmpGe(args[0], args[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
functionSymbol.isComparisonFunction(ib.lessFunByOperandType) -> {
|
||||||
|
when {
|
||||||
|
isFloatingPoint -> fcmpLt(args[0], args[1])
|
||||||
|
shouldUseUnsignedComparison -> icmpULt(args[0], args[1])
|
||||||
|
else -> icmpLt(args[0], args[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
functionSymbol.isComparisonFunction(ib.lessOrEqualFunByOperandType) -> {
|
||||||
|
when {
|
||||||
|
isFloatingPoint -> fcmpLe(args[0], args[1])
|
||||||
|
shouldUseUnsignedComparison -> icmpULe(args[0], args[1])
|
||||||
|
else -> icmpLe(args[0], args[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> TODO(function.name.toString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
functionSymbol.isComparisonFunction(ib.greaterOrEqualFunByOperandType) -> {
|
|
||||||
if (args[0].type.isFloatingPoint()) fcmpGe(args[0], args[1])
|
|
||||||
else icmpGe(args[0], args[1])
|
|
||||||
}
|
|
||||||
functionSymbol.isComparisonFunction(ib.lessFunByOperandType) -> {
|
|
||||||
if (args[0].type.isFloatingPoint()) fcmpLt(args[0], args[1])
|
|
||||||
else icmpLt(args[0], args[1])
|
|
||||||
}
|
|
||||||
functionSymbol.isComparisonFunction(ib.lessOrEqualFunByOperandType) -> {
|
|
||||||
if (args[0].type.isFloatingPoint()) fcmpLe(args[0], args[1])
|
|
||||||
else icmpLe(args[0], args[1])
|
|
||||||
}
|
|
||||||
else -> TODO(function.name.toString())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user