LLVM IR:<n x =“”i1 =“”>向量指令排序导致不同的结果

时间:2016-08-14 21:46:17

标签: llvm code-generation llvm-ir

我一直在使用LLVM作为我的编译器的后端(我没有使用LLVM库,而是我自己生成必要的IR,原因有很多)。目前,我正在实施矢量操作。向量的比较发出布尔值<N x i1>的向量,这些都引起了我的问题。

要访问向量元素,我一直在使用extractelementinsertelement但是,当我以不同的顺序执行这些指令时,我会遇到一些奇怪的行为。下面的代码示例具有相同的说明,并且在逻辑上应该相同。版本1输出BAA,而版本2输出BAB。版本2是逻辑上正确的版本但我无法弄清楚为什么版本1输出错误的版本但具有完全相同的指令,只是以不同的顺序。

编辑: 解决此问题的解决方法是将IR传递给opt -mem2reg,然后编译bitcode。这是好的,但对调试无用,因此解决我的问题。

版本1

; Version 1 - Generated by my naïve SSA generator
; Outputs: BAA (incorrect)
declare i32 @putchar(i32)

define void @main() {
entry:
    %0 = alloca <8 x i1>, align 8 ; v
    store <8 x i1> zeroinitializer, <8 x i1>* %0
    %1 = alloca <8 x i1>, align 8
    store <8 x i1> zeroinitializer, <8 x i1>* %1
    %2 = load <8 x i1>, <8 x i1>* %1, align 8
    %3 = insertelement <8 x i1> %2, i1 true, i64 0
    %4 = insertelement <8 x i1> %3, i1 false, i64 1
    %5 = insertelement <8 x i1> %4, i1 true, i64 2
    %6 = insertelement <8 x i1> %5, i1 false, i64 3
    %7 = insertelement <8 x i1> %6, i1 true, i64 4
    %8 = insertelement <8 x i1> %7, i1 false, i64 5
    %9 = insertelement <8 x i1> %8, i1 true, i64 6
    %10 = insertelement <8 x i1> %9, i1 false, i64 7
    store <8 x i1> %10, <8 x i1>* %0

    %11 = load <8 x i1>, <8 x i1>* %0, align 8
    %12 = extractelement <8 x i1> %11, i64 0
    %13 = zext i1 %12 to i32
    %14 = add i32 %13, 65 ; + 'A'
    %15 = call i32 @putchar(i32 %14)

    %16 = load <8 x i1>, <8 x i1>* %0, align 8
    %17 = extractelement <8 x i1> %16, i64 1
    %18 = zext i1 %17 to i32
    %19 = add i32 %18, 65 ; + 'A'
    %20 = call i32 @putchar(i32 %19)

    %21 = load <8 x i1>, <8 x i1>* %0, align 8
    %22 = extractelement <8 x i1> %21, i64 2
    %23 = zext i1 %22 to i32
    %24 = add i32 %23, 65 ; + 'A'
    %25 = call i32 @putchar(i32 %24)

    %26 = call i32 @putchar(i32 10) ; \n

    ret void
}

第2版

; Version 2 - Manually modified version of Version 1
; Outputs: BAB (correct)
declare i32 @putchar(i32)

define void @main() {
entry:
    %0 = alloca <8 x i1>, align 8 ; v
    store <8 x i1> zeroinitializer, <8 x i1>* %0
    %1 = alloca <8 x i1>, align 8
    store <8 x i1> zeroinitializer, <8 x i1>* %1
    %2 = load <8 x i1>, <8 x i1>* %1, align 8
    %3 = insertelement <8 x i1> %2, i1 true, i64 0
    %4 = insertelement <8 x i1> %3, i1 false, i64 1
    %5 = insertelement <8 x i1> %4, i1 true, i64 2
    %6 = insertelement <8 x i1> %5, i1 false, i64 3
    %7 = insertelement <8 x i1> %6, i1 true, i64 4
    %8 = insertelement <8 x i1> %7, i1 false, i64 5
    %9 = insertelement <8 x i1> %8, i1 true, i64 6
    %10 = insertelement <8 x i1> %9, i1 false, i64 7
    store <8 x i1> %10, <8 x i1>* %0

    %11 = load <8 x i1>, <8 x i1>* %0, align 8
    %12 = load <8 x i1>, <8 x i1>* %0, align 8
    %13 = load <8 x i1>, <8 x i1>* %0, align 8

    %14 = extractelement <8 x i1> %11, i64 0
    %15 = extractelement <8 x i1> %12, i64 1
    %16 = extractelement <8 x i1> %13, i64 2

    %17 = zext i1 %14 to i32
    %18 = zext i1 %15 to i32
    %19 = zext i1 %16 to i32

    %20 = add i32 %17, 65 ; + 'A'
    %21 = add i32 %18, 65 ; + 'A'
    %22 = add i32 %19, 65 ; + 'A'

    %23 = call i32 @putchar(i32 %20)
    %24 = call i32 @putchar(i32 %21)
    %25 = call i32 @putchar(i32 %22)

    %26 = call i32 @putchar(i32 10) ; \n

    ret void
}

0 个答案:

没有答案