AliveToolkit / alive2

Automatic verification of LLVM optimizations
MIT License
766 stars 97 forks source link

possible issue with new asm-mode support for non-byte-sized loads #1052

Closed regehr closed 3 months ago

regehr commented 3 months ago

here's src:

@var = external global i18

define i18 @f() {
  %1 = load i18, ptr @var, align 4
  ret i18 %1
}

the aarch64 backend lowers this to:

f:         
    adrp    x8, :got:var
    ldr x8, [x8, :got_lo12:var]
    ldrb    w9, [x8, #2]
    ldrh    w8, [x8]
    orr w0, w8, w9, lsl #16
    ret

this seems OK. we lift it to:

@var = external local_unnamed_addr global i18

define i18 @f() local_unnamed_addr {
arm_tv_entry:
  %a5_1 = load i8, ptr getelementptr inbounds (i8, ptr @var, i64 2), align 2
  %a6_1 = load i16, ptr @var, align 4
  %a7_1 = zext i16 %a6_1 to i18
  %a7_3 = zext i8 %a5_1 to i18
  %a7_5 = shl i18 %a7_3, 16
  %a7_6 = or disjoint i18 %a7_5, %a7_1
  ret i18 %a7_6
}

which also seems ok? but then we get a value mismatch from Alive I'll need to update the version in Compiler Explorer before I can link to this example

regehr commented 3 months ago

here's another one that looks like it's probably a symptom of the same underlying issue

we start with this IR:

define i32 @f(ptr %0) {
  %2 = load i1, ptr %0, align 1
  %3 = load i32, ptr %0, align 4
  ret i32 %3
}

the backend removes the dead load and we lift the ARM to:

define i32 @f(ptr %0) local_unnamed_addr {
arm_tv_entry:
  %a3_1 = load i32, ptr %0, align 1
  ret i32 %a3_1
}

and this fails with a Value Mismatch

regehr commented 3 months ago

ok CE is updated so I can link to this stuff now https://alive2.llvm.org/ce/z/k8zarP