簡體   English   中英

如何正確訪問 LLVM 數組中的非常量索引?

[英]How to correctly access a non-constant index in an LLVM array?

我一直在嘗試解決 LLVM 中的 arrays,但我無法訪問非常量索引處的元素。 常量索引工作正常。 當我運行我的程序時,它會立即退出。 在我的具體示例中,我嘗試使用 for 循環將 0 到 5 的元素設置為它們各自的值。 這是 LLVM 輸出的內容(禁用優化):

Read function definition:define double @main() {
entry:
  %i = alloca double, align 8
  %test = alloca [100 x double]*, align 8
  store double 0.000000e+00, [100 x double]* %test, align 8
  store double 0.000000e+00, double %i, align 8
  br label %loop

loop:                                             ; preds = %latch, %entry
  %i1 = phi double [ 0.000000e+00, %entry ], [ %nextvar, %latch ]
  %i2 = load double, double %i, align 8
  %cmptmp = fcmp ult double %i2, 5.000000e+00
  %booltmp = uitofp i1 %cmptmp to double
  %loopcond = fcmp one double %booltmp, 0.000000e+00
  br i1 %loopcond, label %body, label %afterloop

body:                                             ; preds = %loop
  %i3 = load double, double %i, align 8
  %casttmp = fptosi double %i3 to i32
  %reftmp = getelementptr [100 x double], [100 x double]* %test, i32 0, i32 %casttmp
  store double 5.000000e+00, double* %reftmp, align 8
  br label %latch

latch:                                            ; preds = %body
  %i4 = load double, double %i, align 8
  %nextvar = fadd double %i4, 1.000000e+00
  store double %nextvar, double %i, align 8
  br label %loop

afterloop:                                        ; preds = %loop
  %reftmp5 = getelementptr [100 x double], [100 x double]* %test, i32 0, i32 0
  %loadtmp = load double, double* %reftmp5, align 8
  %calltmp = call double @print(double %loadtmp)
  ret double %calltmp
}

數組訪問發生的最重要的塊是正文。 這就是代碼的外觀,以幫助解決應該發生的事情:

fun main() {
    mut test: number[100]
    for(i = 0, i < 5) {
        test[i] = 5
    }
    print(test[0])
}

Print 是一個外部 function,經過 100% 測試並且工作正常。 分配之前的打印語句似乎也沒有運行。 如果有人發現任何錯誤,那就太好了:PS,在我的語言中,所有數字都是雙精度數,所以 i 也是雙精度數。 這就是我將其轉換為整數的原因。

編輯:我使用 clang 和 c++ 編譯了相同的代碼,它給出了以下 llvm output:

define dso_local noundef i32 @main() #0 !dbg !207 {
  %1 = alloca i32, align 4
  %2 = alloca [100 x double], align 16
  %3 = alloca double, align 8
  store i32 0, i32* %1, align 4
  call void @llvm.dbg.declare(metadata [100 x double]* %2, metadata !210, metadata !DIExpression()), !dbg !215
  call void @llvm.dbg.declare(metadata double* %3, metadata !216, metadata !DIExpression()), !dbg !218
  store double 0.000000e+00, double* %3, align 8, !dbg !218
  br label %4, !dbg !219

4:                                                ; preds = %13, %0
  %5 = load double, double* %3, align 8, !dbg !220
  %6 = fcmp olt double %5, 5.000000e+00, !dbg !222
  br i1 %6, label %7, label %16, !dbg !223

7:                                                ; preds = %4
  %8 = load double, double* %3, align 8, !dbg !224
  %9 = load double, double* %3, align 8, !dbg !226
  %10 = fptosi double %9 to i32, !dbg !226
  %11 = sext i32 %10 to i64, !dbg !227
  %12 = getelementptr inbounds [100 x double], [100 x double]* %2, i64 0, i64 %11, !dbg !227
  store double %8, double* %12, align 8, !dbg !228
  br label %13, !dbg !229

13:                                               ; preds = %7
  %14 = load double, double* %3, align 8, !dbg !230
  %15 = fadd double %14, 1.000000e+00, !dbg !230
  store double %15, double* %3, align 8, !dbg !230
  br label %4, !dbg !231, !llvm.loop !232

16:                                               ; preds = %4
  %17 = getelementptr inbounds [100 x double], [100 x double]* %2, i64 0, i64 2, !dbg !235
  %18 = load double, double* %17, align 16, !dbg !235
  %19 = call i32 (i8*, ...) @printf(i8* noundef getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), double noundef %18), !dbg !236
  %20 = load i32, i32* %1, align 4, !dbg !237
  ret i32 %20, !dbg !237
}

這看起來與我所擁有的幾乎相同。 我不明白,為什么這不起作用...

Edit2:我已將數組的基本類型更改為 char - i8,然后所有這些都有效。 我很困惑。 我想知道它是否與alignment有關? 在 clang-llvm 上是 16,在我這里是 8

store double 0.000000e+00, [100 x double]* %test, align 8

這看起來打錯了。 %test的類型是[100 x double]** ,而不是[100 x double]*alloca T會給你一個T*類型的指針),在任何情況下,要存儲一個 double 你應該有一個指針鍵入double*

作為一條建議:如果您使用的是 API,您應該在完成創建模塊后調用verifyModule 當您的代碼格式錯誤時,它會告訴您(如果您將代碼生成為文本,然后使用llc進行編譯,它應該會告訴您同樣的情況),並且可以讓您立即發現此類問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM