| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- ; RUN: opt -instcombine -S < %s | FileCheck %s
- ; This test is to verify that the instruction combiner is able to fold
- ; a cttz/ctlz followed by a icmp + select into a single cttz/ctlz with
- ; the 'is_zero_undef' flag cleared.
- define i16 @test1(i16 %x) {
- ; CHECK-LABEL: @test1(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
- ; CHECK-NEXT: ret i16 [[VAR]]
- entry:
- %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
- %tobool = icmp ne i16 %x, 0
- %cond = select i1 %tobool, i16 %0, i16 16
- ret i16 %cond
- }
- define i32 @test2(i32 %x) {
- ; CHECK-LABEL: @test2(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: ret i32 [[VAR]]
- entry:
- %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
- %tobool = icmp ne i32 %x, 0
- %cond = select i1 %tobool, i32 %0, i32 32
- ret i32 %cond
- }
- define i64 @test3(i64 %x) {
- ; CHECK-LABEL: @test3(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
- ; CHECK-NEXT: ret i64 [[VAR]]
- entry:
- %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
- %tobool = icmp ne i64 %x, 0
- %cond = select i1 %tobool, i64 %0, i64 64
- ret i64 %cond
- }
- define i16 @test4(i16 %x) {
- ; CHECK-LABEL: @test4(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
- ; CHECK-NEXT: ret i16 [[VAR]]
- entry:
- %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
- %tobool = icmp eq i16 %x, 0
- %cond = select i1 %tobool, i16 16, i16 %0
- ret i16 %cond
- }
- define i32 @test5(i32 %x) {
- ; CHECK-LABEL: @test5(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: ret i32 [[VAR]]
- entry:
- %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
- %tobool = icmp eq i32 %x, 0
- %cond = select i1 %tobool, i32 32, i32 %0
- ret i32 %cond
- }
- define i64 @test6(i64 %x) {
- ; CHECK-LABEL: @test6(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
- ; CHECK-NEXT: ret i64 [[VAR]]
- entry:
- %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
- %tobool = icmp eq i64 %x, 0
- %cond = select i1 %tobool, i64 64, i64 %0
- ret i64 %cond
- }
- define i16 @test1b(i16 %x) {
- ; CHECK-LABEL: @test1b(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
- ; CHECK-NEXT: ret i16 [[VAR]]
- entry:
- %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
- %tobool = icmp ne i16 %x, 0
- %cond = select i1 %tobool, i16 %0, i16 16
- ret i16 %cond
- }
- define i32 @test2b(i32 %x) {
- ; CHECK-LABEL: @test2b(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: ret i32 [[VAR]]
- entry:
- %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
- %tobool = icmp ne i32 %x, 0
- %cond = select i1 %tobool, i32 %0, i32 32
- ret i32 %cond
- }
- define i64 @test3b(i64 %x) {
- ; CHECK-LABEL: @test3b(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
- ; CHECK-NEXT: ret i64 [[VAR]]
- entry:
- %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
- %tobool = icmp ne i64 %x, 0
- %cond = select i1 %tobool, i64 %0, i64 64
- ret i64 %cond
- }
- define i16 @test4b(i16 %x) {
- ; CHECK-LABEL: @test4b(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
- ; CHECK-NEXT: ret i16 [[VAR]]
- entry:
- %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
- %tobool = icmp eq i16 %x, 0
- %cond = select i1 %tobool, i16 16, i16 %0
- ret i16 %cond
- }
- define i32 @test5b(i32 %x) {
- ; CHECK-LABEL: @test5b(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: ret i32 [[VAR]]
- entry:
- %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
- %tobool = icmp eq i32 %x, 0
- %cond = select i1 %tobool, i32 32, i32 %0
- ret i32 %cond
- }
- define i64 @test6b(i64 %x) {
- ; CHECK-LABEL: @test6b(
- ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
- ; CHECK-NEXT: ret i64 [[VAR]]
- entry:
- %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
- %tobool = icmp eq i64 %x, 0
- %cond = select i1 %tobool, i64 64, i64 %0
- ret i64 %cond
- }
- define i32 @test1c(i16 %x) {
- ; CHECK-LABEL: @test1c(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i32
- ; CHECK-NEXT: ret i32 [[VAR2]]
- entry:
- %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
- %cast2 = zext i16 %0 to i32
- %tobool = icmp ne i16 %x, 0
- %cond = select i1 %tobool, i32 %cast2, i32 16
- ret i32 %cond
- }
- define i64 @test2c(i16 %x) {
- ; CHECK-LABEL: @test2c(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i64
- ; CHECK-NEXT: ret i64 [[VAR2]]
- entry:
- %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
- %conv = zext i16 %0 to i64
- %tobool = icmp ne i16 %x, 0
- %cond = select i1 %tobool, i64 %conv, i64 16
- ret i64 %cond
- }
- define i64 @test3c(i32 %x) {
- ; CHECK-LABEL: @test3c(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
- ; CHECK-NEXT: ret i64 [[VAR2]]
- entry:
- %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
- %conv = zext i32 %0 to i64
- %tobool = icmp ne i32 %x, 0
- %cond = select i1 %tobool, i64 %conv, i64 32
- ret i64 %cond
- }
- define i32 @test4c(i16 %x) {
- ; CHECK-LABEL: @test4c(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i32
- ; CHECK-NEXT: ret i32 [[VAR2]]
- entry:
- %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
- %cast = zext i16 %0 to i32
- %tobool = icmp ne i16 %x, 0
- %cond = select i1 %tobool, i32 %cast, i32 16
- ret i32 %cond
- }
- define i64 @test5c(i16 %x) {
- ; CHECK-LABEL: @test5c(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i64
- ; CHECK-NEXT: ret i64 [[VAR2]]
- entry:
- %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
- %cast = zext i16 %0 to i64
- %tobool = icmp ne i16 %x, 0
- %cond = select i1 %tobool, i64 %cast, i64 16
- ret i64 %cond
- }
- define i64 @test6c(i32 %x) {
- ; CHECK-LABEL: @test6c(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
- ; CHECK-NEXT: ret i64 [[VAR2]]
- entry:
- %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
- %cast = zext i32 %0 to i64
- %tobool = icmp ne i32 %x, 0
- %cond = select i1 %tobool, i64 %cast, i64 32
- ret i64 %cond
- }
- define i16 @test1d(i64 %x) {
- ; CHECK-LABEL: @test1d(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i16
- ; CHECK-NEXT: ret i16 [[VAR2]]
- entry:
- %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
- %conv = trunc i64 %0 to i16
- %tobool = icmp ne i64 %x, 0
- %cond = select i1 %tobool, i16 %conv, i16 64
- ret i16 %cond
- }
- define i32 @test2d(i64 %x) {
- ; CHECK-LABEL: @test2d(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i32
- ; CHECK-NEXT: ret i32 [[VAR2]]
- entry:
- %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
- %cast = trunc i64 %0 to i32
- %tobool = icmp ne i64 %x, 0
- %cond = select i1 %tobool, i32 %cast, i32 64
- ret i32 %cond
- }
- define i16 @test3d(i32 %x) {
- ; CHECK-LABEL: @test3d(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
- ; CHECK-NEXT: ret i16 [[VAR2]]
- entry:
- %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
- %cast = trunc i32 %0 to i16
- %tobool = icmp ne i32 %x, 0
- %cond = select i1 %tobool, i16 %cast, i16 32
- ret i16 %cond
- }
- define i16 @test4d(i64 %x) {
- ; CHECK-LABEL: @test4d(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i16
- ; CHECK-NEXT: ret i16 [[VAR2]]
- entry:
- %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
- %cast = trunc i64 %0 to i16
- %tobool = icmp ne i64 %x, 0
- %cond = select i1 %tobool, i16 %cast, i16 64
- ret i16 %cond
- }
- define i32 @test5d(i64 %x) {
- ; CHECK-LABEL: @test5d(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i32
- ; CHECK-NEXT: ret i32 [[VAR2]]
- entry:
- %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
- %cast = trunc i64 %0 to i32
- %tobool = icmp ne i64 %x, 0
- %cond = select i1 %tobool, i32 %cast, i32 64
- ret i32 %cond
- }
- define i16 @test6d(i32 %x) {
- ; CHECK-LABEL: @test6d(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
- ; CHECK-NEXT: ret i16 [[VAR2]]
- entry:
- %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
- %cast = trunc i32 %0 to i16
- %tobool = icmp ne i32 %x, 0
- %cond = select i1 %tobool, i16 %cast, i16 32
- ret i16 %cond
- }
- define i64 @select_bug1(i32 %x) {
- ; CHECK-LABEL: @select_bug1(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
- ; CHECK-NEXT: ret i64 [[VAR2]]
- entry:
- %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
- %conv = zext i32 %0 to i64
- %tobool = icmp ne i32 %x, 0
- %cond = select i1 %tobool, i64 %conv, i64 32
- ret i64 %cond
- }
- define i16 @select_bug2(i32 %x) {
- ; CHECK-LABEL: @select_bug2(
- ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
- ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
- ; CHECK-NEXT: ret i16 [[VAR2]]
- entry:
- %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
- %conv = trunc i32 %0 to i16
- %tobool = icmp ne i32 %x, 0
- %cond = select i1 %tobool, i16 %conv, i16 32
- ret i16 %cond
- }
- declare i16 @llvm.ctlz.i16(i16, i1)
- declare i32 @llvm.ctlz.i32(i32, i1)
- declare i64 @llvm.ctlz.i64(i64, i1)
- declare i16 @llvm.cttz.i16(i16, i1)
- declare i32 @llvm.cttz.i32(i32, i1)
- declare i64 @llvm.cttz.i64(i64, i1)
|