@@ -1357,8 +1357,7 @@ llvm::Value *LLVMBuildUtils::createStringComparison(LLVMRegister *arg1, LLVMRegi
1357
1357
// Explicitly cast to string
1358
1358
llvm::Value *string1 = castValue (arg1, Compiler::StaticType::String);
1359
1359
llvm::Value *string2 = castValue (arg2, Compiler::StaticType::String);
1360
- llvm::Value *cmp = m_builder.CreateCall (caseSensitive ? m_functions.resolve_string_compare_case_sensitive () : m_functions.resolve_string_compare_case_insensitive (), { string1, string2 });
1361
- llvm::Value *result = m_builder.CreateICmpEQ (cmp, m_builder.getInt32 (0 ));
1360
+ llvm::Value *result = createStringsEqualComparison (string1, string2, caseSensitive);
1362
1361
m_builder.CreateBr (nextBlock);
1363
1362
1364
1363
llvm::BasicBlock *compareBlockNext = m_builder.GetInsertBlock ();
@@ -1846,13 +1845,13 @@ llvm::Value *LLVMBuildUtils::createStringAndStringComparison(LLVMRegister *arg1,
1846
1845
llvm::Value *value1 = castValue (arg1, Compiler::StaticType::String);
1847
1846
llvm::Value *value2 = castValue (arg2, Compiler::StaticType::String);
1848
1847
1848
+ if (type == Comparison::EQ)
1849
+ return createStringsEqualComparison (value1, value2, false );
1850
+
1849
1851
llvm::Value *cmp = m_builder.CreateCall (m_functions.resolve_string_compare_case_insensitive (), { value1, value2 });
1850
1852
llvm::Value *zero = llvm::ConstantInt::get (m_builder.getInt32Ty (), 0 , true );
1851
1853
1852
1854
switch (type) {
1853
- case Comparison::EQ:
1854
- return m_builder.CreateICmpEQ (cmp, zero);
1855
-
1856
1855
case Comparison::GT:
1857
1856
return m_builder.CreateICmpSGT (cmp, zero);
1858
1857
@@ -1970,37 +1969,39 @@ llvm::Value *LLVMBuildUtils::createNumberAndStringComparison(LLVMRegister *arg1,
1970
1969
m_builder.SetInsertPoint (stringBlock);
1971
1970
llvm::Value *stringValue = addStringAlloca ();
1972
1971
m_builder.CreateCall (m_functions.resolve_value_doubleToStringPtr (), { value1, stringValue });
1973
- llvm::Value *cmp = m_builder.CreateCall (m_functions.resolve_string_compare_case_insensitive (), { stringValue, value2 });
1974
1972
1975
- llvm::Value *zero = llvm::ConstantInt::get (m_builder.getInt32Ty (), 0 , true );
1976
1973
llvm::Value *stringCmp;
1977
1974
1978
- switch (type) {
1979
- case Comparison::EQ:
1980
- stringCmp = m_builder.CreateICmpEQ (cmp, zero);
1981
- break ;
1975
+ if (type == Comparison::EQ)
1976
+ stringCmp = createStringsEqualComparison (stringValue, value2, false );
1977
+ else {
1978
+ llvm::Value *cmp = m_builder.CreateCall (m_functions.resolve_string_compare_case_insensitive (), { stringValue, value2 });
1979
+ llvm::Value *zero = llvm::ConstantInt::get (m_builder.getInt32Ty (), 0 , true );
1982
1980
1983
- case Comparison::GT:
1984
- stringCmp = m_builder.CreateICmpSGT (cmp, zero);
1985
- break ;
1981
+ switch (type) {
1982
+ case Comparison::GT:
1983
+ stringCmp = m_builder.CreateICmpSGT (cmp, zero);
1984
+ break ;
1986
1985
1987
- case Comparison::LT:
1988
- stringCmp = m_builder.CreateICmpSLT (cmp, zero);
1989
- break ;
1986
+ case Comparison::LT:
1987
+ stringCmp = m_builder.CreateICmpSLT (cmp, zero);
1988
+ break ;
1990
1989
1991
- default :
1992
- assert (false );
1993
- return nullptr ;
1990
+ default :
1991
+ assert (false );
1992
+ return nullptr ;
1993
+ }
1994
1994
}
1995
1995
1996
+ llvm::BasicBlock *stringBlockNext = m_builder.GetInsertBlock ();
1996
1997
m_builder.CreateBr (nextBlock);
1997
1998
1998
1999
// Merge the results
1999
2000
m_builder.SetInsertPoint (nextBlock);
2000
2001
2001
2002
llvm::PHINode *result = m_builder.CreatePHI (m_builder.getInt1Ty (), 2 );
2002
2003
result->addIncoming (numberCmp, numberBlock);
2003
- result->addIncoming (stringCmp, stringBlock );
2004
+ result->addIncoming (stringCmp, stringBlockNext );
2004
2005
2005
2006
return result;
2006
2007
}
@@ -2051,42 +2052,76 @@ llvm::Value *LLVMBuildUtils::createBoolAndStringComparison(LLVMRegister *arg1, L
2051
2052
// String comparison
2052
2053
m_builder.SetInsertPoint (stringBlock);
2053
2054
llvm::Value *stringValue = m_builder.CreateCall (m_functions.resolve_value_boolToStringPtr (), { value1 });
2054
- llvm::Value *cmp = m_builder.CreateCall (m_functions.resolve_string_compare_case_insensitive (), { stringValue, value2 });
2055
- // NOTE: Do not free the string!
2056
2055
2057
- llvm::Value *zero = llvm::ConstantInt::get (m_builder.getInt32Ty (), 0 , true );
2058
2056
llvm::Value *stringCmp;
2059
2057
2060
- switch (type) {
2061
- case Comparison::EQ:
2062
- stringCmp = m_builder.CreateICmpEQ (cmp, zero);
2063
- break ;
2058
+ if (type == Comparison::EQ)
2059
+ stringCmp = createStringsEqualComparison (stringValue, value2, false );
2060
+ else {
2061
+ llvm::Value *cmp = m_builder.CreateCall (m_functions.resolve_string_compare_case_insensitive (), { stringValue, value2 });
2062
+ llvm::Value *zero = llvm::ConstantInt::get (m_builder.getInt32Ty (), 0 , true );
2064
2063
2065
- case Comparison::GT:
2066
- stringCmp = m_builder.CreateICmpSGT (cmp, zero);
2067
- break ;
2064
+ switch (type) {
2065
+ case Comparison::GT:
2066
+ stringCmp = m_builder.CreateICmpSGT (cmp, zero);
2067
+ break ;
2068
2068
2069
- case Comparison::LT:
2070
- stringCmp = m_builder.CreateICmpSLT (cmp, zero);
2071
- break ;
2069
+ case Comparison::LT:
2070
+ stringCmp = m_builder.CreateICmpSLT (cmp, zero);
2071
+ break ;
2072
2072
2073
- default :
2074
- assert (false );
2075
- return nullptr ;
2073
+ default :
2074
+ assert (false );
2075
+ return nullptr ;
2076
+ }
2076
2077
}
2077
2078
2079
+ llvm::BasicBlock *stringBlockNext = m_builder.GetInsertBlock ();
2078
2080
m_builder.CreateBr (nextBlock);
2079
2081
2080
2082
// Merge the results
2081
2083
m_builder.SetInsertPoint (nextBlock);
2082
2084
2083
2085
llvm::PHINode *result = m_builder.CreatePHI (m_builder.getInt1Ty (), 2 );
2084
2086
result->addIncoming (numberCmp, numberBlock);
2085
- result->addIncoming (stringCmp, stringBlock );
2087
+ result->addIncoming (stringCmp, stringBlockNext );
2086
2088
2087
2089
return result;
2088
2090
}
2089
2091
2092
+ llvm::Value *LLVMBuildUtils::createStringsEqualComparison (llvm::Value *stringPtr1, llvm::Value *stringPtr2, bool caseSensitive)
2093
+ {
2094
+ llvm::Value *sizePtr1 = m_builder.CreateStructGEP (m_stringPtrType, stringPtr1, 1 );
2095
+ llvm::Value *size1 = m_builder.CreateLoad (m_builder.getInt64Ty (), sizePtr1);
2096
+
2097
+ llvm::Value *sizePtr2 = m_builder.CreateStructGEP (m_stringPtrType, stringPtr2, 1 );
2098
+ llvm::Value *size2 = m_builder.CreateLoad (m_builder.getInt64Ty (), sizePtr2);
2099
+
2100
+ llvm::Value *sameSize = m_builder.CreateICmpEQ (size1, size2);
2101
+
2102
+ llvm::BasicBlock *compareBlock = llvm::BasicBlock::Create (m_llvmCtx, " stringsEqual.compare" , m_function);
2103
+ llvm::BasicBlock *differentBlock = llvm::BasicBlock::Create (m_llvmCtx, " stringsEqual.different" , m_function);
2104
+ llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (m_llvmCtx, " stringsEqual.next" , m_function);
2105
+ m_builder.CreateCondBr (sameSize, compareBlock, differentBlock);
2106
+
2107
+ m_builder.SetInsertPoint (compareBlock);
2108
+ llvm::FunctionCallee func = caseSensitive ? m_functions.resolve_string_compare_case_sensitive () : m_functions.resolve_string_compare_case_insensitive ();
2109
+ llvm::Value *cmp = m_builder.CreateCall (func, { stringPtr1, stringPtr2 });
2110
+ llvm::Value *result = m_builder.CreateICmpEQ (cmp, m_builder.getInt32 (0 ));
2111
+ m_builder.CreateBr (nextBlock);
2112
+
2113
+ m_builder.SetInsertPoint (differentBlock);
2114
+ m_builder.CreateBr (nextBlock);
2115
+
2116
+ m_builder.SetInsertPoint (nextBlock);
2117
+
2118
+ llvm::PHINode *phi = m_builder.CreatePHI (m_builder.getInt1Ty (), 2 , " stringsEqual" );
2119
+ phi->addIncoming (result, compareBlock);
2120
+ phi->addIncoming (m_builder.getInt1 (false ), differentBlock);
2121
+
2122
+ return phi;
2123
+ }
2124
+
2090
2125
llvm::Value *LLVMBuildUtils::getVariablePtr (llvm::Value *targetVariables, Variable *variable)
2091
2126
{
2092
2127
if (!m_target->isStage () && variable->target () == m_target) {
0 commit comments