मुझे LLVM IR के भीतर से printf() फ़ंक्शन का उपयोग करने में समस्या है। मैं सिर्फ एक फ्लोट के मूल्य को प्रिंट करना चाहता हूं लेकिन मुझे सिर्फ 0.000000 मिलता है। यह पूर्णांक और तार के लिए ठीक काम करता है लेकिन तैरता नहीं है।

सरल उदाहरण:

@.fstr = private unnamed_addr constant [4 x i8] c"%f\0A\00"

declare i32 @printf(i8*, ...)

define i32 @main() {
    %1 = getelementptr [4 x i8],[4 x i8]* @.fstr, i64 0, i64 0
    %2 = call i32 @printf(i8* %1, double 2.0)
    %3 = call i32 @printf(i8* %1, float 2.0)
    ret i32 0
}

जब मैं इसे एलएलवीएम के साथ संकलित करता हूं और इसे क्लैंग से जोड़ता हूं और निष्पादन योग्य चलाता हूं तो मुझे मिलता है:

0.000000
0.000000

वही परिणाम अगर मैं .bc फ़ाइल को lli के साथ चलाता हूं। मैंने यह प्रासंगिक पोस्ट पढ़ा है, लेकिन जैसा कि आप देखते हैं कि यह युगल के साथ भी काम नहीं करता है।

0
ZeDragon 19 अक्टूबर 2021, 21:59

1 उत्तर

सबसे बढ़िया उत्तर

lli-10 का उपयोग करके अपना उदाहरण चलाने पर मुझे एक मिलता है @printf' defined with type 'i32 (i8*, ...)*' but expected 'i32 (i8*, double)*' त्रुटि एक सफल कॉल के बजाय जो 0.000000 प्रिंट करती है।

यह त्रुटि अपेक्षित है, और इसका कारण यहां बताया गया है। ए>। पोस्ट से प्रासंगिक बिट है

... यदि कॉल के सामने का प्रकार a . है फ़ंक्शन पॉइंटर प्रकार, फिर इसका उपयोग चीज़ के प्रकार के रूप में किया जाता है कहा जाता है, जबकि यदि ऐसा नहीं है, तो इसका उपयोग वापसी प्रकार के रूप में किया जाता है, और निर्देश पर मौजूद तर्कों से कॉल के प्रकार का अनुमान लगाया जाता है।

इसलिए एलएलवीएम पहली कॉल में printf के प्रकार का अनुमान लगाता है i32 (i8*, double)* लेकिन बाद में पता चलता है कि इसे i32 (i8*, ...)* घोषित किया गया है। इसे ठीक करने के लिए बस कॉल्स को ठीक से एनोटेट करें,

%2 = call i32 (i8*, ...) @printf(i8* %1, double 2.0)
%3 = call i32 (i8*, ...) @printf(i8* %1, float 2.0)

आप जल्दी से देखेंगे कि दूसरा printf कॉल अभी भी 0.000000 प्रिंट करता है। देखें क्यों

0
droptop 21 अक्टूबर 2021, 01:19