Skip to content

[Regression 9] i1 is not treated as 8bit in store combine #42791

@kristate

Description

@kristate
mannequin
Bugzilla Link 43446
Resolution FIXED
Resolved on Feb 26, 2020 06:32
Version 9.0
OS Linux
Blocks #30613 #43900
CC @topperc,@zmodem,@LebedevRI,@RKSimon,@slacka,@Kojoley,@rotateright
Fixed by commit(s) d20907d

Extended Description

On LLVM 9 we have some code that breaks when LLVM optimizes it. We have been unable to produce a minimum example in our frontend, but we've narrowed down a small LLVM IR snippet that seems to have the same problem. This was not an issue on LLVM 8.0.0.

testing.ll:

; ModuleID = 'testing-not-working'
source_filename = "testing-not-working"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nobuiltin nounwind
define i64 @​testing() local_unnamed_addr #​1 {
Entry:
  %hasher = alloca i64
  %0 = tail call i64 asm sideeffect "syscall", "={rax},{rax},{rdi},{rsi},{rdx},{r10},{r8},{r9},~{rcx},~{r11},~{memory}"(i64 9, i64 0, i64 1, i64 3, i64 34, i64 -1, i64 0) #​6

  %1 = inttoptr i64 %0 to i8*
  store i8 -2, i8* %1
  %2 = inttoptr i64 %0 to i1*
  store i1 true, i1* %2
  %3 = bitcast i64* %hasher to i8*
  store i64 0, i64* %hasher
  %4 = load i1, i1* %2
  %5 = zext i1 %4 to i64
  ret i64 %5
}

attributes #​0 = { cold noreturn nounwind }
attributes #​1 = { nobuiltin nounwind }
attributes #​2 = { argmemonly nounwind }
attributes #​3 = { naked nobuiltin noreturn nounwind }
attributes #​4 = { nobuiltin noreturn nounwind }
attributes #​5 = { nobuiltin noinline nounwind }
attributes #​6 = { nounwind }
attributes #​7 = { noinline }

test.c:

#include <inttypes.h>
#include <stdio.h>

uint64_t testing();

void main() {
    printf("%" PRId64 "", testing());
}
path/to/llc testing.ll -filetype=obj && gcc test.c testing.o && ./a.out

Compiling this code and running it prints 255. This is very unexpected as we are returning the result of a zext instruction.

  %5 = zext i1 %4 to i64
  ret i64 %5

The docs for llvm say:

When zero extending from i1, the result will always be either 0 or 1.

https://llvm.org/docs/LangRef.html#zext-to-instruction

So no matter what the code above is doing, zext should ALWAYS give 0 or 1. But this is clearly not the case as testing returns 255. Compiling with llc from llvm8 and testing returns 1 as expected.

~/repo/llvm-cfe-install/bin/llc --version | grep LLVM
LLVM (http://llvm.org/):
  LLVM version 9.0.0

❯ llc --version | grep LLVM
LLVM (http://llvm.org/):
  LLVM version 8.0.1

❯ llc testing.ll -filetype=obj && gcc test.c testing.o && ./a.out 
1
❯ ~/repo/llvm-cfe-install/bin/llc testing.ll -filetype=obj && gcc test.c testing.o && ./a.out 
255

Thank-you.


Credit to Jimmi Holst Christensen [email protected]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions