forked from OSchip/llvm-project
[SimplifyCFG] revert the last commit.
I ran ALL the test suite locally, so I will look into this... llvm-svn: 363223
This commit is contained in:
parent
f93b99b2b6
commit
c6cba2957d
|
@ -1,14 +1,11 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -S -simplifycfg -mtriple=arm -mattr=+v6t2 < %s | FileCheck %s
|
; RUN: opt -S -simplifycfg -mtriple=arm -mattr=+v6t2 < %s | FileCheck %s
|
||||||
|
|
||||||
define i32 @ctlz(i32 %A) {
|
define i32 @ctlz(i32 %A) {
|
||||||
; CHECK-LABEL: @ctlz(
|
; CHECK-LABEL: @ctlz(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
|
||||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
|
; CHECK-NEXT: [[CTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[A]], i1 true)
|
; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTZ]]
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
|
; CHECK-NEXT: ret i32 [[SEL]]
|
||||||
; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i32 %A, 0
|
%tobool = icmp eq i32 %A, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -24,12 +21,10 @@ cond.end:
|
||||||
|
|
||||||
define i32 @cttz(i32 %A) {
|
define i32 @cttz(i32 %A) {
|
||||||
; CHECK-LABEL: @cttz(
|
; CHECK-LABEL: @cttz(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
|
||||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
|
; CHECK-NEXT: [[CTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[A]], i1 true)
|
; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTZ]]
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
|
; CHECK-NEXT: ret i32 [[SEL]]
|
||||||
; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i32 %A, 0
|
%tobool = icmp eq i32 %A, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
|
|
@ -1,20 +1,11 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
;RUN: opt -S -simplifycfg -mtriple=arm < %s | FileCheck %s
|
;RUN: opt -S -simplifycfg -mtriple=arm < %s | FileCheck %s
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
|
; CHECK-LABEL: select_trunc_i64
|
||||||
|
; CHECK-NOT: br
|
||||||
|
; CHECK: select
|
||||||
|
; CHECK: select
|
||||||
define arm_aapcscc i32 @select_trunc_i64(i32 %a, i32 %b) {
|
define arm_aapcscc i32 @select_trunc_i64(i32 %a, i32 %b) {
|
||||||
; CHECK-LABEL: @select_trunc_i64(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
|
|
||||||
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
|
|
||||||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[ADD]], 2147483647
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[ADD]], -2147483648
|
|
||||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 -2147483648
|
|
||||||
; CHECK-NEXT: [[EXTRACT_T:%.*]] = trunc i64 [[COND]] to i32
|
|
||||||
; CHECK-NEXT: [[COND8_OFF0:%.*]] = select i1 [[CMP]], i32 2147483647, i32 [[EXTRACT_T]]
|
|
||||||
; CHECK-NEXT: ret i32 [[COND8_OFF0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%conv = sext i32 %a to i64
|
%conv = sext i32 %a to i64
|
||||||
%conv1 = sext i32 %b to i64
|
%conv1 = sext i32 %b to i64
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -S -simplifycfg < %s | FileCheck %s
|
; RUN: opt -S -simplifycfg < %s | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
@ -16,23 +15,6 @@ target triple = "armv7a--none-eabi"
|
||||||
@g4 = external thread_local global i32, align 4
|
@g4 = external thread_local global i32, align 4
|
||||||
|
|
||||||
define i32* @test3(i32 %n) {
|
define i32* @test3(i32 %n) {
|
||||||
; CHECK-LABEL: @test3(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[N:%.*]], label [[SW_DEFAULT:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 0, label [[RETURN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]]
|
|
||||||
; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: sw.bb1:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb2:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.default:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32* [ @g4, [[SW_DEFAULT]] ], [ getelementptr inbounds (i32, i32* inttoptr (i32 mul (i32 ptrtoint (i32* @g3 to i32), i32 2) to i32*), i32 1), [[SW_BB2]] ], [ @g2, [[SW_BB1]] ], [ @g1, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: ret i32* [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %n, label %sw.default [
|
switch i32 %n, label %sw.default [
|
||||||
i32 0, label %sw.bb
|
i32 0, label %sw.bb
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
|
; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
|
||||||
; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
|
; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
|
||||||
; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
|
; RUN: opt -S -simplifycfg -switch-to-lookup -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
|
||||||
|
@ -23,17 +22,6 @@ target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
target triple = "armv7a--none-eabi"
|
target triple = "armv7a--none-eabi"
|
||||||
|
|
||||||
define i32 @test1(i32 %n) {
|
define i32 @test1(i32 %n) {
|
||||||
; CHECK-LABEL: @test1(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N:%.*]], 3
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32], [3 x i32]* @switch.table.test1, i32 0, i32 [[N]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i32 15498
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %n, label %sw.default [
|
switch i32 %n, label %sw.default [
|
||||||
i32 0, label %sw.bb
|
i32 0, label %sw.bb
|
||||||
|
@ -65,34 +53,6 @@ return:
|
||||||
|
|
||||||
|
|
||||||
define i32* @test2(i32 %n) {
|
define i32* @test2(i32 %n) {
|
||||||
; ENABLE-LABEL: @test2(
|
|
||||||
; ENABLE-NEXT: entry:
|
|
||||||
; ENABLE-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N:%.*]], 3
|
|
||||||
; ENABLE-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; ENABLE: switch.lookup:
|
|
||||||
; ENABLE-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32*], [3 x i32*]* @switch.table.test2, i32 0, i32 [[N]]
|
|
||||||
; ENABLE-NEXT: [[SWITCH_LOAD:%.*]] = load i32*, i32** [[SWITCH_GEP]]
|
|
||||||
; ENABLE-NEXT: ret i32* [[SWITCH_LOAD]]
|
|
||||||
; ENABLE: return:
|
|
||||||
; ENABLE-NEXT: ret i32* @c4
|
|
||||||
;
|
|
||||||
; DISABLE-LABEL: @test2(
|
|
||||||
; DISABLE-NEXT: entry:
|
|
||||||
; DISABLE-NEXT: switch i32 [[N:%.*]], label [[SW_DEFAULT:%.*]] [
|
|
||||||
; DISABLE-NEXT: i32 0, label [[RETURN:%.*]]
|
|
||||||
; DISABLE-NEXT: i32 1, label [[SW_BB1:%.*]]
|
|
||||||
; DISABLE-NEXT: i32 2, label [[SW_BB2:%.*]]
|
|
||||||
; DISABLE-NEXT: ]
|
|
||||||
; DISABLE: sw.bb1:
|
|
||||||
; DISABLE-NEXT: br label [[RETURN]]
|
|
||||||
; DISABLE: sw.bb2:
|
|
||||||
; DISABLE-NEXT: br label [[RETURN]]
|
|
||||||
; DISABLE: sw.default:
|
|
||||||
; DISABLE-NEXT: br label [[RETURN]]
|
|
||||||
; DISABLE: return:
|
|
||||||
; DISABLE-NEXT: [[RETVAL_0:%.*]] = phi i32* [ @c4, [[SW_DEFAULT]] ], [ @c3, [[SW_BB2]] ], [ @c2, [[SW_BB1]] ], [ @c1, [[ENTRY:%.*]] ]
|
|
||||||
; DISABLE-NEXT: ret i32* [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %n, label %sw.default [
|
switch i32 %n, label %sw.default [
|
||||||
i32 0, label %sw.bb
|
i32 0, label %sw.bb
|
||||||
|
@ -123,34 +83,6 @@ return:
|
||||||
@g4 = external global i32, align 4
|
@g4 = external global i32, align 4
|
||||||
|
|
||||||
define i32* @test3(i32 %n) {
|
define i32* @test3(i32 %n) {
|
||||||
; ENABLE-LABEL: @test3(
|
|
||||||
; ENABLE-NEXT: entry:
|
|
||||||
; ENABLE-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N:%.*]], 3
|
|
||||||
; ENABLE-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; ENABLE: switch.lookup:
|
|
||||||
; ENABLE-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32*], [3 x i32*]* @switch.table.test3, i32 0, i32 [[N]]
|
|
||||||
; ENABLE-NEXT: [[SWITCH_LOAD:%.*]] = load i32*, i32** [[SWITCH_GEP]]
|
|
||||||
; ENABLE-NEXT: ret i32* [[SWITCH_LOAD]]
|
|
||||||
; ENABLE: return:
|
|
||||||
; ENABLE-NEXT: ret i32* @g4
|
|
||||||
;
|
|
||||||
; DISABLE-LABEL: @test3(
|
|
||||||
; DISABLE-NEXT: entry:
|
|
||||||
; DISABLE-NEXT: switch i32 [[N:%.*]], label [[SW_DEFAULT:%.*]] [
|
|
||||||
; DISABLE-NEXT: i32 0, label [[RETURN:%.*]]
|
|
||||||
; DISABLE-NEXT: i32 1, label [[SW_BB1:%.*]]
|
|
||||||
; DISABLE-NEXT: i32 2, label [[SW_BB2:%.*]]
|
|
||||||
; DISABLE-NEXT: ]
|
|
||||||
; DISABLE: sw.bb1:
|
|
||||||
; DISABLE-NEXT: br label [[RETURN]]
|
|
||||||
; DISABLE: sw.bb2:
|
|
||||||
; DISABLE-NEXT: br label [[RETURN]]
|
|
||||||
; DISABLE: sw.default:
|
|
||||||
; DISABLE-NEXT: br label [[RETURN]]
|
|
||||||
; DISABLE: return:
|
|
||||||
; DISABLE-NEXT: [[RETVAL_0:%.*]] = phi i32* [ @g4, [[SW_DEFAULT]] ], [ @g3, [[SW_BB2]] ], [ @g2, [[SW_BB1]] ], [ @g1, [[ENTRY:%.*]] ]
|
|
||||||
; DISABLE-NEXT: ret i32* [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %n, label %sw.default [
|
switch i32 %n, label %sw.default [
|
||||||
i32 0, label %sw.bb
|
i32 0, label %sw.bb
|
||||||
|
@ -182,26 +114,6 @@ declare i32 @f4(i32, i32)
|
||||||
declare i32 @f5(i32, i32)
|
declare i32 @f5(i32, i32)
|
||||||
|
|
||||||
define i32 @test4(i32 %a, i32 %b, i32 %c) {
|
define i32 @test4(i32 %a, i32 %b, i32 %c) {
|
||||||
; CHECK-LABEL: @test4(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[A:%.*]], label [[COND_FALSE6:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 1, label [[COND_END11:%.*]]
|
|
||||||
; CHECK-NEXT: i32 2, label [[COND_END11_FOLD_SPLIT:%.*]]
|
|
||||||
; CHECK-NEXT: i32 3, label [[COND_END11_FOLD_SPLIT1:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: cond.false6:
|
|
||||||
; CHECK-NEXT: [[CMP7:%.*]] = icmp eq i32 [[A]], 4
|
|
||||||
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP7]], i32 (i32, i32)* @f4, i32 (i32, i32)* @f5
|
|
||||||
; CHECK-NEXT: br label [[COND_END11]]
|
|
||||||
; CHECK: cond.end11.fold.split:
|
|
||||||
; CHECK-NEXT: br label [[COND_END11]]
|
|
||||||
; CHECK: cond.end11.fold.split1:
|
|
||||||
; CHECK-NEXT: br label [[COND_END11]]
|
|
||||||
; CHECK: cond.end11:
|
|
||||||
; CHECK-NEXT: [[COND12:%.*]] = phi i32 (i32, i32)* [ @f1, [[ENTRY:%.*]] ], [ [[COND]], [[COND_FALSE6]] ], [ @f2, [[COND_END11_FOLD_SPLIT]] ], [ @f3, [[COND_END11_FOLD_SPLIT1]] ]
|
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 [[COND12]](i32 [[B:%.*]], i32 [[C:%.*]])
|
|
||||||
; CHECK-NEXT: ret i32 [[CALL]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp eq i32 %a, 1
|
%cmp = icmp eq i32 %a, 1
|
||||||
br i1 %cmp, label %cond.end11, label %cond.false
|
br i1 %cmp, label %cond.end11, label %cond.false
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -simplifycfg -switch-to-lookup -S %s | FileCheck %s
|
; RUN: opt -simplifycfg -switch-to-lookup -S %s | FileCheck %s
|
||||||
; RUN: opt -passes='simplify-cfg<switch-to-lookup>' -S %s | FileCheck %s
|
; RUN: opt -passes='simplify-cfg<switch-to-lookup>' -S %s | FileCheck %s
|
||||||
; rdar://15268442
|
; rdar://15268442
|
||||||
|
@ -6,20 +5,16 @@
|
||||||
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-apple-darwin12.0.0"
|
target triple = "x86_64-apple-darwin12.0.0"
|
||||||
|
|
||||||
|
; CHECK-LABEL: define i3 @coveredswitch_test(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: sub i3 %input, -4
|
||||||
|
; CHECK-NEXT: zext i3 %switch.tableidx to i24
|
||||||
|
; CHECK-NEXT: mul i24 %switch.cast, 3
|
||||||
|
; CHECK-NEXT: lshr i24 7507338, %switch.shiftamt
|
||||||
|
; CHECK-NEXT: trunc i24 %switch.downshift to i3
|
||||||
|
; CHECK-NEXT: ret i3 %switch.masked
|
||||||
|
|
||||||
define i3 @coveredswitch_test(i3 %input) {
|
define i3 @coveredswitch_test(i3 %input) {
|
||||||
; CHECK-LABEL: @coveredswitch_test(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i3 [[INPUT:%.*]], -2
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[BB8:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_CAST:%.*]] = zext i3 [[INPUT]] to i18
|
|
||||||
; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i18 [[SWITCH_CAST]], 3
|
|
||||||
; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i18 42792, [[SWITCH_SHIFTAMT]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i18 [[SWITCH_DOWNSHIFT]] to i3
|
|
||||||
; CHECK-NEXT: ret i3 [[SWITCH_MASKED]]
|
|
||||||
; CHECK: bb8:
|
|
||||||
; CHECK-NEXT: ret i3 -2
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i3 %input, label %bb8 [
|
switch i3 %input, label %bb8 [
|
||||||
i3 0, label %bb7
|
i3 0, label %bb7
|
||||||
|
|
|
@ -1,30 +1,13 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt < %s -simplifycfg -switch-to-lookup -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
; RUN: opt < %s -simplifycfg -switch-to-lookup -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
||||||
; RUN: opt < %s -passes='simplify-cfg<switch-to-lookup>' -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
; RUN: opt < %s -passes='simplify-cfg<switch-to-lookup>' -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
||||||
|
|
||||||
; In the presence of "-no-jump-tables"="true", simplifycfg should not convert switches to lookup tables.
|
; In the presence of "-no-jump-tables"="true", simplifycfg should not convert switches to lookup tables.
|
||||||
|
|
||||||
|
; CHECK: @switch.table.bar = private unnamed_addr constant [4 x i32] [i32 55, i32 123, i32 0, i32 -1]
|
||||||
|
; CHECK-LABEL: foo
|
||||||
|
; CHECK-NOT: @switch.table.foo = private unnamed_addr constant [4 x i32] [i32 55, i32 123, i32 0, i32 -1]
|
||||||
|
|
||||||
define i32 @foo(i32 %c) "no-jump-tables"="true" {
|
define i32 @foo(i32 %c) "no-jump-tables"="true" {
|
||||||
; CHECK-LABEL: @foo(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 42, label [[RETURN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 43, label [[SW_BB1:%.*]]
|
|
||||||
; CHECK-NEXT: i32 44, label [[SW_BB2:%.*]]
|
|
||||||
; CHECK-NEXT: i32 45, label [[SW_BB3:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: sw.bb1:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb2:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb3:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.default:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 15, [[SW_DEFAULT]] ], [ -1, [[SW_BB3]] ], [ 0, [[SW_BB2]] ], [ 123, [[SW_BB1]] ], [ 55, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: ret i32 [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 42, label %return
|
i32 42, label %return
|
||||||
|
@ -44,18 +27,6 @@ return:
|
||||||
|
|
||||||
|
|
||||||
define i32 @bar(i32 %c) {
|
define i32 @bar(i32 %c) {
|
||||||
; CHECK-LABEL: @bar(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.bar, i32 0, i32 [[SWITCH_TABLEIDX]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i32 15
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 42, label %return
|
i32 42, label %return
|
||||||
|
|
|
@ -1,31 +1,14 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+bmi < %s | FileCheck %s --check-prefix=ALL --check-prefix=BMI
|
; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+bmi < %s | FileCheck %s --check-prefix=ALL --check-prefix=BMI
|
||||||
; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+lzcnt < %s | FileCheck %s --check-prefix=ALL --check-prefix=LZCNT
|
; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+lzcnt < %s | FileCheck %s --check-prefix=ALL --check-prefix=LZCNT
|
||||||
; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC
|
; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC
|
||||||
|
|
||||||
|
|
||||||
define i64 @test1(i64 %A) {
|
define i64 @test1(i64 %A) {
|
||||||
; BMI-LABEL: @test1(
|
; ALL-LABEL: @test1(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
|
; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[A]], i1 true)
|
; ALL-NEXT: select i1 [[COND]], i64 64, i64 [[CTLZ]]
|
||||||
; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
|
; ALL: ret
|
||||||
; BMI-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test1(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[A]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
|
|
||||||
; LZCNT-NEXT: ret i64 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test1(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[A]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
|
|
||||||
; GENERIC-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i64 %A, 0
|
%tobool = icmp eq i64 %A, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -40,27 +23,11 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test2(i32 %A) {
|
define i32 @test2(i32 %A) {
|
||||||
; BMI-LABEL: @test2(
|
; ALL-LABEL: @test2(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
|
; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[A]], i1 true)
|
; ALL-NEXT: select i1 [[COND]], i32 32, i32 [[CTLZ]]
|
||||||
; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
|
; ALL: ret
|
||||||
; BMI-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test2(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[A]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
|
|
||||||
; LZCNT-NEXT: ret i32 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test2(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[A]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
|
|
||||||
; GENERIC-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i32 %A, 0
|
%tobool = icmp eq i32 %A, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -76,27 +43,11 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
|
|
||||||
|
|
||||||
define signext i16 @test3(i16 signext %A) {
|
define signext i16 @test3(i16 signext %A) {
|
||||||
; BMI-LABEL: @test3(
|
; ALL-LABEL: @test3(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
|
; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[A]], i1 true)
|
; ALL-NEXT: select i1 [[COND]], i16 16, i16 [[CTLZ]]
|
||||||
; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
|
; ALL: ret
|
||||||
; BMI-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test3(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[A]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
|
|
||||||
; LZCNT-NEXT: ret i16 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test3(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[A]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
|
|
||||||
; GENERIC-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i16 %A, 0
|
%tobool = icmp eq i16 %A, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -112,27 +63,11 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
|
|
||||||
|
|
||||||
define i64 @test1b(i64 %A) {
|
define i64 @test1b(i64 %A) {
|
||||||
; BMI-LABEL: @test1b(
|
; ALL-LABEL: @test1b(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
|
; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[A]], i1 true)
|
; ALL-NEXT: select i1 [[COND]], i64 64, i64 [[CTTZ]]
|
||||||
; BMI-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
|
; ALL: ret
|
||||||
; BMI-NEXT: ret i64 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test1b(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[A]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
|
|
||||||
; LZCNT-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test1b(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[A]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
|
|
||||||
; GENERIC-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i64 %A, 0
|
%tobool = icmp eq i64 %A, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -148,27 +83,11 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
|
|
||||||
|
|
||||||
define i32 @test2b(i32 %A) {
|
define i32 @test2b(i32 %A) {
|
||||||
; BMI-LABEL: @test2b(
|
; ALL-LABEL: @test2b(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
|
; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[A]], i1 true)
|
; ALL-NEXT: select i1 [[COND]], i32 32, i32 [[CTTZ]]
|
||||||
; BMI-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
|
; ALL: ret
|
||||||
; BMI-NEXT: ret i32 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test2b(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[A]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
|
|
||||||
; LZCNT-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test2b(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[A]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
|
|
||||||
; GENERIC-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i32 %A, 0
|
%tobool = icmp eq i32 %A, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -184,27 +103,11 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
|
|
||||||
|
|
||||||
define signext i16 @test3b(i16 signext %A) {
|
define signext i16 @test3b(i16 signext %A) {
|
||||||
; BMI-LABEL: @test3b(
|
; ALL-LABEL: @test3b(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
|
; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[A]], i1 true)
|
; ALL-NEXT: select i1 [[COND]], i16 16, i16 [[CTTZ]]
|
||||||
; BMI-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
|
; ALL: ret
|
||||||
; BMI-NEXT: ret i16 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test3b(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[A]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
|
|
||||||
; LZCNT-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test3b(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[A]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
|
|
||||||
; GENERIC-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i16 %A, 0
|
%tobool = icmp eq i16 %A, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -223,38 +126,14 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
; for the target.
|
; for the target.
|
||||||
|
|
||||||
define i64 @test1e(i32 %x) {
|
define i64 @test1e(i32 %x) {
|
||||||
; BMI-LABEL: @test1e(
|
; ALL-LABEL: @test1e(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true)
|
; ALL: [[ZEXT:%[A-Za-z0-9]+]] = zext i32 [[CTTZ]] to i64
|
||||||
; BMI-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64
|
; BMI-NEXT: select i1 [[COND]], i64 32, i64 [[ZEXT]]
|
||||||
; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 32, i64 [[PHITMP2]]
|
; LZCNT-NOT: select
|
||||||
; BMI-NEXT: ret i64 [[COND]]
|
; GENERIC-NOT: select
|
||||||
;
|
; ALL: ret
|
||||||
; LZCNT-LABEL: @test1e(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
||||||
; LZCNT-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; LZCNT: cond.true:
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64
|
|
||||||
; LZCNT-NEXT: br label [[COND_END]]
|
|
||||||
; LZCNT: cond.end:
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = phi i64 [ [[PHITMP2]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ]
|
|
||||||
; LZCNT-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test1e(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
||||||
; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; GENERIC: cond.true:
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64
|
|
||||||
; GENERIC-NEXT: br label [[COND_END]]
|
|
||||||
; GENERIC: cond.end:
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = phi i64 [ [[PHITMP2]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ]
|
|
||||||
; GENERIC-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i32 %x, 0
|
%tobool = icmp eq i32 %x, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -270,38 +149,14 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test2e(i64 %x) {
|
define i32 @test2e(i64 %x) {
|
||||||
; BMI-LABEL: @test2e(
|
; ALL-LABEL: @test2e(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true)
|
; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTTZ]] to i32
|
||||||
; BMI-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
|
; BMI-NEXT: select i1 [[COND]], i32 64, i32 [[TRUNC]]
|
||||||
; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]
|
; LZCNT-NOT: select
|
||||||
; BMI-NEXT: ret i32 [[COND]]
|
; GENERIC-NOT: select
|
||||||
;
|
; ALL: ret
|
||||||
; LZCNT-LABEL: @test2e(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
||||||
; LZCNT-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; LZCNT: cond.true:
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
|
|
||||||
; LZCNT-NEXT: br label [[COND_END]]
|
|
||||||
; LZCNT: cond.end:
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = phi i32 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ]
|
|
||||||
; LZCNT-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test2e(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
||||||
; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; GENERIC: cond.true:
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
|
|
||||||
; GENERIC-NEXT: br label [[COND_END]]
|
|
||||||
; GENERIC: cond.end:
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = phi i32 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ]
|
|
||||||
; GENERIC-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i64 %x, 0
|
%tobool = icmp eq i64 %x, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -317,38 +172,14 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
}
|
}
|
||||||
|
|
||||||
define i64 @test3e(i32 %x) {
|
define i64 @test3e(i32 %x) {
|
||||||
; BMI-LABEL: @test3e(
|
; ALL-LABEL: @test3e(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
|
||||||
; BMI-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
; ALL: [[ZEXT:%[A-Za-z0-9]+]] = zext i32 [[CTLZ]] to i64
|
||||||
; BMI: cond.true:
|
; LZCNT-NEXT: select i1 [[COND]], i64 32, i64 [[ZEXT]]
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
|
; BMI-NOT: select
|
||||||
; BMI-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64
|
; GENERIC-NOT: select
|
||||||
; BMI-NEXT: br label [[COND_END]]
|
; ALL: ret
|
||||||
; BMI: cond.end:
|
|
||||||
; BMI-NEXT: [[COND:%.*]] = phi i64 [ [[PHITMP2]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ]
|
|
||||||
; BMI-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test3e(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 32, i64 [[PHITMP2]]
|
|
||||||
; LZCNT-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test3e(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
||||||
; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; GENERIC: cond.true:
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64
|
|
||||||
; GENERIC-NEXT: br label [[COND_END]]
|
|
||||||
; GENERIC: cond.end:
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = phi i64 [ [[PHITMP2]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ]
|
|
||||||
; GENERIC-NEXT: ret i64 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i32 %x, 0
|
%tobool = icmp eq i32 %x, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -364,38 +195,14 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test4e(i64 %x) {
|
define i32 @test4e(i64 %x) {
|
||||||
; BMI-LABEL: @test4e(
|
; ALL-LABEL: @test4e(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
|
||||||
; BMI-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTLZ]] to i32
|
||||||
; BMI: cond.true:
|
; LZCNT-NEXT: select i1 [[COND]], i32 64, i32 [[TRUNC]]
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
|
; BMI-NOT: select
|
||||||
; BMI-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
|
; GENERIC-NOT: select
|
||||||
; BMI-NEXT: br label [[COND_END]]
|
; ALL: ret
|
||||||
; BMI: cond.end:
|
|
||||||
; BMI-NEXT: [[COND:%.*]] = phi i32 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ]
|
|
||||||
; BMI-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test4e(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]
|
|
||||||
; LZCNT-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test4e(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
||||||
; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; GENERIC: cond.true:
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
|
|
||||||
; GENERIC-NEXT: br label [[COND_END]]
|
|
||||||
; GENERIC: cond.end:
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = phi i32 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ]
|
|
||||||
; GENERIC-NEXT: ret i32 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i64 %x, 0
|
%tobool = icmp eq i64 %x, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -411,38 +218,14 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @test5e(i64 %x) {
|
define i16 @test5e(i64 %x) {
|
||||||
; BMI-LABEL: @test5e(
|
; ALL-LABEL: @test5e(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
|
||||||
; BMI-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTLZ]] to i16
|
||||||
; BMI: cond.true:
|
; LZCNT-NEXT: select i1 [[COND]], i16 64, i16 [[TRUNC]]
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
|
; BMI-NOT: select
|
||||||
; BMI-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16
|
; GENERIC-NOT: select
|
||||||
; BMI-NEXT: br label [[COND_END]]
|
; ALL: ret
|
||||||
; BMI: cond.end:
|
|
||||||
; BMI-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ]
|
|
||||||
; BMI-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test5e(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 64, i16 [[CAST]]
|
|
||||||
; LZCNT-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test5e(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
||||||
; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; GENERIC: cond.true:
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16
|
|
||||||
; GENERIC-NEXT: br label [[COND_END]]
|
|
||||||
; GENERIC: cond.end:
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ]
|
|
||||||
; GENERIC-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i64 %x, 0
|
%tobool = icmp eq i64 %x, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -458,38 +241,14 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @test6e(i32 %x) {
|
define i16 @test6e(i32 %x) {
|
||||||
; BMI-LABEL: @test6e(
|
; ALL-LABEL: @test6e(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
|
||||||
; BMI-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i32 [[CTLZ]] to i16
|
||||||
; BMI: cond.true:
|
; LZCNT-NEXT: select i1 [[COND]], i16 32, i16 [[TRUNC]]
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
|
; BMI-NOT: select
|
||||||
; BMI-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16
|
; GENERIC-NOT: select
|
||||||
; BMI-NEXT: br label [[COND_END]]
|
; ALL: ret
|
||||||
; BMI: cond.end:
|
|
||||||
; BMI-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ]
|
|
||||||
; BMI-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
; LZCNT-LABEL: @test6e(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 32, i16 [[CAST]]
|
|
||||||
; LZCNT-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test6e(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
||||||
; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; GENERIC: cond.true:
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16
|
|
||||||
; GENERIC-NEXT: br label [[COND_END]]
|
|
||||||
; GENERIC: cond.end:
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ]
|
|
||||||
; GENERIC-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i32 %x, 0
|
%tobool = icmp eq i32 %x, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -505,38 +264,14 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @test7e(i64 %x) {
|
define i16 @test7e(i64 %x) {
|
||||||
; BMI-LABEL: @test7e(
|
; ALL-LABEL: @test7e(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true)
|
; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTTZ]] to i16
|
||||||
; BMI-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16
|
; BMI-NEXT: select i1 [[COND]], i16 64, i16 [[TRUNC]]
|
||||||
; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 64, i16 [[CAST]]
|
; LZCNT-NOT: select
|
||||||
; BMI-NEXT: ret i16 [[COND]]
|
; GENERIC-NOT: select
|
||||||
;
|
; ALL: ret
|
||||||
; LZCNT-LABEL: @test7e(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
||||||
; LZCNT-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; LZCNT: cond.true:
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16
|
|
||||||
; LZCNT-NEXT: br label [[COND_END]]
|
|
||||||
; LZCNT: cond.end:
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ]
|
|
||||||
; LZCNT-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test7e(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
||||||
; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; GENERIC: cond.true:
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[CAST:%.*]] = trunc i64 [[TMP0]] to i16
|
|
||||||
; GENERIC-NEXT: br label [[COND_END]]
|
|
||||||
; GENERIC: cond.end:
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 64, [[ENTRY:%.*]] ]
|
|
||||||
; GENERIC-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i64 %x, 0
|
%tobool = icmp eq i64 %x, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
@ -552,38 +287,14 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @test8e(i32 %x) {
|
define i16 @test8e(i32 %x) {
|
||||||
; BMI-LABEL: @test8e(
|
; ALL-LABEL: @test8e(
|
||||||
; BMI-NEXT: entry:
|
; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
|
||||||
; BMI-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
|
||||||
; BMI-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true)
|
; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i32 [[CTTZ]] to i16
|
||||||
; BMI-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16
|
; BMI-NEXT: select i1 [[COND]], i16 32, i16 [[TRUNC]]
|
||||||
; BMI-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i16 32, i16 [[CAST]]
|
; LZCNT-NOT: select
|
||||||
; BMI-NEXT: ret i16 [[COND]]
|
; GENERIC-NOT: select
|
||||||
;
|
; ALL: ret
|
||||||
; LZCNT-LABEL: @test8e(
|
|
||||||
; LZCNT-NEXT: entry:
|
|
||||||
; LZCNT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
||||||
; LZCNT-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; LZCNT: cond.true:
|
|
||||||
; LZCNT-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true)
|
|
||||||
; LZCNT-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16
|
|
||||||
; LZCNT-NEXT: br label [[COND_END]]
|
|
||||||
; LZCNT: cond.end:
|
|
||||||
; LZCNT-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ]
|
|
||||||
; LZCNT-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
; GENERIC-LABEL: @test8e(
|
|
||||||
; GENERIC-NEXT: entry:
|
|
||||||
; GENERIC-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
||||||
; GENERIC-NEXT: br i1 [[TOBOOL]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
|
|
||||||
; GENERIC: cond.true:
|
|
||||||
; GENERIC-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true)
|
|
||||||
; GENERIC-NEXT: [[CAST:%.*]] = trunc i32 [[TMP0]] to i16
|
|
||||||
; GENERIC-NEXT: br label [[COND_END]]
|
|
||||||
; GENERIC: cond.end:
|
|
||||||
; GENERIC-NEXT: [[COND:%.*]] = phi i16 [ [[CAST]], [[COND_TRUE]] ], [ 32, [[ENTRY:%.*]] ]
|
|
||||||
; GENERIC-NEXT: ret i16 [[COND]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp eq i32 %x, 0
|
%tobool = icmp eq i32 %x, 0
|
||||||
br i1 %tobool, label %cond.end, label %cond.true
|
br i1 %tobool, label %cond.end, label %cond.true
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -S -simplifycfg -switch-to-lookup < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
; RUN: opt -S -simplifycfg -switch-to-lookup < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
||||||
; RUN: opt -S -passes='simplify-cfg<switch-to-lookup>' < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
; RUN: opt -S -passes='simplify-cfg<switch-to-lookup>' < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
||||||
|
|
||||||
|
@ -6,16 +5,17 @@
|
||||||
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-apple-darwin12.0.0"
|
target triple = "x86_64-apple-darwin12.0.0"
|
||||||
|
|
||||||
|
; When we have a covered lookup table, make sure we don't delete PHINodes that
|
||||||
|
; are cached in PHIs.
|
||||||
|
; CHECK-LABEL: @test
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: sub i3 %arg, -4
|
||||||
|
; CHECK-NEXT: zext i3 %switch.tableidx to i4
|
||||||
|
; CHECK-NEXT: getelementptr inbounds [8 x i64], [8 x i64]* @switch.table.test, i32 0, i4 %switch.tableidx.zext
|
||||||
|
; CHECK-NEXT: load i64, i64* %switch.gep
|
||||||
|
; CHECK-NEXT: add i64
|
||||||
|
; CHECK-NEXT: ret i64
|
||||||
define i64 @test(i3 %arg) {
|
define i64 @test(i3 %arg) {
|
||||||
; CHECK-LABEL: @test(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[ARG:%.*]], -4
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i4
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i64], [8 x i64]* @switch.table.test, i32 0, i4 [[SWITCH_TABLEIDX_ZEXT]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, i64* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: [[V3:%.*]] = add i64 [[SWITCH_LOAD]], 0
|
|
||||||
; CHECK-NEXT: ret i64 [[V3]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i3 %arg, label %Default [
|
switch i3 %arg, label %Default [
|
||||||
i3 -2, label %Label6
|
i3 -2, label %Label6
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -S -simplifycfg -switch-to-lookup < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
; RUN: opt -S -simplifycfg -switch-to-lookup < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
||||||
; RUN: opt -S -passes='simplify-cfg<switch-to-lookup>' < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
; RUN: opt -S -passes='simplify-cfg<switch-to-lookup>' < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s
|
||||||
|
|
||||||
|
@ -6,15 +5,15 @@
|
||||||
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-apple-darwin12.0.0"
|
target triple = "x86_64-apple-darwin12.0.0"
|
||||||
|
|
||||||
|
; When tableindex can't fit into i2, we should extend the type to i3.
|
||||||
|
; CHECK-LABEL: @_TFO6reduce1E5toRawfS0_FT_Si
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: sub i2 %0, -2
|
||||||
|
; CHECK-NEXT: zext i2 %switch.tableidx to i3
|
||||||
|
; CHECK-NEXT: getelementptr inbounds [4 x i64], [4 x i64]* @switch.table._TFO6reduce1E5toRawfS0_FT_Si, i32 0, i3 %switch.tableidx.zext
|
||||||
|
; CHECK-NEXT: load i64, i64* %switch.gep
|
||||||
|
; CHECK-NEXT: ret i64 %switch.load
|
||||||
define i64 @_TFO6reduce1E5toRawfS0_FT_Si(i2) {
|
define i64 @_TFO6reduce1E5toRawfS0_FT_Si(i2) {
|
||||||
; CHECK-LABEL: @_TFO6reduce1E5toRawfS0_FT_Si(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i2 [[TMP0:%.*]], -2
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i2 [[SWITCH_TABLEIDX]] to i3
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i64], [4 x i64]* @switch.table._TFO6reduce1E5toRawfS0_FT_Si, i32 0, i3 [[SWITCH_TABLEIDX_ZEXT]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i64, i64* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i64 [[SWITCH_LOAD]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i2 %0, label %1 [
|
switch i2 %0, label %1 [
|
||||||
i2 0, label %2
|
i2 0, label %2
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt < %s -simplifycfg -switch-to-lookup=true -keep-loops=false -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
; RUN: opt < %s -simplifycfg -switch-to-lookup=true -keep-loops=false -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
||||||
; RUN: opt < %s -passes='simplify-cfg<no-keep-loops;switch-to-lookup>' -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
; RUN: opt < %s -passes='simplify-cfg<no-keep-loops;switch-to-lookup>' -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||||
|
@ -20,10 +19,10 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||||
; CHECK: @switch.table.earlyreturncrash = private unnamed_addr constant [4 x i32] [i32 42, i32 9, i32 88, i32 5], align 4
|
; CHECK: @switch.table.earlyreturncrash = private unnamed_addr constant [4 x i32] [i32 42, i32 9, i32 88, i32 5], align 4
|
||||||
|
|
||||||
; The table for @large
|
; The table for @large
|
||||||
; CHECK: @switch.table.large = private unnamed_addr constant [200 x i32] [i32 0, i32 1, i32 4, i32 9,
|
; CHECK: @switch.table.large = private unnamed_addr constant [199 x i32] [i32 1, i32 4, i32 9,
|
||||||
|
|
||||||
; The table for @cprop
|
; The table for @cprop
|
||||||
; CHECK: @switch.table.cprop = private unnamed_addr constant [8 x i32] [i32 123, i32 5, i32 42, i32 126, i32 -452, i32 128, i32 6, i32 7], align 4
|
; CHECK: @switch.table.cprop = private unnamed_addr constant [7 x i32] [i32 5, i32 42, i32 126, i32 -452, i32 128, i32 6, i32 7], align 4
|
||||||
|
|
||||||
; The table for @unreachable_case
|
; The table for @unreachable_case
|
||||||
; CHECK: @switch.table.unreachable_case = private unnamed_addr constant [9 x i32] [i32 0, i32 0, i32 0, i32 2, i32 -1, i32 1, i32 1, i32 1, i32 1], align 4
|
; CHECK: @switch.table.unreachable_case = private unnamed_addr constant [9 x i32] [i32 0, i32 0, i32 0, i32 2, i32 -1, i32 1, i32 1, i32 1, i32 1], align 4
|
||||||
|
@ -34,18 +33,6 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||||
; so we return early, directly from the lookup bb.
|
; so we return early, directly from the lookup bb.
|
||||||
|
|
||||||
define i32 @f(i32 %c) {
|
define i32 @f(i32 %c) {
|
||||||
; CHECK-LABEL: @f(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.f, i32 0, i32 [[SWITCH_TABLEIDX]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i32 15
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 42, label %return
|
i32 42, label %return
|
||||||
|
@ -68,23 +55,22 @@ return:
|
||||||
%retval.0 = phi i32 [ 15, %sw.default ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
%retval.0 = phi i32 [ 15, %sw.default ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @f(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %switch.tableidx = sub i32 %c, 42
|
||||||
|
; CHECK-NEXT: %0 = icmp ult i32 %switch.tableidx, 7
|
||||||
|
; CHECK-NEXT: br i1 %0, label %switch.lookup, label %return
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.gep = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.f, i32 0, i32 %switch.tableidx
|
||||||
|
; CHECK-NEXT: %switch.load = load i32, i32* %switch.gep
|
||||||
|
; CHECK-NEXT: ret i32 %switch.load
|
||||||
|
; CHECK: return:
|
||||||
|
; CHECK-NEXT: ret i32 15
|
||||||
}
|
}
|
||||||
|
|
||||||
; Same thing, but with i8's
|
; Same thing, but with i8's
|
||||||
|
|
||||||
define i8 @char(i32 %c) {
|
define i8 @char(i32 %c) {
|
||||||
; CHECK-LABEL: @char(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 42
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 9
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i8], [9 x i8]* @switch.table.char, i32 0, i32 [[SWITCH_TABLEIDX]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8, i8* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i8 [[SWITCH_LOAD]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i8 15
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 42, label %return
|
i32 42, label %return
|
||||||
|
@ -111,29 +97,23 @@ return:
|
||||||
%retval.0 = phi i8 [ 15, %sw.default ], [ 84, %sw.bb8 ], [ 33, %sw.bb7 ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
%retval.0 = phi i8 [ 15, %sw.default ], [ 84, %sw.bb8 ], [ 33, %sw.bb7 ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
||||||
ret i8 %retval.0
|
ret i8 %retval.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @char(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %switch.tableidx = sub i32 %c, 42
|
||||||
|
; CHECK-NEXT: %0 = icmp ult i32 %switch.tableidx, 9
|
||||||
|
; CHECK-NEXT: br i1 %0, label %switch.lookup, label %return
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.gep = getelementptr inbounds [9 x i8], [9 x i8]* @switch.table.char, i32 0, i32 %switch.tableidx
|
||||||
|
; CHECK-NEXT: %switch.load = load i8, i8* %switch.gep
|
||||||
|
; CHECK-NEXT: ret i8 %switch.load
|
||||||
|
; CHECK: return:
|
||||||
|
; CHECK-NEXT: ret i8 15
|
||||||
}
|
}
|
||||||
|
|
||||||
; A switch used to initialize two variables, an i8 and a float.
|
; A switch used to initialize two variables, an i8 and a float.
|
||||||
|
|
||||||
declare void @dummy(i8 signext, float)
|
declare void @dummy(i8 signext, float)
|
||||||
define void @h(i32 %x) {
|
define void @h(i32 %x) {
|
||||||
; CHECK-LABEL: @h(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[X]], 8
|
|
||||||
; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 89655594, [[SWITCH_SHIFTAMT]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x float], [4 x float]* @switch.table.h, i32 0, i32 [[X]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load float, float* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: br label [[SW_EPILOG]]
|
|
||||||
; CHECK: sw.epilog:
|
|
||||||
; CHECK-NEXT: [[A_0:%.*]] = phi i8 [ [[SWITCH_MASKED]], [[SWITCH_LOOKUP]] ], [ 7, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: [[B_0:%.*]] = phi float [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ], [ 0x4023FAE140000000, [[ENTRY]] ]
|
|
||||||
; CHECK-NEXT: call void @dummy(i8 signext [[A_0]], float [[B_0]])
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %sw.epilog
|
i32 0, label %sw.epilog
|
||||||
|
@ -153,6 +133,22 @@ sw.epilog:
|
||||||
call void @dummy(i8 signext %a.0, float %b.0)
|
call void @dummy(i8 signext %a.0, float %b.0)
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @h(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %0 = icmp ult i32 %x, 4
|
||||||
|
; CHECK-NEXT: br i1 %0, label %switch.lookup, label %sw.epilog
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.shiftamt = mul i32 %x, 8
|
||||||
|
; CHECK-NEXT: %switch.downshift = lshr i32 89655594, %switch.shiftamt
|
||||||
|
; CHECK-NEXT: %switch.masked = trunc i32 %switch.downshift to i8
|
||||||
|
; CHECK-NEXT: %switch.gep = getelementptr inbounds [4 x float], [4 x float]* @switch.table.h, i32 0, i32 %x
|
||||||
|
; CHECK-NEXT: %switch.load = load float, float* %switch.gep
|
||||||
|
; CHECK-NEXT: br label %sw.epilog
|
||||||
|
; CHECK: sw.epilog:
|
||||||
|
; CHECK-NEXT: %a.0 = phi i8 [ %switch.masked, %switch.lookup ], [ 7, %entry ]
|
||||||
|
; CHECK-NEXT: %b.0 = phi float [ %switch.load, %switch.lookup ], [ 0x4023FAE140000000, %entry ]
|
||||||
|
; CHECK-NEXT: call void @dummy(i8 signext %a.0, float %b.0)
|
||||||
|
; CHECK-NEXT: ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,17 +161,6 @@ sw.epilog:
|
||||||
@.str4 = private unnamed_addr constant [6 x i8] c"error\00", align 1
|
@.str4 = private unnamed_addr constant [6 x i8] c"error\00", align 1
|
||||||
|
|
||||||
define i8* @foostring(i32 %x) {
|
define i8* @foostring(i32 %x) {
|
||||||
; CHECK-LABEL: @foostring(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* @switch.table.foostring, i32 0, i32 [[X]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i8*, i8** [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i8* [[SWITCH_LOAD]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str4, i64 0, i64 0)
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %return
|
i32 0, label %return
|
||||||
|
@ -197,23 +182,20 @@ return:
|
||||||
[ getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), %entry ]
|
[ getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), %entry ]
|
||||||
ret i8* %retval.0
|
ret i8* %retval.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @foostring(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %0 = icmp ult i32 %x, 4
|
||||||
|
; CHECK-NEXT: br i1 %0, label %switch.lookup, label %return
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.gep = getelementptr inbounds [4 x i8*], [4 x i8*]* @switch.table.foostring, i32 0, i32 %x
|
||||||
|
; CHECK-NEXT: %switch.load = load i8*, i8** %switch.gep
|
||||||
|
; CHECK-NEXT: ret i8* %switch.load
|
||||||
}
|
}
|
||||||
|
|
||||||
; Switch used to initialize two values. The first value is returned, the second
|
; Switch used to initialize two values. The first value is returned, the second
|
||||||
; value is not used. This used to make the transformation generate illegal code.
|
; value is not used. This used to make the transformation generate illegal code.
|
||||||
|
|
||||||
define i32 @earlyreturncrash(i32 %x) {
|
define i32 @earlyreturncrash(i32 %x) {
|
||||||
; CHECK-LABEL: @earlyreturncrash(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_EPILOG:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.earlyreturncrash, i32 0, i32 [[X]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
; CHECK: sw.epilog:
|
|
||||||
; CHECK-NEXT: ret i32 7
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %sw.epilog
|
i32 0, label %sw.epilog
|
||||||
|
@ -232,6 +214,13 @@ sw.epilog:
|
||||||
%b.0 = phi i32 [ 10, %sw.default ], [ 5, %sw.bb3 ], [ 1, %sw.bb2 ], [ 4, %sw.bb1 ], [ 3, %entry ]
|
%b.0 = phi i32 [ 10, %sw.default ], [ 5, %sw.bb3 ], [ 1, %sw.bb2 ], [ 4, %sw.bb1 ], [ 3, %entry ]
|
||||||
ret i32 %a.0
|
ret i32 %a.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @earlyreturncrash(
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.gep = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.earlyreturncrash, i32 0, i32 %x
|
||||||
|
; CHECK-NEXT: %switch.load = load i32, i32* %switch.gep
|
||||||
|
; CHECK-NEXT: ret i32 %switch.load
|
||||||
|
; CHECK: sw.epilog:
|
||||||
|
; CHECK-NEXT: ret i32 7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,25 +229,6 @@ sw.epilog:
|
||||||
; can be packed into a bitmap.
|
; can be packed into a bitmap.
|
||||||
|
|
||||||
define i32 @crud(i8 zeroext %c) {
|
define i32 @crud(i8 zeroext %c) {
|
||||||
; CHECK-LABEL: @crud(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[C:%.*]], 33
|
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[C]], 34
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 59
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[LOR_END]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_CAST:%.*]] = zext i8 [[SWITCH_TABLEIDX]] to i59
|
|
||||||
; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i59 [[SWITCH_CAST]], 1
|
|
||||||
; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i59 -288230375765830623, [[SWITCH_SHIFTAMT]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i59 [[SWITCH_DOWNSHIFT]] to i1
|
|
||||||
; CHECK-NEXT: br label [[LOR_END]]
|
|
||||||
; CHECK: lor.end:
|
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[SWITCH_MASKED]], [[SWITCH_LOOKUP]] ], [ false, [[SWITCH_EARLY_TEST]] ]
|
|
||||||
; CHECK-NEXT: [[LOR_EXT:%.*]] = zext i1 [[TMP1]] to i32
|
|
||||||
; CHECK-NEXT: ret i32 [[LOR_EXT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ult i8 %c, 33
|
%cmp = icmp ult i8 %c, 33
|
||||||
br i1 %cmp, label %lor.end, label %switch.early.test
|
br i1 %cmp, label %lor.end, label %switch.early.test
|
||||||
|
@ -294,28 +264,28 @@ lor.end:
|
||||||
%lor.ext = zext i1 %0 to i32
|
%lor.ext = zext i1 %0 to i32
|
||||||
ret i32 %lor.ext
|
ret i32 %lor.ext
|
||||||
|
|
||||||
|
; CHECK-LABEL: @crud(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %cmp = icmp ult i8 %c, 33
|
||||||
|
; CHECK-NEXT: br i1 %cmp, label %lor.end, label %switch.early.test
|
||||||
|
; CHECK: switch.early.test:
|
||||||
|
; CHECK-NEXT: %switch.tableidx = sub i8 %c, 34
|
||||||
|
; CHECK-NEXT: %0 = icmp ult i8 %switch.tableidx, 59
|
||||||
|
; CHECK-NEXT: br i1 %0, label %switch.lookup, label %lor.end
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.cast = zext i8 %switch.tableidx to i59
|
||||||
|
; CHECK-NEXT: %switch.shiftamt = mul i59 %switch.cast, 1
|
||||||
|
; CHECK-NEXT: %switch.downshift = lshr i59 -288230375765830623, %switch.shiftamt
|
||||||
|
; CHECK-NEXT: %switch.masked = trunc i59 %switch.downshift to i1
|
||||||
|
; CHECK-NEXT: br label %lor.end
|
||||||
|
; CHECK: lor.end:
|
||||||
|
; CHECK-NEXT: %1 = phi i1 [ true, %entry ], [ %switch.masked, %switch.lookup ], [ false, %switch.early.test ]
|
||||||
|
; CHECK-NEXT: %lor.ext = zext i1 %1 to i32
|
||||||
|
; CHECK-NEXT: ret i32 %lor.ext
|
||||||
}
|
}
|
||||||
|
|
||||||
; PR13946
|
; PR13946
|
||||||
define i32 @overflow(i32 %type) {
|
define i32 @overflow(i32 %type) {
|
||||||
; CHECK-LABEL: @overflow(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[TYPE:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 3, label [[SW_BB3:%.*]]
|
|
||||||
; CHECK-NEXT: i32 -2147483645, label [[SW_BB3]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]]
|
|
||||||
; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: sw.bb1:
|
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
|
||||||
; CHECK: sw.bb2:
|
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
|
||||||
; CHECK: sw.bb3:
|
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: [[DIRENT_TYPE_0:%.*]] = phi i32 [ 6, [[SW_BB3]] ], [ 5, [[SW_BB2]] ], [ 0, [[SW_BB1]] ], [ 3, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: ret i32 [[DIRENT_TYPE_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %type, label %sw.default [
|
switch i32 %type, label %sw.default [
|
||||||
i32 -2147483648, label %sw.bb
|
i32 -2147483648, label %sw.bb
|
||||||
|
@ -336,23 +306,13 @@ if.else: br label %if.end
|
||||||
if.end:
|
if.end:
|
||||||
%dirent_type.0 = phi i32 [ 3, %sw.default ], [ 6, %sw.bb3 ], [ 5, %sw.bb2 ], [ 0, %sw.bb1 ], [ 3, %sw.bb ], [ 0, %if.else ]
|
%dirent_type.0 = phi i32 [ 3, %sw.default ], [ 6, %sw.bb3 ], [ 5, %sw.bb2 ], [ 0, %sw.bb1 ], [ 3, %sw.bb ], [ 0, %if.else ]
|
||||||
ret i32 %dirent_type.0
|
ret i32 %dirent_type.0
|
||||||
|
; CHECK-LABEL: define i32 @overflow(
|
||||||
|
; CHECK: switch
|
||||||
|
; CHECK: phi
|
||||||
}
|
}
|
||||||
|
|
||||||
; PR13985
|
; PR13985
|
||||||
define i1 @undef(i32 %tmp) {
|
define i1 @undef(i32 %tmp) {
|
||||||
; CHECK-LABEL: @undef(
|
|
||||||
; CHECK-NEXT: bb:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[TMP:%.*]], 9
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[BB3:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_CAST:%.*]] = trunc i32 [[TMP]] to i9
|
|
||||||
; CHECK-NEXT: [[SWITCH_SHIFTAMT:%.*]] = mul i9 [[SWITCH_CAST]], 1
|
|
||||||
; CHECK-NEXT: [[SWITCH_DOWNSHIFT:%.*]] = lshr i9 3, [[SWITCH_SHIFTAMT]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_MASKED:%.*]] = trunc i9 [[SWITCH_DOWNSHIFT]] to i1
|
|
||||||
; CHECK-NEXT: ret i1 [[SWITCH_MASKED]]
|
|
||||||
; CHECK: bb3:
|
|
||||||
; CHECK-NEXT: ret i1 undef
|
|
||||||
;
|
|
||||||
bb:
|
bb:
|
||||||
switch i32 %tmp, label %bb3 [
|
switch i32 %tmp, label %bb3 [
|
||||||
i32 0, label %bb1
|
i32 0, label %bb1
|
||||||
|
@ -367,27 +327,16 @@ bb2: br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%tmp4 = phi i1 [ undef, %bb ], [ false, %bb2 ], [ true, %bb1 ]
|
%tmp4 = phi i1 [ undef, %bb ], [ false, %bb2 ], [ true, %bb1 ]
|
||||||
ret i1 %tmp4
|
ret i1 %tmp4
|
||||||
|
; CHECK-LABEL: define i1 @undef(
|
||||||
|
; CHECK: %switch.cast = trunc i32 %tmp to i9
|
||||||
|
; CHECK: %switch.downshift = lshr i9 3, %switch.shiftamt
|
||||||
}
|
}
|
||||||
|
|
||||||
; Also handle large switches that would be rejected by
|
; Also handle large switches that would be rejected by
|
||||||
; isValueEqualityComparison()
|
; isValueEqualityComparison()
|
||||||
|
; CHECK: large
|
||||||
|
; CHECK-NOT: switch i32
|
||||||
define i32 @large(i32 %x) {
|
define i32 @large(i32 %x) {
|
||||||
; CHECK-LABEL: @large(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
|
|
||||||
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X]], -10
|
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 [[MUL]], i32 [[X]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[SPEC_SELECT]], 1
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 199
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [199 x i32], [199 x i32]* @switch.table.large, i32 0, i32 [[SWITCH_TABLEIDX]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i32 0
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp slt i32 %x, 0
|
%cmp = icmp slt i32 %x, 0
|
||||||
br i1 %cmp, label %if.then, label %if.end
|
br i1 %cmp, label %if.then, label %if.end
|
||||||
|
@ -806,18 +755,6 @@ return:
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @cprop(i32 %x, i32 %y) {
|
define i32 @cprop(i32 %x, i32 %y) {
|
||||||
; CHECK-LABEL: @cprop(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[X:%.*]], 1
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 7
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.cprop, i32 0, i32 [[SWITCH_TABLEIDX]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i32 123
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 1, label %return
|
i32 1, label %return
|
||||||
|
@ -853,20 +790,12 @@ return:
|
||||||
%retval.0 = phi i32 [ 123, %sw.default ], [ %select, %sw.bb3 ], [ %sub, %sw.bb2 ], [ 42, %sw.bb1 ], [ 5, %entry ]
|
%retval.0 = phi i32 [ 123, %sw.default ], [ %select, %sw.bb3 ], [ %sub, %sw.bb2 ], [ 42, %sw.bb1 ], [ 5, %entry ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @cprop(
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK: %switch.gep = getelementptr inbounds [7 x i32], [7 x i32]* @switch.table.cprop, i32 0, i32 %switch.tableidx
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @unreachable_case(i32 %x) {
|
define i32 @unreachable_case(i32 %x) {
|
||||||
; CHECK-LABEL: @unreachable_case(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 9
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [9 x i32], [9 x i32]* @switch.table.unreachable_case, i32 0, i32 [[X]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i32 2
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %sw.bb
|
i32 0, label %sw.bb
|
||||||
|
@ -890,15 +819,12 @@ return:
|
||||||
%retval.0 = phi i32 [ 1, %sw.bb3 ], [ -1, %sw.bb2 ], [ 0, %sw.bb ], [ 2, %sw.default ]
|
%retval.0 = phi i32 [ 1, %sw.bb3 ], [ -1, %sw.bb2 ], [ 0, %sw.bb ], [ 2, %sw.default ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @unreachable_case(
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK: getelementptr inbounds [9 x i32], [9 x i32]* @switch.table.unreachable_case, i32 0, i32 %x
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @unreachable_default(i32 %x) {
|
define i32 @unreachable_default(i32 %x) {
|
||||||
; CHECK-LABEL: @unreachable_default(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.unreachable_default, i32 0, i32 [[X:%.*]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %default [
|
switch i32 %x, label %default [
|
||||||
i32 0, label %bb0
|
i32 0, label %bb0
|
||||||
|
@ -917,33 +843,17 @@ return:
|
||||||
%retval = phi i32 [ 42, %bb0 ], [ 52, %bb1 ], [ 1, %bb2 ], [ 2, %bb3 ]
|
%retval = phi i32 [ 42, %bb0 ], [ 52, %bb1 ], [ 1, %bb2 ], [ 2, %bb3 ]
|
||||||
ret i32 %retval
|
ret i32 %retval
|
||||||
|
|
||||||
|
; CHECK-LABEL: @unreachable_default(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NOT: icmp
|
||||||
|
; CHECK-NOT: br 1i
|
||||||
|
; CHECK-NEXT: %switch.gep = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.unreachable_default, i32 0, i32 %x
|
||||||
|
; CHECK-NEXT: %switch.load = load i32, i32* %switch.gep
|
||||||
|
; CHECK-NEXT: ret i32 %switch.load
|
||||||
}
|
}
|
||||||
|
|
||||||
; Don't create a table with illegal type
|
; Don't create a table with illegal type
|
||||||
define i96 @illegaltype(i32 %c) {
|
define i96 @illegaltype(i32 %c) {
|
||||||
; CHECK-LABEL: @illegaltype(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 42, label [[RETURN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 43, label [[SW_BB1:%.*]]
|
|
||||||
; CHECK-NEXT: i32 44, label [[SW_BB2:%.*]]
|
|
||||||
; CHECK-NEXT: i32 45, label [[SW_BB3:%.*]]
|
|
||||||
; CHECK-NEXT: i32 46, label [[SW_BB4:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: sw.bb1:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb2:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb3:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb4:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.default:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i96 [ 15, [[SW_DEFAULT]] ], [ 27, [[SW_BB4]] ], [ -1, [[SW_BB3]] ], [ 0, [[SW_BB2]] ], [ 123, [[SW_BB1]] ], [ 55, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: ret i96 [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 42, label %return
|
i32 42, label %return
|
||||||
|
@ -962,23 +872,14 @@ return:
|
||||||
%retval.0 = phi i96 [ 15, %sw.default ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
%retval.0 = phi i96 [ 15, %sw.default ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
||||||
ret i96 %retval.0
|
ret i96 %retval.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @illegaltype(
|
||||||
|
; CHECK-NOT: @switch.table
|
||||||
|
; CHECK: switch i32 %c
|
||||||
}
|
}
|
||||||
|
|
||||||
; If we can build a lookup table without any holes, we don't need a default result.
|
; If we can build a lookup table without any holes, we don't need a default result.
|
||||||
declare void @exit(i32)
|
declare void @exit(i32)
|
||||||
define i32 @nodefaultnoholes(i32 %c) {
|
define i32 @nodefaultnoholes(i32 %c) {
|
||||||
; CHECK-LABEL: @nodefaultnoholes(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[C:%.*]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[SW_DEFAULT:%.*]]
|
|
||||||
; CHECK: sw.default:
|
|
||||||
; CHECK-NEXT: call void @exit(i32 1)
|
|
||||||
; CHECK-NEXT: unreachable
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* @switch.table.nodefaultnoholes, i32 0, i32 [[C]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 0, label %return
|
i32 0, label %return
|
||||||
|
@ -996,27 +897,13 @@ return:
|
||||||
%x = phi i32 [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
%x = phi i32 [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
|
|
||||||
|
; CHECK-LABEL: @nodefaultnoholes(
|
||||||
|
; CHECK: @switch.table
|
||||||
|
; CHECK-NOT: switch i32
|
||||||
}
|
}
|
||||||
|
|
||||||
; This lookup table will have holes, so we need to test for the holes.
|
; This lookup table will have holes, so we need to test for the holes.
|
||||||
define i32 @nodefaultwithholes(i32 %c) {
|
define i32 @nodefaultwithholes(i32 %c) {
|
||||||
; CHECK-LABEL: @nodefaultwithholes(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[C:%.*]], 6
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_HOLE_CHECK:%.*]], label [[SW_DEFAULT:%.*]]
|
|
||||||
; CHECK: sw.default:
|
|
||||||
; CHECK-NEXT: call void @exit(i32 1)
|
|
||||||
; CHECK-NEXT: unreachable
|
|
||||||
; CHECK: switch.hole_check:
|
|
||||||
; CHECK-NEXT: [[SWITCH_MASKINDEX:%.*]] = trunc i32 [[C]] to i8
|
|
||||||
; CHECK-NEXT: [[SWITCH_SHIFTED:%.*]] = lshr i8 47, [[SWITCH_MASKINDEX]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOBIT:%.*]] = trunc i8 [[SWITCH_SHIFTED]] to i1
|
|
||||||
; CHECK-NEXT: br i1 [[SWITCH_LOBIT]], label [[SWITCH_LOOKUP:%.*]], label [[SW_DEFAULT]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [6 x i32], [6 x i32]* @switch.table.nodefaultwithholes, i32 0, i32 [[C]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 0, label %return
|
i32 0, label %return
|
||||||
|
@ -1035,28 +922,20 @@ return:
|
||||||
%x = phi i32 [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
%x = phi i32 [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ]
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
|
|
||||||
|
; CHECK-LABEL: @nodefaultwithholes(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK: br i1 %{{.*}}, label %switch.hole_check, label %sw.default
|
||||||
|
; CHECK: switch.hole_check:
|
||||||
|
; CHECK-NEXT: %switch.maskindex = trunc i32 %c to i8
|
||||||
|
; CHECK-NEXT: %switch.shifted = lshr i8 47, %switch.maskindex
|
||||||
; The mask is binary 101111.
|
; The mask is binary 101111.
|
||||||
|
; CHECK-NEXT: %switch.lobit = trunc i8 %switch.shifted to i1
|
||||||
|
; CHECK-NEXT: br i1 %switch.lobit, label %switch.lookup, label %sw.default
|
||||||
|
; CHECK-NOT: switch i32
|
||||||
}
|
}
|
||||||
|
|
||||||
; We don't build lookup tables with holes for switches with less than four cases.
|
; We don't build lookup tables with holes for switches with less than four cases.
|
||||||
define i32 @threecasesholes(i32 %c) {
|
define i32 @threecasesholes(i32 %c) {
|
||||||
; CHECK-LABEL: @threecasesholes(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 0, label [[RETURN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]]
|
|
||||||
; CHECK-NEXT: i32 3, label [[SW_BB2:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: sw.bb1:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb2:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.default:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[C]], [[SW_DEFAULT]] ], [ 5, [[SW_BB2]] ], [ 7, [[SW_BB1]] ], [ 9, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: ret i32 [[X]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 0, label %return
|
i32 0, label %return
|
||||||
|
@ -1069,16 +948,19 @@ sw.default: br label %return
|
||||||
return:
|
return:
|
||||||
%x = phi i32 [ %c, %sw.default ], [ 5, %sw.bb2 ], [ 7, %sw.bb1 ], [ 9, %entry ]
|
%x = phi i32 [ %c, %sw.default ], [ 5, %sw.bb2 ], [ 7, %sw.bb1 ], [ 9, %entry ]
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
|
; CHECK-LABEL: @threecasesholes(
|
||||||
|
; CHECK: switch i32
|
||||||
|
; CHECK-NOT: @switch.table
|
||||||
}
|
}
|
||||||
|
|
||||||
; We build lookup tables for switches with three or more cases.
|
; We build lookup tables for switches with three or more cases.
|
||||||
define i32 @threecases(i32 %c) {
|
define i32 @threecases(i32 %c) {
|
||||||
; CHECK-LABEL: @threecases(
|
; CHECK-LABEL: @threecases(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[C:%.*]], 3
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 %c, 3
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
; CHECK-NEXT: br i1 [[TMP0]], label %switch.lookup, label %return
|
||||||
; CHECK: switch.lookup:
|
; CHECK: switch.lookup:
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32], [3 x i32]* @switch.table.threecases, i32 0, i32 [[C]]
|
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i32], [3 x i32]* @switch.table.threecases, i32 0, i32 %c
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
; CHECK-NEXT: ret i32 [[SWITCH_LOAD]]
|
||||||
; CHECK: return:
|
; CHECK: return:
|
||||||
|
@ -1105,9 +987,9 @@ return:
|
||||||
define i32 @twocases(i32 %c) {
|
define i32 @twocases(i32 %c) {
|
||||||
; CHECK-LABEL: @twocases(
|
; CHECK-LABEL: @twocases(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[C:%.*]], 1
|
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 %c, 1
|
||||||
; CHECK-NEXT: [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 7, i32 3
|
; CHECK-NEXT: [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP:%.*]], i32 7, i32 3
|
||||||
; CHECK-NEXT: [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 [[C]], 0
|
; CHECK-NEXT: [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 %c, 0
|
||||||
; CHECK-NEXT: [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], i32 9, i32 [[SWITCH_SELECT]]
|
; CHECK-NEXT: [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], i32 9, i32 [[SWITCH_SELECT]]
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_SELECT2]]
|
; CHECK-NEXT: ret i32 [[SWITCH_SELECT2]]
|
||||||
;
|
;
|
||||||
|
@ -1131,23 +1013,6 @@ return:
|
||||||
@tls_c = thread_local global i32 0
|
@tls_c = thread_local global i32 0
|
||||||
@tls_d = thread_local global i32 0
|
@tls_d = thread_local global i32 0
|
||||||
define i32* @tls(i32 %x) {
|
define i32* @tls(i32 %x) {
|
||||||
; CHECK-LABEL: @tls(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[SW_DEFAULT:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 0, label [[RETURN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]]
|
|
||||||
; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: sw.bb1:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb2:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.default:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32* [ @tls_d, [[SW_DEFAULT]] ], [ @tls_c, [[SW_BB2]] ], [ @tls_b, [[SW_BB1]] ], [ @tls_a, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: ret i32* [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %return
|
i32 0, label %return
|
||||||
|
@ -1163,6 +1028,9 @@ sw.default:
|
||||||
return:
|
return:
|
||||||
%retval.0 = phi i32* [ @tls_d, %sw.default ], [ @tls_c, %sw.bb2 ], [ @tls_b, %sw.bb1 ], [ @tls_a, %entry ]
|
%retval.0 = phi i32* [ @tls_d, %sw.default ], [ @tls_c, %sw.bb2 ], [ @tls_b, %sw.bb1 ], [ @tls_a, %entry ]
|
||||||
ret i32* %retval.0
|
ret i32* %retval.0
|
||||||
|
; CHECK-LABEL: @tls(
|
||||||
|
; CHECK: switch i32
|
||||||
|
; CHECK-NOT: @switch.table
|
||||||
}
|
}
|
||||||
|
|
||||||
; Don't build tables for switches with dllimport variables.
|
; Don't build tables for switches with dllimport variables.
|
||||||
|
@ -1171,23 +1039,6 @@ return:
|
||||||
@dllimport_c = external dllimport global [3x i32]
|
@dllimport_c = external dllimport global [3x i32]
|
||||||
@dllimport_d = external dllimport global [3x i32]
|
@dllimport_d = external dllimport global [3x i32]
|
||||||
define i32* @dllimport(i32 %x) {
|
define i32* @dllimport(i32 %x) {
|
||||||
; CHECK-LABEL: @dllimport(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[SW_DEFAULT:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 0, label [[RETURN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]]
|
|
||||||
; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: sw.bb1:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.bb2:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: sw.default:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32* [ getelementptr inbounds ([3 x i32], [3 x i32]* @dllimport_d, i32 0, i32 0), [[SW_DEFAULT]] ], [ getelementptr inbounds ([3 x i32], [3 x i32]* @dllimport_c, i32 0, i32 0), [[SW_BB2]] ], [ getelementptr inbounds ([3 x i32], [3 x i32]* @dllimport_b, i32 0, i32 0), [[SW_BB1]] ], [ getelementptr inbounds ([3 x i32], [3 x i32]* @dllimport_a, i32 0, i32 0), [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: ret i32* [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %return
|
i32 0, label %return
|
||||||
|
@ -1206,23 +1057,13 @@ return:
|
||||||
[ getelementptr inbounds ([3 x i32], [3 x i32]* @dllimport_b, i32 0, i32 0), %sw.bb1 ],
|
[ getelementptr inbounds ([3 x i32], [3 x i32]* @dllimport_b, i32 0, i32 0), %sw.bb1 ],
|
||||||
[ getelementptr inbounds ([3 x i32], [3 x i32]* @dllimport_a, i32 0, i32 0), %entry ]
|
[ getelementptr inbounds ([3 x i32], [3 x i32]* @dllimport_a, i32 0, i32 0), %entry ]
|
||||||
ret i32* %retval.0
|
ret i32* %retval.0
|
||||||
|
; CHECK-LABEL: @dllimport(
|
||||||
|
; CHECK: switch i32
|
||||||
|
; CHECK-NOT: @switch.table
|
||||||
}
|
}
|
||||||
|
|
||||||
; We can use linear mapping.
|
; We can use linear mapping.
|
||||||
define i8 @linearmap1(i32 %c) {
|
define i8 @linearmap1(i32 %c) {
|
||||||
; CHECK-LABEL: @linearmap1(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8
|
|
||||||
; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], -5
|
|
||||||
; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i8 [[SWITCH_IDX_MULT]], 18
|
|
||||||
; CHECK-NEXT: ret i8 [[SWITCH_OFFSET]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i8 3
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 10, label %return
|
i32 10, label %return
|
||||||
|
@ -1237,22 +1078,18 @@ sw.default: br label %return
|
||||||
return:
|
return:
|
||||||
%x = phi i8 [ 3, %sw.default ], [ 3, %sw.bb3 ], [ 8, %sw.bb2 ], [ 13, %sw.bb1 ], [ 18, %entry ]
|
%x = phi i8 [ 3, %sw.default ], [ 3, %sw.bb3 ], [ 8, %sw.bb2 ], [ 13, %sw.bb1 ], [ 18, %entry ]
|
||||||
ret i8 %x
|
ret i8 %x
|
||||||
|
; CHECK-LABEL: @linearmap1(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %switch.tableidx = sub i32 %c, 10
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.idx.cast = trunc i32 %switch.tableidx to i8
|
||||||
|
; CHECK-NEXT: %switch.idx.mult = mul i8 %switch.idx.cast, -5
|
||||||
|
; CHECK-NEXT: %switch.offset = add i8 %switch.idx.mult, 18
|
||||||
|
; CHECK-NEXT: ret i8 %switch.offset
|
||||||
}
|
}
|
||||||
|
|
||||||
; Linear mapping in a different configuration.
|
; Linear mapping in a different configuration.
|
||||||
define i32 @linearmap2(i8 %c) {
|
define i32 @linearmap2(i8 %c) {
|
||||||
; CHECK-LABEL: @linearmap2(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[C:%.*]], -13
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = zext i8 [[SWITCH_TABLEIDX]] to i32
|
|
||||||
; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[SWITCH_IDX_CAST]], 18
|
|
||||||
; CHECK-NEXT: ret i32 [[SWITCH_OFFSET]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i32 3
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i8 %c, label %sw.default [
|
switch i8 %c, label %sw.default [
|
||||||
i8 -10, label %return
|
i8 -10, label %return
|
||||||
|
@ -1267,22 +1104,17 @@ sw.default: br label %return
|
||||||
return:
|
return:
|
||||||
%x = phi i32 [ 3, %sw.default ], [ 18, %sw.bb3 ], [ 19, %sw.bb2 ], [ 20, %sw.bb1 ], [ 21, %entry ]
|
%x = phi i32 [ 3, %sw.default ], [ 18, %sw.bb3 ], [ 19, %sw.bb2 ], [ 20, %sw.bb1 ], [ 21, %entry ]
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
|
; CHECK-LABEL: @linearmap2(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %switch.tableidx = sub i8 %c, -13
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.idx.cast = zext i8 %switch.tableidx to i32
|
||||||
|
; CHECK-NEXT: %switch.offset = add i32 %switch.idx.cast, 18
|
||||||
|
; CHECK-NEXT: ret i32 %switch.offset
|
||||||
}
|
}
|
||||||
|
|
||||||
; Linear mapping with overflows.
|
; Linear mapping with overflows.
|
||||||
define i8 @linearmap3(i32 %c) {
|
define i8 @linearmap3(i32 %c) {
|
||||||
; CHECK-LABEL: @linearmap3(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], 10
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8
|
|
||||||
; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i8 [[SWITCH_IDX_CAST]], 100
|
|
||||||
; CHECK-NEXT: ret i8 [[SWITCH_IDX_MULT]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i8 3
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 10, label %return
|
i32 10, label %return
|
||||||
|
@ -1297,21 +1129,17 @@ sw.default: br label %return
|
||||||
return:
|
return:
|
||||||
%x = phi i8 [ 3, %sw.default ], [ 44, %sw.bb3 ], [ -56, %sw.bb2 ], [ 100, %sw.bb1 ], [ 0, %entry ]
|
%x = phi i8 [ 3, %sw.default ], [ 44, %sw.bb3 ], [ -56, %sw.bb2 ], [ 100, %sw.bb1 ], [ 0, %entry ]
|
||||||
ret i8 %x
|
ret i8 %x
|
||||||
|
; CHECK-LABEL: @linearmap3(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %switch.tableidx = sub i32 %c, 10
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.idx.cast = trunc i32 %switch.tableidx to i8
|
||||||
|
; CHECK-NEXT: %switch.idx.mult = mul i8 %switch.idx.cast, 100
|
||||||
|
; CHECK-NEXT: ret i8 %switch.idx.mult
|
||||||
}
|
}
|
||||||
|
|
||||||
; Linear mapping with with multiplier 1 and offset 0.
|
; Linear mapping with with multiplier 1 and offset 0.
|
||||||
define i8 @linearmap4(i32 %c) {
|
define i8 @linearmap4(i32 %c) {
|
||||||
; CHECK-LABEL: @linearmap4(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i32 [[C:%.*]], -2
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[SWITCH_TABLEIDX]], 4
|
|
||||||
; CHECK-NEXT: br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i32 [[SWITCH_TABLEIDX]] to i8
|
|
||||||
; CHECK-NEXT: ret i8 [[SWITCH_IDX_CAST]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret i8 3
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %c, label %sw.default [
|
switch i32 %c, label %sw.default [
|
||||||
i32 -2, label %return
|
i32 -2, label %return
|
||||||
|
@ -1326,20 +1154,16 @@ sw.default: br label %return
|
||||||
return:
|
return:
|
||||||
%x = phi i8 [ 3, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 1, %sw.bb1 ], [ 0, %entry ]
|
%x = phi i8 [ 3, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 1, %sw.bb1 ], [ 0, %entry ]
|
||||||
ret i8 %x
|
ret i8 %x
|
||||||
|
; CHECK-LABEL: @linearmap4(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %switch.tableidx = sub i32 %c, -2
|
||||||
|
; CHECK: switch.lookup:
|
||||||
|
; CHECK-NEXT: %switch.idx.cast = trunc i32 %switch.tableidx to i8
|
||||||
|
; CHECK-NEXT: ret i8 %switch.idx.cast
|
||||||
}
|
}
|
||||||
|
|
||||||
; Reuse the inverted table range compare.
|
; Reuse the inverted table range compare.
|
||||||
define i32 @reuse_cmp1(i32 %x) {
|
define i32 @reuse_cmp1(i32 %x) {
|
||||||
; CHECK-LABEL: @reuse_cmp1(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
|
|
||||||
; CHECK-NEXT: [[INVERTED_CMP:%.*]] = xor i1 [[TMP0]], true
|
|
||||||
; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[X]], 10
|
|
||||||
; CHECK-NEXT: [[R_0:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[R_0]], 0
|
|
||||||
; CHECK-NEXT: [[DOTR_0:%.*]] = select i1 [[INVERTED_CMP]], i32 100, i32 [[R_0]]
|
|
||||||
; CHECK-NEXT: ret i32 [[DOTR_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %sw.bb
|
i32 0, label %sw.bb
|
||||||
|
@ -1361,18 +1185,16 @@ if.end: br label %return
|
||||||
return:
|
return:
|
||||||
%retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
|
%retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
; CHECK-LABEL: @reuse_cmp1(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: [[C:%.+]] = icmp ult i32 %x, 4
|
||||||
|
; CHECK-NEXT: %inverted.cmp = xor i1 [[C]], true
|
||||||
|
; CHECK: [[R:%.+]] = select i1 %inverted.cmp, i32 100, i32 {{.*}}
|
||||||
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
}
|
}
|
||||||
|
|
||||||
; Reuse the table range compare.
|
; Reuse the table range compare.
|
||||||
define i32 @reuse_cmp2(i32 %x) {
|
define i32 @reuse_cmp2(i32 %x) {
|
||||||
; CHECK-LABEL: @reuse_cmp2(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
|
|
||||||
; CHECK-NEXT: [[X_:%.*]] = select i1 [[TMP0]], i32 [[X]], i32 4
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X_]], 4
|
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = select i1 [[TMP0]], i32 [[X_]], i32 100
|
|
||||||
; CHECK-NEXT: ret i32 [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %sw.bb
|
i32 0, label %sw.bb
|
||||||
|
@ -1394,20 +1216,18 @@ if.end: br label %return
|
||||||
return:
|
return:
|
||||||
%retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
|
%retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
; CHECK-LABEL: @reuse_cmp2(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK-NEXT: %0 = icmp ult i32 %x, 4
|
||||||
|
; CHECK-NEXT: %x. = select i1 %0, i32 %x, i32 4
|
||||||
|
; CHECK-NEXT: [[C:%.+]] = icmp ne i32 %x., 4
|
||||||
|
; CHECK: [[R:%.+]] = select i1 %0, i32 {{.*}}, i32 100
|
||||||
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot reuse the table range compare, because the default value is the same
|
; Cannot reuse the table range compare, because the default value is the same
|
||||||
; as one of the case values.
|
; as one of the case values.
|
||||||
define i32 @no_reuse_cmp(i32 %x) {
|
define i32 @no_reuse_cmp(i32 %x) {
|
||||||
; CHECK-LABEL: @no_reuse_cmp(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
|
|
||||||
; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[X]], 10
|
|
||||||
; CHECK-NEXT: [[R_0:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 12
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[R_0]], 0
|
|
||||||
; CHECK-NEXT: [[R_0_:%.*]] = select i1 [[CMP]], i32 [[R_0]], i32 100
|
|
||||||
; CHECK-NEXT: ret i32 [[R_0_]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %sw.default [
|
switch i32 %x, label %sw.default [
|
||||||
i32 0, label %sw.bb
|
i32 0, label %sw.bb
|
||||||
|
@ -1429,26 +1249,16 @@ if.end: br label %return
|
||||||
return:
|
return:
|
||||||
%retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
|
%retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
; CHECK-LABEL: @no_reuse_cmp(
|
||||||
|
; CHECK: [[S:%.+]] = select
|
||||||
|
; CHECK-NEXT: %cmp = icmp ne i32 [[S]], 0
|
||||||
|
; CHECK-NEXT: [[R:%.+]] = select i1 %cmp, i32 [[S]], i32 100
|
||||||
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot reuse the table range compare, because the phi at the switch merge
|
; Cannot reuse the table range compare, because the phi at the switch merge
|
||||||
; point is not dominated by the switch.
|
; point is not dominated by the switch.
|
||||||
define i32 @no_reuse_cmp2(i32 %x, i32 %y) {
|
define i32 @no_reuse_cmp2(i32 %x, i32 %y) {
|
||||||
; CHECK-LABEL: @no_reuse_cmp2(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[EC:%.*]] = icmp ne i32 [[Y:%.*]], 0
|
|
||||||
; CHECK-NEXT: br i1 [[EC]], label [[SWITCH_ENTRY:%.*]], label [[SW_EPILOG:%.*]]
|
|
||||||
; CHECK: switch.entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X:%.*]], 4
|
|
||||||
; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i32 [[X]], 10
|
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SWITCH_OFFSET]], i32 0
|
|
||||||
; CHECK-NEXT: br label [[SW_EPILOG]]
|
|
||||||
; CHECK: sw.epilog:
|
|
||||||
; CHECK-NEXT: [[R_0:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[SWITCH_ENTRY]] ]
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[R_0]], 0
|
|
||||||
; CHECK-NEXT: [[DOTR_0:%.*]] = select i1 [[CMP]], i32 100, i32 [[R_0]]
|
|
||||||
; CHECK-NEXT: ret i32 [[DOTR_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%ec = icmp ne i32 %y, 0
|
%ec = icmp ne i32 %y, 0
|
||||||
br i1 %ec, label %switch.entry, label %sw.epilog
|
br i1 %ec, label %switch.entry, label %sw.epilog
|
||||||
|
@ -1473,39 +1283,18 @@ if.end: br label %return
|
||||||
return:
|
return:
|
||||||
%retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
|
%retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
; CHECK-LABEL: @no_reuse_cmp2(
|
||||||
|
; CHECK: %r.0 = phi
|
||||||
|
; CHECK-NEXT: %cmp = icmp eq i32 %r.0, 0
|
||||||
|
; CHECK-NEXT: [[R:%.+]] = select i1 %cmp
|
||||||
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @pr20210(i8 %x, i1 %y) {
|
define void @pr20210(i8 %x, i1 %y) {
|
||||||
; %z has uses outside of its BB or the phi it feeds into,
|
; %z has uses outside of its BB or the phi it feeds into,
|
||||||
; so doing a table lookup and jumping directly to while.cond would
|
; so doing a table lookup and jumping directly to while.cond would
|
||||||
; cause %z to cease dominating all its uses.
|
; cause %z to cease dominating all its uses.
|
||||||
; CHECK-LABEL: @pr20210(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: br i1 [[Y:%.*]], label [[SW:%.*]], label [[INTERMEDIATE:%.*]]
|
|
||||||
; CHECK: sw:
|
|
||||||
; CHECK-NEXT: switch i8 [[X:%.*]], label [[END:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 7, label [[INTERMEDIATE]]
|
|
||||||
; CHECK-NEXT: i8 3, label [[INTERMEDIATE]]
|
|
||||||
; CHECK-NEXT: i8 2, label [[INTERMEDIATE]]
|
|
||||||
; CHECK-NEXT: i8 1, label [[INTERMEDIATE]]
|
|
||||||
; CHECK-NEXT: i8 0, label [[INTERMEDIATE]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: intermediate:
|
|
||||||
; CHECK-NEXT: [[Z:%.*]] = zext i8 [[X]] to i32
|
|
||||||
; CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
|
||||||
; CHECK: while.cond:
|
|
||||||
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[Z]], [[INTERMEDIATE]] ], [ [[J:%.*]], [[WHILE_BODY:%.*]] ]
|
|
||||||
; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[I]], 7
|
|
||||||
; CHECK-NEXT: br i1 [[B]], label [[WHILE_BODY]], label [[WHILE_END:%.*]]
|
|
||||||
; CHECK: while.body:
|
|
||||||
; CHECK-NEXT: [[J]] = add i32 [[I]], 1
|
|
||||||
; CHECK-NEXT: br label [[WHILE_COND]]
|
|
||||||
; CHECK: while.end:
|
|
||||||
; CHECK-NEXT: call void @exit(i32 [[Z]])
|
|
||||||
; CHECK-NEXT: unreachable
|
|
||||||
; CHECK: end:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
br i1 %y, label %sw, label %intermediate
|
br i1 %y, label %sw, label %intermediate
|
||||||
|
|
||||||
|
@ -1537,6 +1326,8 @@ while.end:
|
||||||
|
|
||||||
end:
|
end:
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @pr20210
|
||||||
|
; CHECK: switch i8 %x
|
||||||
}
|
}
|
||||||
|
|
||||||
; Make sure we do not crash due to trying to generate an unguarded
|
; Make sure we do not crash due to trying to generate an unguarded
|
||||||
|
@ -1544,22 +1335,6 @@ end:
|
||||||
; values) and simultaneously trying to generate a branch to deal with
|
; values) and simultaneously trying to generate a branch to deal with
|
||||||
; the fact that we have holes in the range.
|
; the fact that we have holes in the range.
|
||||||
define i32 @covered_switch_with_bit_tests(i3) {
|
define i32 @covered_switch_with_bit_tests(i3) {
|
||||||
; CHECK-LABEL: @covered_switch_with_bit_tests(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[TMP0:%.*]], -4
|
|
||||||
; CHECK-NEXT: [[SWITCH_MASKINDEX:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i8
|
|
||||||
; CHECK-NEXT: [[SWITCH_SHIFTED:%.*]] = lshr i8 -61, [[SWITCH_MASKINDEX]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOBIT:%.*]] = trunc i8 [[SWITCH_SHIFTED]] to i1
|
|
||||||
; CHECK-NEXT: br i1 [[SWITCH_LOBIT]], label [[SWITCH_LOOKUP:%.*]], label [[L6:%.*]]
|
|
||||||
; CHECK: switch.lookup:
|
|
||||||
; CHECK-NEXT: [[SWITCH_TABLEIDX_ZEXT:%.*]] = zext i3 [[SWITCH_TABLEIDX]] to i4
|
|
||||||
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @switch.table.covered_switch_with_bit_tests, i32 0, i4 [[SWITCH_TABLEIDX_ZEXT]]
|
|
||||||
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, i32* [[SWITCH_GEP]]
|
|
||||||
; CHECK-NEXT: br label [[L6]]
|
|
||||||
; CHECK: l6:
|
|
||||||
; CHECK-NEXT: [[R:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SWITCH_LOAD]], [[SWITCH_LOOKUP]] ]
|
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i3 %0, label %l6 [
|
switch i3 %0, label %l6 [
|
||||||
i3 -3, label %l5
|
i3 -3, label %l5
|
||||||
|
@ -1579,17 +1354,18 @@ l5: br label %l2
|
||||||
l6:
|
l6:
|
||||||
%r = phi i32 [ %x, %l2 ], [ 0, %entry ]
|
%r = phi i32 [ %x, %l2 ], [ 0, %entry ]
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
|
; CHECK-LABEL: @covered_switch_with_bit_tests
|
||||||
|
; CHECK: entry
|
||||||
|
; CHECK-NEXT: switch
|
||||||
}
|
}
|
||||||
|
|
||||||
; Speculation depth must be limited to avoid a zero-cost instruction cycle.
|
; Speculation depth must be limited to avoid a zero-cost instruction cycle.
|
||||||
|
|
||||||
define i32 @PR26308(i1 %B, i64 %load) {
|
|
||||||
; CHECK-LABEL: @PR26308(
|
; CHECK-LABEL: @PR26308(
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: br label [[CLEANUP4:%.*]]
|
|
||||||
; CHECK: cleanup4:
|
; CHECK: cleanup4:
|
||||||
; CHECK-NEXT: br label [[CLEANUP4]]
|
; CHECK-NEXT: br label %cleanup4
|
||||||
;
|
|
||||||
|
define i32 @PR26308(i1 %B, i64 %load) {
|
||||||
entry:
|
entry:
|
||||||
br label %while.body
|
br label %while.body
|
||||||
|
|
||||||
|
@ -1617,29 +1393,6 @@ cleanup4:
|
||||||
declare void @throw(i1)
|
declare void @throw(i1)
|
||||||
|
|
||||||
define void @wineh_test(i64 %val) personality i32 (...)* @__CxxFrameHandler3 {
|
define void @wineh_test(i64 %val) personality i32 (...)* @__CxxFrameHandler3 {
|
||||||
; CHECK-LABEL: @wineh_test(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: invoke void @throw(i1 false)
|
|
||||||
; CHECK-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[CLEANUP1:%.*]]
|
|
||||||
; CHECK: unreachable:
|
|
||||||
; CHECK-NEXT: unreachable
|
|
||||||
; CHECK: cleanup1:
|
|
||||||
; CHECK-NEXT: [[CLEANUPPAD1:%.*]] = cleanuppad within none []
|
|
||||||
; CHECK-NEXT: switch i64 [[VAL:%.*]], label [[CLEANUPDONE2:%.*]] [
|
|
||||||
; CHECK-NEXT: i64 0, label [[CLEANUPDONE1:%.*]]
|
|
||||||
; CHECK-NEXT: i64 1, label [[CLEANUPDONE1]]
|
|
||||||
; CHECK-NEXT: i64 6, label [[CLEANUPDONE1]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: cleanupdone1:
|
|
||||||
; CHECK-NEXT: cleanupret from [[CLEANUPPAD1]] unwind label [[CLEANUP2:%.*]]
|
|
||||||
; CHECK: cleanupdone2:
|
|
||||||
; CHECK-NEXT: cleanupret from [[CLEANUPPAD1]] unwind label [[CLEANUP2]]
|
|
||||||
; CHECK: cleanup2:
|
|
||||||
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ true, [[CLEANUPDONE1]] ], [ false, [[CLEANUPDONE2]] ]
|
|
||||||
; CHECK-NEXT: [[CLEANUPPAD2:%.*]] = cleanuppad within none []
|
|
||||||
; CHECK-NEXT: call void @throw(i1 [[PHI]]) [ "funclet"(token [[CLEANUPPAD2]]) ]
|
|
||||||
; CHECK-NEXT: unreachable
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
invoke void @throw(i1 false)
|
invoke void @throw(i1 false)
|
||||||
to label %unreachable unwind label %cleanup1
|
to label %unreachable unwind label %cleanup1
|
||||||
|
@ -1668,4 +1421,32 @@ cleanup2:
|
||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: @wineh_test(
|
||||||
|
; CHECK: entry:
|
||||||
|
; CHECK: invoke void @throw(i1 false)
|
||||||
|
; CHECK: to label %[[unreachable:.*]] unwind label %[[cleanup1:.*]]
|
||||||
|
|
||||||
|
; CHECK: [[unreachable]]:
|
||||||
|
; CHECK: unreachable
|
||||||
|
|
||||||
|
; CHECK: [[cleanup1]]:
|
||||||
|
; CHECK: %[[cleanuppad1:.*]] = cleanuppad within none []
|
||||||
|
; CHECK: switch i64 %val, label %[[cleanupdone2:.*]] [
|
||||||
|
; CHECK: i64 0, label %[[cleanupdone1:.*]]
|
||||||
|
; CHECK: i64 1, label %[[cleanupdone1]]
|
||||||
|
; CHECK: i64 6, label %[[cleanupdone1]]
|
||||||
|
; CHECK: ]
|
||||||
|
|
||||||
|
; CHECK: [[cleanupdone1]]:
|
||||||
|
; CHECK: cleanupret from %[[cleanuppad1]] unwind label %[[cleanup2:.*]]
|
||||||
|
|
||||||
|
; CHECK: [[cleanupdone2]]:
|
||||||
|
; CHECK: cleanupret from %[[cleanuppad1]] unwind label %[[cleanup2]]
|
||||||
|
|
||||||
|
; CHECK: [[cleanup2]]:
|
||||||
|
; CHECK: %[[phi:.*]] = phi i1 [ true, %[[cleanupdone1]] ], [ false, %[[cleanupdone2]] ]
|
||||||
|
; CHECK: %[[cleanuppad2:.*]] = cleanuppad within none []
|
||||||
|
; CHECK: call void @throw(i1 %[[phi]]) [ "funclet"(token %[[cleanuppad2]]) ]
|
||||||
|
; CHECK: unreachable
|
||||||
|
|
||||||
declare i32 @__CxxFrameHandler3(...)
|
declare i32 @__CxxFrameHandler3(...)
|
||||||
|
|
|
@ -1,18 +1,9 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; RUN: opt %s -S -simplifycfg | FileCheck %s
|
||||||
; RUN: opt %s -S -passes='simplify-cfg<switch-to-lookup>' | FileCheck %s
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
||||||
declare void @foo(i32)
|
declare void @foo(i32)
|
||||||
|
|
||||||
define void @test(i1 %a) {
|
define void @test(i1 %a) {
|
||||||
; CHECK-LABEL: @test(
|
; CHECK-LABEL: @test
|
||||||
; CHECK-NEXT: br i1 [[A:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
|
||||||
; CHECK: true:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 1)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: false:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 3)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
switch i1 %a, label %default [i1 1, label %true
|
switch i1 %a, label %default [i1 1, label %true
|
||||||
i1 0, label %false]
|
i1 0, label %false]
|
||||||
true:
|
true:
|
||||||
|
@ -27,28 +18,7 @@ default:
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2(i2 %a) {
|
define void @test2(i2 %a) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2
|
||||||
; CHECK-NEXT: switch i2 [[A:%.*]], label [[DEFAULT1:%.*]] [
|
|
||||||
; CHECK-NEXT: i2 0, label [[CASE0:%.*]]
|
|
||||||
; CHECK-NEXT: i2 1, label [[CASE1:%.*]]
|
|
||||||
; CHECK-NEXT: i2 -2, label [[CASE2:%.*]]
|
|
||||||
; CHECK-NEXT: i2 -1, label [[CASE3:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: case0:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 0)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: case1:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 1)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: case2:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 2)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: case3:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 3)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: default1:
|
|
||||||
; CHECK-NEXT: unreachable
|
|
||||||
;
|
|
||||||
switch i2 %a, label %default [i2 0, label %case0
|
switch i2 %a, label %default [i2 0, label %case0
|
||||||
i2 1, label %case1
|
i2 1, label %case1
|
||||||
i2 2, label %case2
|
i2 2, label %case2
|
||||||
|
@ -66,6 +36,8 @@ case3:
|
||||||
call void @foo(i32 3)
|
call void @foo(i32 3)
|
||||||
ret void
|
ret void
|
||||||
default:
|
default:
|
||||||
|
; CHECK-LABEL: default1:
|
||||||
|
; CHECK-NEXT: unreachable
|
||||||
call void @foo(i32 4)
|
call void @foo(i32 4)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -73,25 +45,7 @@ default:
|
||||||
; This one is a negative test - we know the value of the default,
|
; This one is a negative test - we know the value of the default,
|
||||||
; but that's about it
|
; but that's about it
|
||||||
define void @test3(i2 %a) {
|
define void @test3(i2 %a) {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3
|
||||||
; CHECK-NEXT: switch i2 [[A:%.*]], label [[DEFAULT:%.*]] [
|
|
||||||
; CHECK-NEXT: i2 0, label [[CASE0:%.*]]
|
|
||||||
; CHECK-NEXT: i2 1, label [[CASE1:%.*]]
|
|
||||||
; CHECK-NEXT: i2 -2, label [[CASE2:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: case0:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 0)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: case1:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 1)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: case2:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 2)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: default:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 0)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
switch i2 %a, label %default [i2 0, label %case0
|
switch i2 %a, label %default [i2 0, label %case0
|
||||||
i2 1, label %case1
|
i2 1, label %case1
|
||||||
i2 2, label %case2]
|
i2 2, label %case2]
|
||||||
|
@ -106,6 +60,8 @@ case2:
|
||||||
call void @foo(i32 2)
|
call void @foo(i32 2)
|
||||||
ret void
|
ret void
|
||||||
default:
|
default:
|
||||||
|
; CHECK-LABEL: default:
|
||||||
|
; CHECK-NEXT: call void @foo
|
||||||
call void @foo(i32 0)
|
call void @foo(i32 0)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -113,21 +69,7 @@ default:
|
||||||
; Negative test - check for possible overflow when computing
|
; Negative test - check for possible overflow when computing
|
||||||
; number of possible cases.
|
; number of possible cases.
|
||||||
define void @test4(i128 %a) {
|
define void @test4(i128 %a) {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4
|
||||||
; CHECK-NEXT: switch i128 [[A:%.*]], label [[DEFAULT:%.*]] [
|
|
||||||
; CHECK-NEXT: i128 0, label [[CASE0:%.*]]
|
|
||||||
; CHECK-NEXT: i128 1, label [[CASE1:%.*]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: case0:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 0)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: case1:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 1)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: default:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 0)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
switch i128 %a, label %default [i128 0, label %case0
|
switch i128 %a, label %default [i128 0, label %case0
|
||||||
i128 1, label %case1]
|
i128 1, label %case1]
|
||||||
|
|
||||||
|
@ -138,24 +80,16 @@ case1:
|
||||||
call void @foo(i32 1)
|
call void @foo(i32 1)
|
||||||
ret void
|
ret void
|
||||||
default:
|
default:
|
||||||
|
; CHECK-LABEL: default:
|
||||||
|
; CHECK-NEXT: call void @foo
|
||||||
call void @foo(i32 0)
|
call void @foo(i32 0)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; All but one bit known zero
|
; All but one bit known zero
|
||||||
define void @test5(i8 %a) {
|
define void @test5(i8 %a) {
|
||||||
; CHECK-LABEL: @test5(
|
; CHECK-LABEL: @test5
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 2
|
; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
|
||||||
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp eq i8 [[A]], 1
|
|
||||||
; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
||||||
; CHECK: true:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 1)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: false:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 3)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%cmp = icmp ult i8 %a, 2
|
%cmp = icmp ult i8 %a, 2
|
||||||
call void @llvm.assume(i1 %cmp)
|
call void @llvm.assume(i1 %cmp)
|
||||||
switch i8 %a, label %default [i8 1, label %true
|
switch i8 %a, label %default [i8 1, label %true
|
||||||
|
@ -173,18 +107,9 @@ default:
|
||||||
|
|
||||||
;; All but one bit known one
|
;; All but one bit known one
|
||||||
define void @test6(i8 %a) {
|
define void @test6(i8 %a) {
|
||||||
; CHECK-LABEL: @test6(
|
; CHECK-LABEL: @test6
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A:%.*]], -3
|
; CHECK: @llvm.assume
|
||||||
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
|
; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp eq i8 [[A]], -1
|
|
||||||
; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
||||||
; CHECK: true:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 1)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: false:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 3)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = and i8 %a, 254
|
%and = and i8 %a, 254
|
||||||
%cmp = icmp eq i8 %and, 254
|
%cmp = icmp eq i8 %and, 254
|
||||||
call void @llvm.assume(i1 %cmp)
|
call void @llvm.assume(i1 %cmp)
|
||||||
|
@ -204,18 +129,9 @@ default:
|
||||||
; Check that we can eliminate both dead cases and dead defaults
|
; Check that we can eliminate both dead cases and dead defaults
|
||||||
; within a single run of simplify-cfg
|
; within a single run of simplify-cfg
|
||||||
define void @test7(i8 %a) {
|
define void @test7(i8 %a) {
|
||||||
; CHECK-LABEL: @test7(
|
; CHECK-LABEL: @test7
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A:%.*]], -3
|
; CHECK: @llvm.assume
|
||||||
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
|
; CHECK: br i1 [[IGNORE:%.*]], label %true, label %false
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp eq i8 [[A]], -1
|
|
||||||
; CHECK-NEXT: br i1 [[SWITCH]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
||||||
; CHECK: true:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 1)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: false:
|
|
||||||
; CHECK-NEXT: tail call void @foo(i32 3)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = and i8 %a, 254
|
%and = and i8 %a, 254
|
||||||
%cmp = icmp eq i8 %and, 254
|
%cmp = icmp eq i8 %and, 254
|
||||||
call void @llvm.assume(i1 %cmp)
|
call void @llvm.assume(i1 %cmp)
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
define i32 @test1(i32 %x) nounwind {
|
define i32 @test1(i32 %x) nounwind {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: a:
|
; CHECK-NEXT: a:
|
||||||
; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 1
|
; CHECK-NEXT: [[I:%.*]] = shl i32 %x, 1
|
||||||
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I]], 24
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I]], 24
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND]], i32 5, i32 0
|
; CHECK-NEXT: [[DOT:%.*]] = select i1 [[COND]], i32 5, i32 0
|
||||||
; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
|
; CHECK-NEXT: ret i32 [[DOT]]
|
||||||
;
|
;
|
||||||
%i = shl i32 %x, 1
|
%i = shl i32 %x, 1
|
||||||
switch i32 %i, label %a [
|
switch i32 %i, label %a [
|
||||||
|
@ -48,19 +48,12 @@ c:
|
||||||
|
|
||||||
define i1 @repeated_signbits(i8 %condition) {
|
define i1 @repeated_signbits(i8 %condition) {
|
||||||
; CHECK-LABEL: @repeated_signbits(
|
; CHECK-LABEL: @repeated_signbits(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK: switch i32
|
||||||
; CHECK-NEXT: [[SEXT:%.*]] = sext i8 [[CONDITION:%.*]] to i32
|
; CHECK-DAG: i32 -128, label %a
|
||||||
; CHECK-NEXT: switch i32 [[SEXT]], label [[DEFAULT:%.*]] [
|
; CHECK-DAG: i32 -1, label %a
|
||||||
; CHECK-NEXT: i32 0, label [[A:%.*]]
|
; CHECK-DAG: i32 0, label %a
|
||||||
; CHECK-NEXT: i32 127, label [[A]]
|
; CHECK-DAG: i32 127, label %a
|
||||||
; CHECK-NEXT: i32 -128, label [[A]]
|
|
||||||
; CHECK-NEXT: i32 -1, label [[A]]
|
|
||||||
; CHECK-NEXT: ]
|
; CHECK-NEXT: ]
|
||||||
; CHECK: a:
|
|
||||||
; CHECK-NEXT: [[MERGE:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ], [ false, [[DEFAULT]] ]
|
|
||||||
; CHECK-NEXT: ret i1 [[MERGE]]
|
|
||||||
; CHECK: default:
|
|
||||||
; CHECK-NEXT: br label [[A]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%sext = sext i8 %condition to i32
|
%sext = sext i8 %condition to i32
|
||||||
|
|
|
@ -1,28 +1,14 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt < %s -simplifycfg -S | FileCheck -enable-var-scope %s
|
; RUN: opt < %s -simplifycfg -S | FileCheck -enable-var-scope %s
|
||||||
|
|
||||||
; Test basic folding to a conditional branch.
|
; Test basic folding to a conditional branch.
|
||||||
define i32 @foo(i64 %x, i64 %y) nounwind {
|
define i32 @foo(i64 %x, i64 %y) nounwind {
|
||||||
; CHECK-LABEL: @foo(
|
; CHECK-LABEL: @foo(
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
|
|
||||||
; CHECK-NEXT: br i1 [[EQ]], label [[B:%.*]], label [[SWITCH:%.*]]
|
|
||||||
; CHECK: switch:
|
|
||||||
; CHECK-NEXT: [[LT:%.*]] = icmp slt i64 [[X]], [[Y]]
|
|
||||||
; CHECK-NEXT: br i1 [[LT]], label [[A:%.*]], label [[B]]
|
|
||||||
; CHECK: a:
|
|
||||||
; CHECK-NEXT: tail call void @bees.a() #0
|
|
||||||
; CHECK-NEXT: ret i32 1
|
|
||||||
; CHECK: b:
|
|
||||||
; CHECK-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[SWITCH]] ], [ 2, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: tail call void @bees.b() #0
|
|
||||||
; CHECK-NEXT: ret i32 [[RETVAL]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%eq = icmp eq i64 %x, %y
|
%eq = icmp eq i64 %x, %y
|
||||||
br i1 %eq, label %b, label %switch
|
br i1 %eq, label %b, label %switch
|
||||||
switch:
|
switch:
|
||||||
%lt = icmp slt i64 %x, %y
|
%lt = icmp slt i64 %x, %y
|
||||||
|
; CHECK: br i1 %lt, label %a, label %b
|
||||||
%qux = select i1 %lt, i32 0, i32 2
|
%qux = select i1 %lt, i32 0, i32 2
|
||||||
switch i32 %qux, label %bees [
|
switch i32 %qux, label %bees [
|
||||||
i32 0, label %a
|
i32 0, label %a
|
||||||
|
@ -32,10 +18,13 @@ switch:
|
||||||
a:
|
a:
|
||||||
tail call void @bees.a() nounwind
|
tail call void @bees.a() nounwind
|
||||||
ret i32 1
|
ret i32 1
|
||||||
|
; CHECK: b:
|
||||||
|
; CHECK-NEXT: %retval = phi i32 [ 0, %switch ], [ 2, %entry ]
|
||||||
b:
|
b:
|
||||||
%retval = phi i32 [0, %switch], [0, %switch], [2, %entry]
|
%retval = phi i32 [0, %switch], [0, %switch], [2, %entry]
|
||||||
tail call void @bees.b() nounwind
|
tail call void @bees.b() nounwind
|
||||||
ret i32 %retval
|
ret i32 %retval
|
||||||
|
; CHECK-NOT: bees:
|
||||||
bees:
|
bees:
|
||||||
tail call void @llvm.trap() nounwind
|
tail call void @llvm.trap() nounwind
|
||||||
unreachable
|
unreachable
|
||||||
|
@ -44,11 +33,10 @@ bees:
|
||||||
; Test basic folding to an unconditional branch.
|
; Test basic folding to an unconditional branch.
|
||||||
define i32 @bar(i64 %x, i64 %y) nounwind {
|
define i32 @bar(i64 %x, i64 %y) nounwind {
|
||||||
; CHECK-LABEL: @bar(
|
; CHECK-LABEL: @bar(
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: tail call void @bees.a() #0
|
|
||||||
; CHECK-NEXT: ret i32 0
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: tail call void @bees.a() [[$NUW:#[0-9]+]]
|
||||||
|
; CHECK-NEXT: ret i32 0
|
||||||
%lt = icmp slt i64 %x, %y
|
%lt = icmp slt i64 %x, %y
|
||||||
%qux = select i1 %lt, i32 0, i32 2
|
%qux = select i1 %lt, i32 0, i32 2
|
||||||
switch i32 %qux, label %bees [
|
switch i32 %qux, label %bees [
|
||||||
|
@ -71,11 +59,10 @@ bees:
|
||||||
; Test the edge case where both values from the select are the default case.
|
; Test the edge case where both values from the select are the default case.
|
||||||
define void @bazz(i64 %x, i64 %y) nounwind {
|
define void @bazz(i64 %x, i64 %y) nounwind {
|
||||||
; CHECK-LABEL: @bazz(
|
; CHECK-LABEL: @bazz(
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: tail call void @bees.b() #0
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: tail call void @bees.b() [[$NUW]]
|
||||||
|
; CHECK-NEXT: ret void
|
||||||
%lt = icmp slt i64 %x, %y
|
%lt = icmp slt i64 %x, %y
|
||||||
%qux = select i1 %lt, i32 10, i32 12
|
%qux = select i1 %lt, i32 10, i32 12
|
||||||
switch i32 %qux, label %b [
|
switch i32 %qux, label %b [
|
||||||
|
@ -97,11 +84,10 @@ bees:
|
||||||
; Test the edge case where both values from the select are equal.
|
; Test the edge case where both values from the select are equal.
|
||||||
define void @quux(i64 %x, i64 %y) nounwind {
|
define void @quux(i64 %x, i64 %y) nounwind {
|
||||||
; CHECK-LABEL: @quux(
|
; CHECK-LABEL: @quux(
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: tail call void @bees.a() #0
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: tail call void @bees.a() [[$NUW]]
|
||||||
|
; CHECK-NEXT: ret void
|
||||||
%lt = icmp slt i64 %x, %y
|
%lt = icmp slt i64 %x, %y
|
||||||
%qux = select i1 %lt, i32 0, i32 0
|
%qux = select i1 %lt, i32 0, i32 0
|
||||||
switch i32 %qux, label %b [
|
switch i32 %qux, label %b [
|
||||||
|
@ -123,18 +109,13 @@ bees:
|
||||||
; A final test, for phi node munging.
|
; A final test, for phi node munging.
|
||||||
define i32 @xyzzy(i64 %x, i64 %y) {
|
define i32 @xyzzy(i64 %x, i64 %y) {
|
||||||
; CHECK-LABEL: @xyzzy(
|
; CHECK-LABEL: @xyzzy(
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
|
|
||||||
; CHECK-NEXT: [[LT:%.*]] = icmp slt i64 [[X]], [[Y]]
|
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[LT]], i32 -1, i32 1
|
|
||||||
; CHECK-NEXT: [[VAL:%.*]] = select i1 [[EQ]], i32 0, i32 [[SPEC_SELECT]]
|
|
||||||
; CHECK-NEXT: ret i32 [[VAL]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%eq = icmp eq i64 %x, %y
|
%eq = icmp eq i64 %x, %y
|
||||||
br i1 %eq, label %r, label %cont
|
br i1 %eq, label %r, label %cont
|
||||||
cont:
|
cont:
|
||||||
|
; CHECK: %lt = icmp slt i64 %x, %y
|
||||||
%lt = icmp slt i64 %x, %y
|
%lt = icmp slt i64 %x, %y
|
||||||
|
; CHECK-NEXT: select i1 %lt, i32 -1, i32 1
|
||||||
%qux = select i1 %lt, i32 0, i32 2
|
%qux = select i1 %lt, i32 0, i32 2
|
||||||
switch i32 %qux, label %bees [
|
switch i32 %qux, label %bees [
|
||||||
i32 0, label %a
|
i32 0, label %a
|
||||||
|
@ -146,6 +127,7 @@ r:
|
||||||
ret i32 %val
|
ret i32 %val
|
||||||
a:
|
a:
|
||||||
ret i32 -1
|
ret i32 -1
|
||||||
|
; CHECK-NOT: bees:
|
||||||
bees:
|
bees:
|
||||||
tail call void @llvm.trap()
|
tail call void @llvm.trap()
|
||||||
unreachable
|
unreachable
|
||||||
|
@ -155,4 +137,5 @@ declare void @llvm.trap() nounwind noreturn
|
||||||
declare void @bees.a() nounwind
|
declare void @bees.a() nounwind
|
||||||
declare void @bees.b() nounwind
|
declare void @bees.b() nounwind
|
||||||
|
|
||||||
|
; CHECK: attributes [[$NUW]] = { nounwind }
|
||||||
; CHECK: attributes #1 = { cold noreturn nounwind }
|
; CHECK: attributes #1 = { cold noreturn nounwind }
|
||||||
|
|
|
@ -1,21 +1,12 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt %s -simplifycfg -S | FileCheck %s
|
; RUN: opt %s -simplifycfg -S | FileCheck %s
|
||||||
|
|
||||||
declare i32 @f(i32)
|
declare i32 @f(i32)
|
||||||
|
|
||||||
define i32 @basic(i32 %x) {
|
define i32 @basic(i32 %x) {
|
||||||
; CHECK-LABEL: @basic(
|
; CHECK-LABEL: @basic
|
||||||
; CHECK-NEXT: entry:
|
; CHECK: x.off = add i32 %x, -5
|
||||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5
|
; CHECK: %switch = icmp ult i32 %x.off, 3
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
|
; CHECK: br i1 %switch, label %a, label %default
|
||||||
; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[DEFAULT:%.*]]
|
|
||||||
; CHECK: default:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @f(i32 0)
|
|
||||||
; CHECK-NEXT: ret i32 [[TMP0]]
|
|
||||||
; CHECK: a:
|
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @f(i32 1)
|
|
||||||
; CHECK-NEXT: ret i32 [[TMP1]]
|
|
||||||
;
|
|
||||||
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %default [
|
switch i32 %x, label %default [
|
||||||
|
@ -33,18 +24,10 @@ a:
|
||||||
|
|
||||||
|
|
||||||
define i32 @unreachable(i32 %x) {
|
define i32 @unreachable(i32 %x) {
|
||||||
; CHECK-LABEL: @unreachable(
|
; CHECK-LABEL: @unreachable
|
||||||
; CHECK-NEXT: entry:
|
; CHECK: x.off = add i32 %x, -5
|
||||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5
|
; CHECK: %switch = icmp ult i32 %x.off, 3
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
|
; CHECK: br i1 %switch, label %a, label %b
|
||||||
; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[B:%.*]]
|
|
||||||
; CHECK: a:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @f(i32 0)
|
|
||||||
; CHECK-NEXT: ret i32 [[TMP0]]
|
|
||||||
; CHECK: b:
|
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @f(i32 1)
|
|
||||||
; CHECK-NEXT: ret i32 [[TMP1]]
|
|
||||||
;
|
|
||||||
|
|
||||||
entry:
|
entry:
|
||||||
switch i32 %x, label %unreachable [
|
switch i32 %x, label %unreachable [
|
||||||
|
@ -68,18 +51,10 @@ b:
|
||||||
|
|
||||||
|
|
||||||
define i32 @unreachable2(i32 %x) {
|
define i32 @unreachable2(i32 %x) {
|
||||||
; CHECK-LABEL: @unreachable2(
|
; CHECK-LABEL: @unreachable2
|
||||||
; CHECK-NEXT: entry:
|
; CHECK: x.off = add i32 %x, -5
|
||||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5
|
; CHECK: %switch = icmp ult i32 %x.off, 3
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
|
; CHECK: br i1 %switch, label %a, label %b
|
||||||
; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[B:%.*]]
|
|
||||||
; CHECK: a:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @f(i32 0)
|
|
||||||
; CHECK-NEXT: ret i32 [[TMP0]]
|
|
||||||
; CHECK: b:
|
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @f(i32 1)
|
|
||||||
; CHECK-NEXT: ret i32 [[TMP1]]
|
|
||||||
;
|
|
||||||
|
|
||||||
entry:
|
entry:
|
||||||
; Note: folding the most popular case destination into the default
|
; Note: folding the most popular case destination into the default
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -S -simplifycfg < %s | FileCheck %s
|
; RUN: opt -S -simplifycfg < %s | FileCheck %s
|
||||||
target datalayout="p:40:64:64:32"
|
target datalayout="p:40:64:64:32"
|
||||||
|
|
||||||
|
@ -7,18 +6,6 @@ declare void @foo1()
|
||||||
declare void @foo2()
|
declare void @foo2()
|
||||||
|
|
||||||
define void @test1(i32 %V) {
|
define void @test1(i32 %V) {
|
||||||
; CHECK-LABEL: @test1(
|
|
||||||
; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 17, label [[T:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[T]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: call void @foo2()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
|
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
|
||||||
%C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1]
|
%C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1]
|
||||||
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
||||||
|
@ -29,22 +16,14 @@ T: ; preds = %0
|
||||||
F: ; preds = %0
|
F: ; preds = %0
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test1(
|
||||||
|
; CHECK: switch i32 %V, label %F [
|
||||||
|
; CHECK: i32 17, label %T
|
||||||
|
; CHECK: i32 4, label %T
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test1_ptr(i32* %V) {
|
define void @test1_ptr(i32* %V) {
|
||||||
; CHECK-LABEL: @test1_ptr(
|
|
||||||
; CHECK-NEXT: [[MAGICPTR:%.*]] = ptrtoint i32* [[V:%.*]] to i32
|
|
||||||
; CHECK-NEXT: switch i32 [[MAGICPTR]], label [[F:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 17, label [[T:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[T]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: call void @foo2()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp eq i32* %V, inttoptr (i32 4 to i32*)
|
%C1 = icmp eq i32* %V, inttoptr (i32 4 to i32*)
|
||||||
%C2 = icmp eq i32* %V, inttoptr (i32 17 to i32*)
|
%C2 = icmp eq i32* %V, inttoptr (i32 17 to i32*)
|
||||||
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
||||||
|
@ -55,22 +34,15 @@ T: ; preds = %0
|
||||||
F: ; preds = %0
|
F: ; preds = %0
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test1_ptr(
|
||||||
|
; DL: %magicptr = ptrtoint i32* %V to i32
|
||||||
|
; DL: switch i32 %magicptr, label %F [
|
||||||
|
; DL: i32 17, label %T
|
||||||
|
; DL: i32 4, label %T
|
||||||
|
; DL: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test1_ptr_as1(i32 addrspace(1)* %V) {
|
define void @test1_ptr_as1(i32 addrspace(1)* %V) {
|
||||||
; CHECK-LABEL: @test1_ptr_as1(
|
|
||||||
; CHECK-NEXT: [[MAGICPTR:%.*]] = ptrtoint i32 addrspace(1)* [[V:%.*]] to i32
|
|
||||||
; CHECK-NEXT: switch i32 [[MAGICPTR]], label [[F:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 17, label [[T:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[T]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: call void @foo2()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 4 to i32 addrspace(1)*)
|
%C1 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 4 to i32 addrspace(1)*)
|
||||||
%C2 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 17 to i32 addrspace(1)*)
|
%C2 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 17 to i32 addrspace(1)*)
|
||||||
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
||||||
|
@ -81,21 +53,15 @@ T: ; preds = %0
|
||||||
F: ; preds = %0
|
F: ; preds = %0
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test1_ptr_as1(
|
||||||
|
; DL: %magicptr = ptrtoint i32 addrspace(1)* %V to i16
|
||||||
|
; DL: switch i16 %magicptr, label %F [
|
||||||
|
; DL: i16 17, label %T
|
||||||
|
; DL: i16 4, label %T
|
||||||
|
; DL: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2(i32 %V) {
|
define void @test2(i32 %V) {
|
||||||
; CHECK-LABEL: @test2(
|
|
||||||
; CHECK-NEXT: switch i32 [[V:%.*]], label [[T:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 17, label [[F:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[F]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: call void @foo2()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp ne i32 %V, 4 ; <i1> [#uses=1]
|
%C1 = icmp ne i32 %V, 4 ; <i1> [#uses=1]
|
||||||
%C2 = icmp ne i32 %V, 17 ; <i1> [#uses=1]
|
%C2 = icmp ne i32 %V, 17 ; <i1> [#uses=1]
|
||||||
%CN = and i1 %C1, %C2 ; <i1> [#uses=1]
|
%CN = and i1 %C1, %C2 ; <i1> [#uses=1]
|
||||||
|
@ -106,21 +72,14 @@ T: ; preds = %0
|
||||||
F: ; preds = %0
|
F: ; preds = %0
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test2(
|
||||||
|
; CHECK: switch i32 %V, label %T [
|
||||||
|
; CHECK: i32 17, label %F
|
||||||
|
; CHECK: i32 4, label %F
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test3(i32 %V) {
|
define void @test3(i32 %V) {
|
||||||
; CHECK-LABEL: @test3(
|
|
||||||
; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 4, label [[T:%.*]]
|
|
||||||
; CHECK-NEXT: i32 17, label [[T]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: call void @foo2()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
|
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
|
||||||
br i1 %C1, label %T, label %N
|
br i1 %C1, label %T, label %N
|
||||||
N: ; preds = %0
|
N: ; preds = %0
|
||||||
|
@ -133,25 +92,16 @@ F: ; preds = %N
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test3(
|
||||||
|
; CHECK: switch i32 %V, label %F [
|
||||||
|
; CHECK: i32 4, label %T
|
||||||
|
; CHECK: i32 17, label %T
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
|
define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test4(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i8 [[C:%.*]], label [[LOR_RHS:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 62, label [[LOR_END:%.*]]
|
|
||||||
; CHECK-NEXT: i8 34, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 92, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: lor.rhs:
|
|
||||||
; CHECK-NEXT: br label [[LOR_END]]
|
|
||||||
; CHECK: lor.end:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
|
|
||||||
; CHECK-NEXT: [[LOR_EXT:%.*]] = zext i1 [[TMP0]] to i32
|
|
||||||
; CHECK-NEXT: ret i32 [[LOR_EXT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp eq i8 %c, 62
|
%cmp = icmp eq i8 %c, 62
|
||||||
br i1 %cmp, label %lor.end, label %lor.lhs.false
|
br i1 %cmp, label %lor.end, label %lor.lhs.false
|
||||||
|
@ -169,23 +119,15 @@ lor.end: ; preds = %lor.rhs, %lor.lhs.f
|
||||||
%lor.ext = zext i1 %0 to i32
|
%lor.ext = zext i1 %0 to i32
|
||||||
ret i32 %lor.ext
|
ret i32 %lor.ext
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test4(
|
||||||
|
; CHECK: switch i8 %c, label %lor.rhs [
|
||||||
|
; CHECK: i8 62, label %lor.end
|
||||||
|
; CHECK: i8 34, label %lor.end
|
||||||
|
; CHECK: i8 92, label %lor.end
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
|
define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test5(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i8 [[C:%.*]], label [[LOR_RHS:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 62, label [[LOR_END:%.*]]
|
|
||||||
; CHECK-NEXT: i8 34, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 92, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: lor.rhs:
|
|
||||||
; CHECK-NEXT: br label [[LOR_END]]
|
|
||||||
; CHECK: lor.end:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
|
|
||||||
; CHECK-NEXT: [[LOR_EXT:%.*]] = zext i1 [[TMP0]] to i32
|
|
||||||
; CHECK-NEXT: ret i32 [[LOR_EXT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i8 %c, label %lor.rhs [
|
switch i8 %c, label %lor.rhs [
|
||||||
i8 62, label %lor.end
|
i8 62, label %lor.end
|
||||||
|
@ -201,19 +143,16 @@ lor.end: ; preds = %entry, %entry, %ent
|
||||||
%0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ]
|
%0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ]
|
||||||
%lor.ext = zext i1 %0 to i32
|
%lor.ext = zext i1 %0 to i32
|
||||||
ret i32 %lor.ext
|
ret i32 %lor.ext
|
||||||
|
; CHECK-LABEL: @test5(
|
||||||
|
; CHECK: switch i8 %c, label %lor.rhs [
|
||||||
|
; CHECK: i8 62, label %lor.end
|
||||||
|
; CHECK: i8 34, label %lor.end
|
||||||
|
; CHECK: i8 92, label %lor.end
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define i1 @test6({ i32, i32 }* %I) {
|
define i1 @test6({ i32, i32 }* %I) {
|
||||||
; CHECK-LABEL: @test6(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP_1_I:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[I:%.*]], i64 0, i32 1
|
|
||||||
; CHECK-NEXT: [[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]]
|
|
||||||
; CHECK-NEXT: [[TMP_2_I_OFF:%.*]] = add i32 [[TMP_2_I]], -14
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[TMP_2_I_OFF]], 6
|
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false
|
|
||||||
; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tmp.1.i = getelementptr { i32, i32 }, { i32, i32 }* %I, i64 0, i32 1 ; <i32*> [#uses=1]
|
%tmp.1.i = getelementptr { i32, i32 }, { i32, i32 }* %I, i64 0, i32 1 ; <i32*> [#uses=1]
|
||||||
%tmp.2.i = load i32, i32* %tmp.1.i ; <i32> [#uses=6]
|
%tmp.2.i = load i32, i32* %tmp.1.i ; <i32> [#uses=6]
|
||||||
|
@ -240,24 +179,12 @@ UnifiedReturnBlock: ; preds = %shortcirc_done.4, %shortcirc_next.4
|
||||||
%UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ] ; <i1> [#uses=1]
|
%UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ] ; <i1> [#uses=1]
|
||||||
ret i1 %UnifiedRetVal
|
ret i1 %UnifiedRetVal
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test6(
|
||||||
|
; CHECK: %tmp.2.i.off = add i32 %tmp.2.i, -14
|
||||||
|
; CHECK: %switch = icmp ult i32 %tmp.2.i.off, 6
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
|
define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test7(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32
|
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: switch i8 [[C:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 99, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i8 97, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.then:
|
|
||||||
; CHECK-NEXT: tail call void @foo1() #2
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ult i32 %x, 32
|
%cmp = icmp ult i32 %x, 32
|
||||||
%cmp4 = icmp eq i8 %c, 97
|
%cmp4 = icmp eq i8 %c, 97
|
||||||
|
@ -273,27 +200,17 @@ if.then: ; preds = %entry
|
||||||
if.end: ; preds = %entry
|
if.end: ; preds = %entry
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test7(
|
||||||
|
; CHECK: %cmp = icmp ult i32 %x, 32
|
||||||
|
; CHECK: br i1 %cmp, label %if.then, label %switch.early.test
|
||||||
|
; CHECK: switch.early.test:
|
||||||
|
; CHECK: switch i8 %c, label %if.end [
|
||||||
|
; CHECK: i8 99, label %if.then
|
||||||
|
; CHECK: i8 97, label %if.then
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
|
define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test8(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[N:%.*]], label [[IF_THEN:%.*]]
|
|
||||||
; CHECK: N:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32
|
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN]], label [[SWITCH_EARLY_TEST:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: switch i8 [[C:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 99, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i8 97, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.then:
|
|
||||||
; CHECK-NEXT: [[A:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 42, [[SWITCH_EARLY_TEST]] ], [ 42, [[N]] ], [ 42, [[SWITCH_EARLY_TEST]] ]
|
|
||||||
; CHECK-NEXT: tail call void @foo1() #2
|
|
||||||
; CHECK-NEXT: ret i32 [[A]]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: ret i32 0
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
br i1 %C, label %N, label %if.then
|
br i1 %C, label %N, label %if.then
|
||||||
N:
|
N:
|
||||||
|
@ -312,33 +229,17 @@ if.then: ; preds = %entry
|
||||||
if.end: ; preds = %entry
|
if.end: ; preds = %entry
|
||||||
ret i32 0
|
ret i32 0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test8(
|
||||||
|
; CHECK: switch.early.test:
|
||||||
|
; CHECK: switch i8 %c, label %if.end [
|
||||||
|
; CHECK: i8 99, label %if.then
|
||||||
|
; CHECK: i8 97, label %if.then
|
||||||
|
; CHECK: ]
|
||||||
|
; CHECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ]
|
||||||
}
|
}
|
||||||
|
|
||||||
;; This is "Example 7" from http://blog.regehr.org/archives/320
|
;; This is "Example 7" from http://blog.regehr.org/archives/320
|
||||||
define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
|
define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test9(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[C:%.*]], 33
|
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: switch i8 [[C]], label [[LOR_RHS:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 92, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 62, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 60, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 59, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 58, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 46, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 44, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 34, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 39, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: lor.rhs:
|
|
||||||
; CHECK-NEXT: br label [[LOR_END]]
|
|
||||||
; CHECK: lor.end:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[SWITCH_EARLY_TEST]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY:%.*]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ]
|
|
||||||
; CHECK-NEXT: [[CONV46:%.*]] = zext i1 [[TMP0]] to i32
|
|
||||||
; CHECK-NEXT: ret i32 [[CONV46]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ult i8 %c, 33
|
%cmp = icmp ult i8 %c, 33
|
||||||
br i1 %cmp, label %lor.end, label %lor.lhs.false
|
br i1 %cmp, label %lor.end, label %lor.lhs.false
|
||||||
|
@ -384,23 +285,25 @@ lor.end: ; preds = %lor.rhs, %lor.lhs.f
|
||||||
%conv46 = zext i1 %0 to i32
|
%conv46 = zext i1 %0 to i32
|
||||||
ret i32 %conv46
|
ret i32 %conv46
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test9(
|
||||||
|
; CHECK: %cmp = icmp ult i8 %c, 33
|
||||||
|
; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test
|
||||||
|
|
||||||
|
; CHECK: switch.early.test:
|
||||||
|
; CHECK: switch i8 %c, label %lor.rhs [
|
||||||
|
; CHECK: i8 92, label %lor.end
|
||||||
|
; CHECK: i8 62, label %lor.end
|
||||||
|
; CHECK: i8 60, label %lor.end
|
||||||
|
; CHECK: i8 59, label %lor.end
|
||||||
|
; CHECK: i8 58, label %lor.end
|
||||||
|
; CHECK: i8 46, label %lor.end
|
||||||
|
; CHECK: i8 44, label %lor.end
|
||||||
|
; CHECK: i8 34, label %lor.end
|
||||||
|
; CHECK: i8 39, label %lor.end
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test10(i32 %mode, i1 %Cond) {
|
define i32 @test10(i32 %mode, i1 %Cond) {
|
||||||
; CHECK-LABEL: @test10(
|
|
||||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[SWITCH_EARLY_TEST:%.*]], label [[F:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: switch i32 [[MODE:%.*]], label [[T:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 51, label [[F]]
|
|
||||||
; CHECK-NEXT: i32 0, label [[F]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ 123, [[SWITCH_EARLY_TEST]] ], [ 324, [[F]] ]
|
|
||||||
; CHECK-NEXT: ret i32 [[MERGE]]
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: br label [[T]]
|
|
||||||
;
|
|
||||||
%A = icmp ne i32 %mode, 0
|
%A = icmp ne i32 %mode, 0
|
||||||
%B = icmp ne i32 %mode, 51
|
%B = icmp ne i32 %mode, 51
|
||||||
%C = and i1 %A, %B
|
%C = and i1 %A, %B
|
||||||
|
@ -411,27 +314,17 @@ T:
|
||||||
F:
|
F:
|
||||||
ret i32 324
|
ret i32 324
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test10(
|
||||||
|
; CHECK: br i1 %Cond, label %switch.early.test, label %F
|
||||||
|
; CHECK:switch.early.test:
|
||||||
|
; CHECK: switch i32 %mode, label %T [
|
||||||
|
; CHECK: i32 51, label %F
|
||||||
|
; CHECK: i32 0, label %F
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
; PR8780
|
; PR8780
|
||||||
define i32 @test11(i32 %bar) nounwind {
|
define i32 @test11(i32 %bar) nounwind {
|
||||||
; CHECK-LABEL: @test11(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[BAR:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 55, label [[RETURN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 53, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 35, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 24, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 23, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 12, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_END]] ], [ 1, [[ENTRY:%.*]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ]
|
|
||||||
; CHECK-NEXT: ret i32 [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp eq i32 %bar, 4
|
%cmp = icmp eq i32 %bar, 4
|
||||||
%cmp2 = icmp eq i32 %bar, 35
|
%cmp2 = icmp eq i32 %bar, 35
|
||||||
|
@ -460,21 +353,19 @@ return: ; preds = %if.end, %if.then
|
||||||
%retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ]
|
%retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test11(
|
||||||
|
; CHECK: switch i32 %bar, label %if.end [
|
||||||
|
; CHECK: i32 55, label %return
|
||||||
|
; CHECK: i32 53, label %return
|
||||||
|
; CHECK: i32 35, label %return
|
||||||
|
; CHECK: i32 24, label %return
|
||||||
|
; CHECK: i32 23, label %return
|
||||||
|
; CHECK: i32 12, label %return
|
||||||
|
; CHECK: i32 4, label %return
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test12() nounwind {
|
define void @test12() nounwind {
|
||||||
; CHECK-LABEL: @test12(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[A_OLD:%.*]] = icmp eq i32 undef, undef
|
|
||||||
; CHECK-NEXT: br i1 [[A_OLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]]
|
|
||||||
; CHECK: bb55.us.us:
|
|
||||||
; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 undef, undef
|
|
||||||
; CHECK-NEXT: [[A:%.*]] = icmp eq i32 undef, undef
|
|
||||||
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[B]], [[A]]
|
|
||||||
; CHECK-NEXT: br i1 [[OR_COND]], label [[BB55_US_US]], label [[MALFORMED]]
|
|
||||||
; CHECK: malformed:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
br label %bb49.us.us
|
br label %bb49.us.us
|
||||||
|
|
||||||
|
@ -491,26 +382,12 @@ bb55.us.us:
|
||||||
|
|
||||||
malformed:
|
malformed:
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test12(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; test13 - handle switch formation with ult.
|
; test13 - handle switch formation with ult.
|
||||||
define void @test13(i32 %x) nounwind ssp noredzone {
|
define void @test13(i32 %x) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test13(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 6, label [[IF_THEN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 3, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 0, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.then:
|
|
||||||
; CHECK-NEXT: call void @foo1() #3
|
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ult i32 %x, 2
|
%cmp = icmp ult i32 %x, 2
|
||||||
br i1 %cmp, label %if.then, label %lor.lhs.false3
|
br i1 %cmp, label %if.then, label %lor.lhs.false3
|
||||||
|
@ -533,26 +410,18 @@ if.then: ; preds = %lor.lhs.false9, %lo
|
||||||
|
|
||||||
if.end: ; preds = %if.then, %lor.lhs.false9
|
if.end: ; preds = %if.then, %lor.lhs.false9
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test13(
|
||||||
|
; CHECK: switch i32 %x, label %if.end [
|
||||||
|
; CHECK: i32 6, label %if.then
|
||||||
|
; CHECK: i32 4, label %if.then
|
||||||
|
; CHECK: i32 3, label %if.then
|
||||||
|
; CHECK: i32 1, label %if.then
|
||||||
|
; CHECK: i32 0, label %if.then
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
; test14 - handle switch formation with ult.
|
; test14 - handle switch formation with ult.
|
||||||
define void @test14(i32 %x) nounwind ssp noredzone {
|
define void @test14(i32 %x) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test14(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 6, label [[IF_THEN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 3, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 2, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 0, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.then:
|
|
||||||
; CHECK-NEXT: call void @foo1() #3
|
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ugt i32 %x, 2
|
%cmp = icmp ugt i32 %x, 2
|
||||||
br i1 %cmp, label %lor.lhs.false3, label %if.then
|
br i1 %cmp, label %lor.lhs.false3, label %if.then
|
||||||
|
@ -575,15 +444,18 @@ if.then: ; preds = %lor.lhs.false9, %lo
|
||||||
|
|
||||||
if.end: ; preds = %if.then, %lor.lhs.false9
|
if.end: ; preds = %if.then, %lor.lhs.false9
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test14(
|
||||||
|
; CHECK: switch i32 %x, label %if.end [
|
||||||
|
; CHECK: i32 6, label %if.then
|
||||||
|
; CHECK: i32 4, label %if.then
|
||||||
|
; CHECK: i32 3, label %if.then
|
||||||
|
; CHECK: i32 1, label %if.then
|
||||||
|
; CHECK: i32 0, label %if.then
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
; Don't crash on ginormous ranges.
|
; Don't crash on ginormous ranges.
|
||||||
define void @test15(i128 %x) nounwind {
|
define void @test15(i128 %x) nounwind {
|
||||||
; CHECK-LABEL: @test15(
|
|
||||||
; CHECK-NEXT: if.end:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[X:%.*]], 2
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%cmp = icmp ugt i128 %x, 2
|
%cmp = icmp ugt i128 %x, 2
|
||||||
br i1 %cmp, label %if.end, label %lor.false
|
br i1 %cmp, label %if.end, label %lor.false
|
||||||
|
|
||||||
|
@ -598,19 +470,18 @@ if.then:
|
||||||
if.end:
|
if.end:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test15(
|
||||||
|
; CHECK-NOT: switch
|
||||||
|
; CHECK: ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; PR8675
|
; PR8675
|
||||||
; rdar://5134905
|
; rdar://5134905
|
||||||
define zeroext i1 @test16(i32 %x) nounwind {
|
define zeroext i1 @test16(i32 %x) nounwind {
|
||||||
; CHECK-LABEL: @test16(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -1
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
|
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false
|
|
||||||
; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
|
; CHECK-LABEL: @test16(
|
||||||
|
; CHECK: %x.off = add i32 %x, -1
|
||||||
|
; CHECK: %switch = icmp ult i32 %x.off, 3
|
||||||
%cmp.i = icmp eq i32 %x, 1
|
%cmp.i = icmp eq i32 %x, 1
|
||||||
br i1 %cmp.i, label %lor.end, label %lor.lhs.false
|
br i1 %cmp.i, label %lor.end, label %lor.lhs.false
|
||||||
|
|
||||||
|
@ -629,17 +500,6 @@ lor.end:
|
||||||
|
|
||||||
; Check that we don't turn an icmp into a switch where it's not useful.
|
; Check that we don't turn an icmp into a switch where it's not useful.
|
||||||
define void @test17(i32 %x, i32 %y) {
|
define void @test17(i32 %x, i32 %y) {
|
||||||
; CHECK-LABEL: @test17(
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[Y:%.*]], 2
|
|
||||||
; CHECK-NEXT: [[OR_COND775:%.*]] = or i1 [[CMP]], [[SWITCH]]
|
|
||||||
; CHECK-NEXT: br i1 [[OR_COND775]], label [[LOR_LHS_FALSE8:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: lor.lhs.false8:
|
|
||||||
; CHECK-NEXT: tail call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%cmp = icmp ult i32 %x, 3
|
%cmp = icmp ult i32 %x, 3
|
||||||
%switch = icmp ult i32 %y, 2
|
%switch = icmp ult i32 %y, 2
|
||||||
%or.cond775 = or i1 %cmp, %switch
|
%or.cond775 = or i1 %cmp, %switch
|
||||||
|
@ -652,20 +512,13 @@ lor.lhs.false8:
|
||||||
return:
|
return:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test17(
|
||||||
|
; CHECK-NOT: switch.early.test
|
||||||
|
; CHECK-NOT: switch i32
|
||||||
|
; CHECK: ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test18(i32 %arg) {
|
define void @test18(i32 %arg) {
|
||||||
; CHECK-LABEL: @test18(
|
|
||||||
; CHECK-NEXT: bb:
|
|
||||||
; CHECK-NEXT: [[ARG_OFF:%.*]] = add i32 [[ARG:%.*]], -8
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[ARG_OFF]], 11
|
|
||||||
; CHECK-NEXT: br i1 [[SWITCH]], label [[BB19:%.*]], label [[BB20:%.*]]
|
|
||||||
; CHECK: bb19:
|
|
||||||
; CHECK-NEXT: tail call void @foo1()
|
|
||||||
; CHECK-NEXT: br label [[BB20]]
|
|
||||||
; CHECK: bb20:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
bb:
|
bb:
|
||||||
%tmp = and i32 %arg, -2
|
%tmp = and i32 %arg, -2
|
||||||
%tmp1 = icmp eq i32 %tmp, 8
|
%tmp1 = icmp eq i32 %tmp, 8
|
||||||
|
@ -697,23 +550,12 @@ bb19: ; preds = %bb8, %bb
|
||||||
bb20: ; preds = %bb19, %bb8
|
bb20: ; preds = %bb19, %bb8
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test18(
|
||||||
|
; CHECK: %arg.off = add i32 %arg, -8
|
||||||
|
; CHECK: icmp ult i32 %arg.off, 11
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @PR26323(i1 %tobool23, i32 %tmp3) {
|
define void @PR26323(i1 %tobool23, i32 %tmp3) {
|
||||||
; CHECK-LABEL: @PR26323(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp ne i32 [[TMP3:%.*]], 0
|
|
||||||
; CHECK-NEXT: [[NEG14:%.*]] = and i32 [[TMP3]], -2
|
|
||||||
; CHECK-NEXT: [[CMP17:%.*]] = icmp ne i32 [[NEG14]], -1
|
|
||||||
; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TOBOOL5]], [[TOBOOL23:%.*]]
|
|
||||||
; CHECK-NEXT: [[OR_COND1:%.*]] = and i1 [[CMP17]], [[OR_COND]]
|
|
||||||
; CHECK-NEXT: br i1 [[OR_COND1]], label [[IF_END29:%.*]], label [[IF_THEN27:%.*]]
|
|
||||||
; CHECK: if.then27:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: unreachable
|
|
||||||
; CHECK: if.end29:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool5 = icmp ne i32 %tmp3, 0
|
%tobool5 = icmp ne i32 %tmp3, 0
|
||||||
%neg14 = and i32 %tmp3, -2
|
%neg14 = and i32 %tmp3, -2
|
||||||
|
@ -730,19 +572,21 @@ if.end29: ; preds = %entry
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: define void @PR26323(
|
||||||
|
; CHECK: %tobool5 = icmp ne i32 %tmp3, 0
|
||||||
|
; CHECK: %neg14 = and i32 %tmp3, -2
|
||||||
|
; CHECK: %cmp17 = icmp ne i32 %neg14, -1
|
||||||
|
; CHECK: %or.cond = and i1 %tobool5, %tobool23
|
||||||
|
; CHECK: %or.cond1 = and i1 %cmp17, %or.cond
|
||||||
|
; CHECK: br i1 %or.cond1, label %if.end29, label %if.then27
|
||||||
|
|
||||||
|
; Form a switch when and'ing a negated power of two
|
||||||
|
; CHECK-LABEL: define void @test19
|
||||||
|
; CHECK: switch i32 %arg, label %else [
|
||||||
|
; CHECK: i32 32, label %if
|
||||||
|
; CHECK: i32 13, label %if
|
||||||
|
; CHECK: i32 12, label %if
|
||||||
define void @test19(i32 %arg) {
|
define void @test19(i32 %arg) {
|
||||||
; CHECK-LABEL: @test19(
|
|
||||||
; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[ELSE:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 32, label [[IF:%.*]]
|
|
||||||
; CHECK-NEXT: i32 13, label [[IF]]
|
|
||||||
; CHECK-NEXT: i32 12, label [[IF]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: else:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = and i32 %arg, -2
|
%and = and i32 %arg, -2
|
||||||
%cmp1 = icmp eq i32 %and, 12
|
%cmp1 = icmp eq i32 %and, 12
|
||||||
%cmp2 = icmp eq i32 %arg, 32
|
%cmp2 = icmp eq i32 %arg, 32
|
||||||
|
@ -758,19 +602,10 @@ else:
|
||||||
}
|
}
|
||||||
|
|
||||||
; Since %cmp1 is always false, a switch is never formed
|
; Since %cmp1 is always false, a switch is never formed
|
||||||
|
; CHECK-LABEL: define void @test20
|
||||||
|
; CHECK-NOT: switch
|
||||||
|
; CHECK: ret void
|
||||||
define void @test20(i32 %arg) {
|
define void @test20(i32 %arg) {
|
||||||
; CHECK-LABEL: @test20(
|
|
||||||
; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARG:%.*]], -2
|
|
||||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND]], 13
|
|
||||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[ARG]], 32
|
|
||||||
; CHECK-NEXT: [[PRED:%.*]] = or i1 [[CMP1]], [[CMP2]]
|
|
||||||
; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]]
|
|
||||||
; CHECK: if:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: else:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = and i32 %arg, -2
|
%and = and i32 %arg, -2
|
||||||
%cmp1 = icmp eq i32 %and, 13
|
%cmp1 = icmp eq i32 %and, 13
|
||||||
%cmp2 = icmp eq i32 %arg, 32
|
%cmp2 = icmp eq i32 %arg, 32
|
||||||
|
@ -786,19 +621,11 @@ else:
|
||||||
}
|
}
|
||||||
|
|
||||||
; Form a switch when or'ing a power of two
|
; Form a switch when or'ing a power of two
|
||||||
|
; CHECK-LABEL: define void @test21
|
||||||
|
; CHECK: i32 32, label %else
|
||||||
|
; CHECK: i32 13, label %else
|
||||||
|
; CHECK: i32 12, label %else
|
||||||
define void @test21(i32 %arg) {
|
define void @test21(i32 %arg) {
|
||||||
; CHECK-LABEL: @test21(
|
|
||||||
; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[IF:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 32, label [[ELSE:%.*]]
|
|
||||||
; CHECK-NEXT: i32 13, label [[ELSE]]
|
|
||||||
; CHECK-NEXT: i32 12, label [[ELSE]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: else:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = or i32 %arg, 1
|
%and = or i32 %arg, 1
|
||||||
%cmp1 = icmp ne i32 %and, 13
|
%cmp1 = icmp ne i32 %and, 13
|
||||||
%cmp2 = icmp ne i32 %arg, 32
|
%cmp2 = icmp ne i32 %arg, 32
|
||||||
|
@ -814,19 +641,10 @@ else:
|
||||||
}
|
}
|
||||||
|
|
||||||
; Since %cmp1 is always false, a switch is never formed
|
; Since %cmp1 is always false, a switch is never formed
|
||||||
|
; CHECK-LABEL: define void @test22
|
||||||
|
; CHECK-NOT: switch
|
||||||
|
; CHECK: ret void
|
||||||
define void @test22(i32 %arg) {
|
define void @test22(i32 %arg) {
|
||||||
; CHECK-LABEL: @test22(
|
|
||||||
; CHECK-NEXT: [[AND:%.*]] = or i32 [[ARG:%.*]], 1
|
|
||||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 12
|
|
||||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[ARG]], 32
|
|
||||||
; CHECK-NEXT: [[PRED:%.*]] = and i1 [[CMP1]], [[CMP2]]
|
|
||||||
; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]]
|
|
||||||
; CHECK: if:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: else:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = or i32 %arg, 1
|
%and = or i32 %arg, 1
|
||||||
%cmp1 = icmp ne i32 %and, 12
|
%cmp1 = icmp ne i32 %and, 12
|
||||||
%cmp2 = icmp ne i32 %arg, 32
|
%cmp2 = icmp ne i32 %arg, 32
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
||||||
; RUN: opt -S -simplifycfg < %s | FileCheck %s
|
; RUN: opt -S -simplifycfg < %s | FileCheck %s
|
||||||
; RUN: opt -S -data-layout="p:32:32-p1:16:16" -simplifycfg < %s | FileCheck -check-prefix=CHECK -check-prefix=DL %s
|
; RUN: opt -S -data-layout="p:32:32-p1:16:16" -simplifycfg < %s | FileCheck -check-prefix=CHECK -check-prefix=DL %s
|
||||||
|
|
||||||
|
@ -7,18 +6,6 @@ declare void @foo1()
|
||||||
declare void @foo2()
|
declare void @foo2()
|
||||||
|
|
||||||
define void @test1(i32 %V) {
|
define void @test1(i32 %V) {
|
||||||
; CHECK-LABEL: @test1(
|
|
||||||
; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 17, label [[T:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[T]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: call void @foo2()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
|
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
|
||||||
%C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1]
|
%C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1]
|
||||||
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
||||||
|
@ -29,22 +16,14 @@ T: ; preds = %0
|
||||||
F: ; preds = %0
|
F: ; preds = %0
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test1(
|
||||||
|
; CHECK: switch i32 %V, label %F [
|
||||||
|
; CHECK: i32 17, label %T
|
||||||
|
; CHECK: i32 4, label %T
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test1_ptr(i32* %V) {
|
define void @test1_ptr(i32* %V) {
|
||||||
; DL-LABEL: @test1_ptr(
|
|
||||||
; DL-NEXT: [[MAGICPTR:%.*]] = ptrtoint i32* [[V:%.*]] to i32
|
|
||||||
; DL-NEXT: switch i32 [[MAGICPTR]], label [[F:%.*]] [
|
|
||||||
; DL-NEXT: i32 17, label [[T:%.*]]
|
|
||||||
; DL-NEXT: i32 4, label [[T]]
|
|
||||||
; DL-NEXT: ]
|
|
||||||
; DL: T:
|
|
||||||
; DL-NEXT: call void @foo1()
|
|
||||||
; DL-NEXT: ret void
|
|
||||||
; DL: F:
|
|
||||||
; DL-NEXT: call void @foo2()
|
|
||||||
; DL-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp eq i32* %V, inttoptr (i32 4 to i32*)
|
%C1 = icmp eq i32* %V, inttoptr (i32 4 to i32*)
|
||||||
%C2 = icmp eq i32* %V, inttoptr (i32 17 to i32*)
|
%C2 = icmp eq i32* %V, inttoptr (i32 17 to i32*)
|
||||||
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
||||||
|
@ -55,22 +34,15 @@ T: ; preds = %0
|
||||||
F: ; preds = %0
|
F: ; preds = %0
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test1_ptr(
|
||||||
|
; DL: %magicptr = ptrtoint i32* %V to i32
|
||||||
|
; DL: switch i32 %magicptr, label %F [
|
||||||
|
; DL: i32 17, label %T
|
||||||
|
; DL: i32 4, label %T
|
||||||
|
; DL: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test1_ptr_as1(i32 addrspace(1)* %V) {
|
define void @test1_ptr_as1(i32 addrspace(1)* %V) {
|
||||||
; DL-LABEL: @test1_ptr_as1(
|
|
||||||
; DL-NEXT: [[MAGICPTR:%.*]] = ptrtoint i32 addrspace(1)* [[V:%.*]] to i16
|
|
||||||
; DL-NEXT: switch i16 [[MAGICPTR]], label [[F:%.*]] [
|
|
||||||
; DL-NEXT: i16 17, label [[T:%.*]]
|
|
||||||
; DL-NEXT: i16 4, label [[T]]
|
|
||||||
; DL-NEXT: ]
|
|
||||||
; DL: T:
|
|
||||||
; DL-NEXT: call void @foo1()
|
|
||||||
; DL-NEXT: ret void
|
|
||||||
; DL: F:
|
|
||||||
; DL-NEXT: call void @foo2()
|
|
||||||
; DL-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 4 to i32 addrspace(1)*)
|
%C1 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 4 to i32 addrspace(1)*)
|
||||||
%C2 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 17 to i32 addrspace(1)*)
|
%C2 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 17 to i32 addrspace(1)*)
|
||||||
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
%CN = or i1 %C1, %C2 ; <i1> [#uses=1]
|
||||||
|
@ -81,21 +53,15 @@ T: ; preds = %0
|
||||||
F: ; preds = %0
|
F: ; preds = %0
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test1_ptr_as1(
|
||||||
|
; DL: %magicptr = ptrtoint i32 addrspace(1)* %V to i16
|
||||||
|
; DL: switch i16 %magicptr, label %F [
|
||||||
|
; DL: i16 17, label %T
|
||||||
|
; DL: i16 4, label %T
|
||||||
|
; DL: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2(i32 %V) {
|
define void @test2(i32 %V) {
|
||||||
; CHECK-LABEL: @test2(
|
|
||||||
; CHECK-NEXT: switch i32 [[V:%.*]], label [[T:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 17, label [[F:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[F]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: call void @foo2()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp ne i32 %V, 4 ; <i1> [#uses=1]
|
%C1 = icmp ne i32 %V, 4 ; <i1> [#uses=1]
|
||||||
%C2 = icmp ne i32 %V, 17 ; <i1> [#uses=1]
|
%C2 = icmp ne i32 %V, 17 ; <i1> [#uses=1]
|
||||||
%CN = and i1 %C1, %C2 ; <i1> [#uses=1]
|
%CN = and i1 %C1, %C2 ; <i1> [#uses=1]
|
||||||
|
@ -106,21 +72,14 @@ T: ; preds = %0
|
||||||
F: ; preds = %0
|
F: ; preds = %0
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test2(
|
||||||
|
; CHECK: switch i32 %V, label %T [
|
||||||
|
; CHECK: i32 17, label %F
|
||||||
|
; CHECK: i32 4, label %F
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test3(i32 %V) {
|
define void @test3(i32 %V) {
|
||||||
; CHECK-LABEL: @test3(
|
|
||||||
; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 4, label [[T:%.*]]
|
|
||||||
; CHECK-NEXT: i32 17, label [[T]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: call void @foo2()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
|
%C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
|
||||||
br i1 %C1, label %T, label %N
|
br i1 %C1, label %T, label %N
|
||||||
N: ; preds = %0
|
N: ; preds = %0
|
||||||
|
@ -133,25 +92,16 @@ F: ; preds = %N
|
||||||
call void @foo2( )
|
call void @foo2( )
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test3(
|
||||||
|
; CHECK: switch i32 %V, label %F [
|
||||||
|
; CHECK: i32 4, label %T
|
||||||
|
; CHECK: i32 17, label %T
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
|
define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test4(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i8 [[C:%.*]], label [[LOR_RHS:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 62, label [[LOR_END:%.*]]
|
|
||||||
; CHECK-NEXT: i8 34, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 92, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: lor.rhs:
|
|
||||||
; CHECK-NEXT: br label [[LOR_END]]
|
|
||||||
; CHECK: lor.end:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
|
|
||||||
; CHECK-NEXT: [[LOR_EXT:%.*]] = zext i1 [[TMP0]] to i32
|
|
||||||
; CHECK-NEXT: ret i32 [[LOR_EXT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp eq i8 %c, 62
|
%cmp = icmp eq i8 %c, 62
|
||||||
br i1 %cmp, label %lor.end, label %lor.lhs.false
|
br i1 %cmp, label %lor.end, label %lor.lhs.false
|
||||||
|
@ -169,23 +119,15 @@ lor.end: ; preds = %lor.rhs, %lor.lhs.f
|
||||||
%lor.ext = zext i1 %0 to i32
|
%lor.ext = zext i1 %0 to i32
|
||||||
ret i32 %lor.ext
|
ret i32 %lor.ext
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test4(
|
||||||
|
; CHECK: switch i8 %c, label %lor.rhs [
|
||||||
|
; CHECK: i8 62, label %lor.end
|
||||||
|
; CHECK: i8 34, label %lor.end
|
||||||
|
; CHECK: i8 92, label %lor.end
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
|
define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test5(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i8 [[C:%.*]], label [[LOR_RHS:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 62, label [[LOR_END:%.*]]
|
|
||||||
; CHECK-NEXT: i8 34, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 92, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: lor.rhs:
|
|
||||||
; CHECK-NEXT: br label [[LOR_END]]
|
|
||||||
; CHECK: lor.end:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
|
|
||||||
; CHECK-NEXT: [[LOR_EXT:%.*]] = zext i1 [[TMP0]] to i32
|
|
||||||
; CHECK-NEXT: ret i32 [[LOR_EXT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
switch i8 %c, label %lor.rhs [
|
switch i8 %c, label %lor.rhs [
|
||||||
i8 62, label %lor.end
|
i8 62, label %lor.end
|
||||||
|
@ -201,19 +143,16 @@ lor.end: ; preds = %entry, %entry, %ent
|
||||||
%0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ]
|
%0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ]
|
||||||
%lor.ext = zext i1 %0 to i32
|
%lor.ext = zext i1 %0 to i32
|
||||||
ret i32 %lor.ext
|
ret i32 %lor.ext
|
||||||
|
; CHECK-LABEL: @test5(
|
||||||
|
; CHECK: switch i8 %c, label %lor.rhs [
|
||||||
|
; CHECK: i8 62, label %lor.end
|
||||||
|
; CHECK: i8 34, label %lor.end
|
||||||
|
; CHECK: i8 92, label %lor.end
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define i1 @test6({ i32, i32 }* %I) {
|
define i1 @test6({ i32, i32 }* %I) {
|
||||||
; CHECK-LABEL: @test6(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP_1_I:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[I:%.*]], i64 0, i32 1
|
|
||||||
; CHECK-NEXT: [[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]]
|
|
||||||
; CHECK-NEXT: [[TMP_2_I_OFF:%.*]] = add i32 [[TMP_2_I]], -14
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[TMP_2_I_OFF]], 6
|
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false
|
|
||||||
; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tmp.1.i = getelementptr { i32, i32 }, { i32, i32 }* %I, i64 0, i32 1 ; <i32*> [#uses=1]
|
%tmp.1.i = getelementptr { i32, i32 }, { i32, i32 }* %I, i64 0, i32 1 ; <i32*> [#uses=1]
|
||||||
%tmp.2.i = load i32, i32* %tmp.1.i ; <i32> [#uses=6]
|
%tmp.2.i = load i32, i32* %tmp.1.i ; <i32> [#uses=6]
|
||||||
|
@ -240,24 +179,12 @@ UnifiedReturnBlock: ; preds = %shortcirc_done.4, %shortcirc_next.4
|
||||||
%UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ] ; <i1> [#uses=1]
|
%UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ] ; <i1> [#uses=1]
|
||||||
ret i1 %UnifiedRetVal
|
ret i1 %UnifiedRetVal
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test6(
|
||||||
|
; CHECK: %tmp.2.i.off = add i32 %tmp.2.i, -14
|
||||||
|
; CHECK: %switch = icmp ult i32 %tmp.2.i.off, 6
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
|
define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test7(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32
|
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: switch i8 [[C:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 99, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i8 97, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.then:
|
|
||||||
; CHECK-NEXT: tail call void @foo1() #2
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ult i32 %x, 32
|
%cmp = icmp ult i32 %x, 32
|
||||||
%cmp4 = icmp eq i8 %c, 97
|
%cmp4 = icmp eq i8 %c, 97
|
||||||
|
@ -273,27 +200,17 @@ if.then: ; preds = %entry
|
||||||
if.end: ; preds = %entry
|
if.end: ; preds = %entry
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test7(
|
||||||
|
; CHECK: %cmp = icmp ult i32 %x, 32
|
||||||
|
; CHECK: br i1 %cmp, label %if.then, label %switch.early.test
|
||||||
|
; CHECK: switch.early.test:
|
||||||
|
; CHECK: switch i8 %c, label %if.end [
|
||||||
|
; CHECK: i8 99, label %if.then
|
||||||
|
; CHECK: i8 97, label %if.then
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
|
define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test8(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[N:%.*]], label [[IF_THEN:%.*]]
|
|
||||||
; CHECK: N:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32
|
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN]], label [[SWITCH_EARLY_TEST:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: switch i8 [[C:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 99, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i8 97, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.then:
|
|
||||||
; CHECK-NEXT: [[A:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 42, [[SWITCH_EARLY_TEST]] ], [ 42, [[N]] ], [ 42, [[SWITCH_EARLY_TEST]] ]
|
|
||||||
; CHECK-NEXT: tail call void @foo1() #2
|
|
||||||
; CHECK-NEXT: ret i32 [[A]]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: ret i32 0
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
br i1 %C, label %N, label %if.then
|
br i1 %C, label %N, label %if.then
|
||||||
N:
|
N:
|
||||||
|
@ -312,33 +229,17 @@ if.then: ; preds = %entry
|
||||||
if.end: ; preds = %entry
|
if.end: ; preds = %entry
|
||||||
ret i32 0
|
ret i32 0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test8(
|
||||||
|
; CHECK: switch.early.test:
|
||||||
|
; CHECK: switch i8 %c, label %if.end [
|
||||||
|
; CHECK: i8 99, label %if.then
|
||||||
|
; CHECK: i8 97, label %if.then
|
||||||
|
; CHECK: ]
|
||||||
|
; CHECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ]
|
||||||
}
|
}
|
||||||
|
|
||||||
;; This is "Example 7" from http://blog.regehr.org/archives/320
|
;; This is "Example 7" from http://blog.regehr.org/archives/320
|
||||||
define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
|
define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test9(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[C:%.*]], 33
|
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: switch i8 [[C]], label [[LOR_RHS:%.*]] [
|
|
||||||
; CHECK-NEXT: i8 92, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 62, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 60, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 59, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 58, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 46, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 44, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 34, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: i8 39, label [[LOR_END]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: lor.rhs:
|
|
||||||
; CHECK-NEXT: br label [[LOR_END]]
|
|
||||||
; CHECK: lor.end:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[SWITCH_EARLY_TEST]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY:%.*]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ]
|
|
||||||
; CHECK-NEXT: [[CONV46:%.*]] = zext i1 [[TMP0]] to i32
|
|
||||||
; CHECK-NEXT: ret i32 [[CONV46]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ult i8 %c, 33
|
%cmp = icmp ult i8 %c, 33
|
||||||
br i1 %cmp, label %lor.end, label %lor.lhs.false
|
br i1 %cmp, label %lor.end, label %lor.lhs.false
|
||||||
|
@ -384,23 +285,25 @@ lor.end: ; preds = %lor.rhs, %lor.lhs.f
|
||||||
%conv46 = zext i1 %0 to i32
|
%conv46 = zext i1 %0 to i32
|
||||||
ret i32 %conv46
|
ret i32 %conv46
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test9(
|
||||||
|
; CHECK: %cmp = icmp ult i8 %c, 33
|
||||||
|
; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test
|
||||||
|
|
||||||
|
; CHECK: switch.early.test:
|
||||||
|
; CHECK: switch i8 %c, label %lor.rhs [
|
||||||
|
; CHECK: i8 92, label %lor.end
|
||||||
|
; CHECK: i8 62, label %lor.end
|
||||||
|
; CHECK: i8 60, label %lor.end
|
||||||
|
; CHECK: i8 59, label %lor.end
|
||||||
|
; CHECK: i8 58, label %lor.end
|
||||||
|
; CHECK: i8 46, label %lor.end
|
||||||
|
; CHECK: i8 44, label %lor.end
|
||||||
|
; CHECK: i8 34, label %lor.end
|
||||||
|
; CHECK: i8 39, label %lor.end
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test10(i32 %mode, i1 %Cond) {
|
define i32 @test10(i32 %mode, i1 %Cond) {
|
||||||
; CHECK-LABEL: @test10(
|
|
||||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[SWITCH_EARLY_TEST:%.*]], label [[F:%.*]]
|
|
||||||
; CHECK: switch.early.test:
|
|
||||||
; CHECK-NEXT: switch i32 [[MODE:%.*]], label [[T:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 51, label [[F]]
|
|
||||||
; CHECK-NEXT: i32 0, label [[F]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: T:
|
|
||||||
; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ 123, [[SWITCH_EARLY_TEST]] ], [ 324, [[F]] ]
|
|
||||||
; CHECK-NEXT: ret i32 [[MERGE]]
|
|
||||||
; CHECK: F:
|
|
||||||
; CHECK-NEXT: br label [[T]]
|
|
||||||
;
|
|
||||||
%A = icmp ne i32 %mode, 0
|
%A = icmp ne i32 %mode, 0
|
||||||
%B = icmp ne i32 %mode, 51
|
%B = icmp ne i32 %mode, 51
|
||||||
%C = and i1 %A, %B
|
%C = and i1 %A, %B
|
||||||
|
@ -411,27 +314,17 @@ T:
|
||||||
F:
|
F:
|
||||||
ret i32 324
|
ret i32 324
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test10(
|
||||||
|
; CHECK: br i1 %Cond, label %switch.early.test, label %F
|
||||||
|
; CHECK:switch.early.test:
|
||||||
|
; CHECK: switch i32 %mode, label %T [
|
||||||
|
; CHECK: i32 51, label %F
|
||||||
|
; CHECK: i32 0, label %F
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
; PR8780
|
; PR8780
|
||||||
define i32 @test11(i32 %bar) nounwind {
|
define i32 @test11(i32 %bar) nounwind {
|
||||||
; CHECK-LABEL: @test11(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[BAR:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 55, label [[RETURN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 53, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 35, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 24, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 23, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 12, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[RETURN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: br label [[RETURN]]
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_END]] ], [ 1, [[ENTRY:%.*]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ]
|
|
||||||
; CHECK-NEXT: ret i32 [[RETVAL_0]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp eq i32 %bar, 4
|
%cmp = icmp eq i32 %bar, 4
|
||||||
%cmp2 = icmp eq i32 %bar, 35
|
%cmp2 = icmp eq i32 %bar, 35
|
||||||
|
@ -460,21 +353,19 @@ return: ; preds = %if.end, %if.then
|
||||||
%retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ]
|
%retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ]
|
||||||
ret i32 %retval.0
|
ret i32 %retval.0
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test11(
|
||||||
|
; CHECK: switch i32 %bar, label %if.end [
|
||||||
|
; CHECK: i32 55, label %return
|
||||||
|
; CHECK: i32 53, label %return
|
||||||
|
; CHECK: i32 35, label %return
|
||||||
|
; CHECK: i32 24, label %return
|
||||||
|
; CHECK: i32 23, label %return
|
||||||
|
; CHECK: i32 12, label %return
|
||||||
|
; CHECK: i32 4, label %return
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test12() nounwind {
|
define void @test12() nounwind {
|
||||||
; CHECK-LABEL: @test12(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[A_OLD:%.*]] = icmp eq i32 undef, undef
|
|
||||||
; CHECK-NEXT: br i1 [[A_OLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]]
|
|
||||||
; CHECK: bb55.us.us:
|
|
||||||
; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 undef, undef
|
|
||||||
; CHECK-NEXT: [[A:%.*]] = icmp eq i32 undef, undef
|
|
||||||
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[B]], [[A]]
|
|
||||||
; CHECK-NEXT: br i1 [[OR_COND]], label [[BB55_US_US]], label [[MALFORMED]]
|
|
||||||
; CHECK: malformed:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
br label %bb49.us.us
|
br label %bb49.us.us
|
||||||
|
|
||||||
|
@ -491,26 +382,12 @@ bb55.us.us:
|
||||||
|
|
||||||
malformed:
|
malformed:
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test12(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; test13 - handle switch formation with ult.
|
; test13 - handle switch formation with ult.
|
||||||
define void @test13(i32 %x) nounwind ssp noredzone {
|
define void @test13(i32 %x) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test13(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 6, label [[IF_THEN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 3, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 0, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.then:
|
|
||||||
; CHECK-NEXT: call void @foo1() #3
|
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ult i32 %x, 2
|
%cmp = icmp ult i32 %x, 2
|
||||||
br i1 %cmp, label %if.then, label %lor.lhs.false3
|
br i1 %cmp, label %if.then, label %lor.lhs.false3
|
||||||
|
@ -533,26 +410,18 @@ if.then: ; preds = %lor.lhs.false9, %lo
|
||||||
|
|
||||||
if.end: ; preds = %if.then, %lor.lhs.false9
|
if.end: ; preds = %if.then, %lor.lhs.false9
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test13(
|
||||||
|
; CHECK: switch i32 %x, label %if.end [
|
||||||
|
; CHECK: i32 6, label %if.then
|
||||||
|
; CHECK: i32 4, label %if.then
|
||||||
|
; CHECK: i32 3, label %if.then
|
||||||
|
; CHECK: i32 1, label %if.then
|
||||||
|
; CHECK: i32 0, label %if.then
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
; test14 - handle switch formation with ult.
|
; test14 - handle switch formation with ult.
|
||||||
define void @test14(i32 %x) nounwind ssp noredzone {
|
define void @test14(i32 %x) nounwind ssp noredzone {
|
||||||
; CHECK-LABEL: @test14(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[IF_END:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 6, label [[IF_THEN:%.*]]
|
|
||||||
; CHECK-NEXT: i32 4, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 3, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 2, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 1, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: i32 0, label [[IF_THEN]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if.then:
|
|
||||||
; CHECK-NEXT: call void @foo1() #3
|
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
|
||||||
; CHECK: if.end:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ugt i32 %x, 2
|
%cmp = icmp ugt i32 %x, 2
|
||||||
br i1 %cmp, label %lor.lhs.false3, label %if.then
|
br i1 %cmp, label %lor.lhs.false3, label %if.then
|
||||||
|
@ -575,15 +444,18 @@ if.then: ; preds = %lor.lhs.false9, %lo
|
||||||
|
|
||||||
if.end: ; preds = %if.then, %lor.lhs.false9
|
if.end: ; preds = %if.then, %lor.lhs.false9
|
||||||
ret void
|
ret void
|
||||||
|
; CHECK-LABEL: @test14(
|
||||||
|
; CHECK: switch i32 %x, label %if.end [
|
||||||
|
; CHECK: i32 6, label %if.then
|
||||||
|
; CHECK: i32 4, label %if.then
|
||||||
|
; CHECK: i32 3, label %if.then
|
||||||
|
; CHECK: i32 1, label %if.then
|
||||||
|
; CHECK: i32 0, label %if.then
|
||||||
|
; CHECK: ]
|
||||||
}
|
}
|
||||||
|
|
||||||
; Don't crash on ginormous ranges.
|
; Don't crash on ginormous ranges.
|
||||||
define void @test15(i128 %x) nounwind {
|
define void @test15(i128 %x) nounwind {
|
||||||
; CHECK-LABEL: @test15(
|
|
||||||
; CHECK-NEXT: if.end:
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[X:%.*]], 2
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%cmp = icmp ugt i128 %x, 2
|
%cmp = icmp ugt i128 %x, 2
|
||||||
br i1 %cmp, label %if.end, label %lor.false
|
br i1 %cmp, label %if.end, label %lor.false
|
||||||
|
|
||||||
|
@ -598,19 +470,18 @@ if.then:
|
||||||
if.end:
|
if.end:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test15(
|
||||||
|
; CHECK-NOT: switch
|
||||||
|
; CHECK: ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; PR8675
|
; PR8675
|
||||||
; rdar://5134905
|
; rdar://5134905
|
||||||
define zeroext i1 @test16(i32 %x) nounwind {
|
define zeroext i1 @test16(i32 %x) nounwind {
|
||||||
; CHECK-LABEL: @test16(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -1
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
|
|
||||||
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false
|
|
||||||
; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
|
; CHECK-LABEL: @test16(
|
||||||
|
; CHECK: %x.off = add i32 %x, -1
|
||||||
|
; CHECK: %switch = icmp ult i32 %x.off, 3
|
||||||
%cmp.i = icmp eq i32 %x, 1
|
%cmp.i = icmp eq i32 %x, 1
|
||||||
br i1 %cmp.i, label %lor.end, label %lor.lhs.false
|
br i1 %cmp.i, label %lor.end, label %lor.lhs.false
|
||||||
|
|
||||||
|
@ -629,17 +500,6 @@ lor.end:
|
||||||
|
|
||||||
; Check that we don't turn an icmp into a switch where it's not useful.
|
; Check that we don't turn an icmp into a switch where it's not useful.
|
||||||
define void @test17(i32 %x, i32 %y) {
|
define void @test17(i32 %x, i32 %y) {
|
||||||
; CHECK-LABEL: @test17(
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[Y:%.*]], 2
|
|
||||||
; CHECK-NEXT: [[OR_COND775:%.*]] = or i1 [[CMP]], [[SWITCH]]
|
|
||||||
; CHECK-NEXT: br i1 [[OR_COND775]], label [[LOR_LHS_FALSE8:%.*]], label [[RETURN:%.*]]
|
|
||||||
; CHECK: lor.lhs.false8:
|
|
||||||
; CHECK-NEXT: tail call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: return:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%cmp = icmp ult i32 %x, 3
|
%cmp = icmp ult i32 %x, 3
|
||||||
%switch = icmp ult i32 %y, 2
|
%switch = icmp ult i32 %y, 2
|
||||||
%or.cond775 = or i1 %cmp, %switch
|
%or.cond775 = or i1 %cmp, %switch
|
||||||
|
@ -652,20 +512,13 @@ lor.lhs.false8:
|
||||||
return:
|
return:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test17(
|
||||||
|
; CHECK-NOT: switch.early.test
|
||||||
|
; CHECK-NOT: switch i32
|
||||||
|
; CHECK: ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test18(i32 %arg) {
|
define void @test18(i32 %arg) {
|
||||||
; CHECK-LABEL: @test18(
|
|
||||||
; CHECK-NEXT: bb:
|
|
||||||
; CHECK-NEXT: [[ARG_OFF:%.*]] = add i32 [[ARG:%.*]], -8
|
|
||||||
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[ARG_OFF]], 11
|
|
||||||
; CHECK-NEXT: br i1 [[SWITCH]], label [[BB19:%.*]], label [[BB20:%.*]]
|
|
||||||
; CHECK: bb19:
|
|
||||||
; CHECK-NEXT: tail call void @foo1()
|
|
||||||
; CHECK-NEXT: br label [[BB20]]
|
|
||||||
; CHECK: bb20:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
bb:
|
bb:
|
||||||
%tmp = and i32 %arg, -2
|
%tmp = and i32 %arg, -2
|
||||||
%tmp1 = icmp eq i32 %tmp, 8
|
%tmp1 = icmp eq i32 %tmp, 8
|
||||||
|
@ -697,23 +550,12 @@ bb19: ; preds = %bb8, %bb
|
||||||
bb20: ; preds = %bb19, %bb8
|
bb20: ; preds = %bb19, %bb8
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
; CHECK-LABEL: @test18(
|
||||||
|
; CHECK: %arg.off = add i32 %arg, -8
|
||||||
|
; CHECK: icmp ult i32 %arg.off, 11
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @PR26323(i1 %tobool23, i32 %tmp3) {
|
define void @PR26323(i1 %tobool23, i32 %tmp3) {
|
||||||
; CHECK-LABEL: @PR26323(
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp ne i32 [[TMP3:%.*]], 0
|
|
||||||
; CHECK-NEXT: [[NEG14:%.*]] = and i32 [[TMP3]], -2
|
|
||||||
; CHECK-NEXT: [[CMP17:%.*]] = icmp ne i32 [[NEG14]], -1
|
|
||||||
; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TOBOOL5]], [[TOBOOL23:%.*]]
|
|
||||||
; CHECK-NEXT: [[OR_COND1:%.*]] = and i1 [[CMP17]], [[OR_COND]]
|
|
||||||
; CHECK-NEXT: br i1 [[OR_COND1]], label [[IF_END29:%.*]], label [[IF_THEN27:%.*]]
|
|
||||||
; CHECK: if.then27:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: unreachable
|
|
||||||
; CHECK: if.end29:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%tobool5 = icmp ne i32 %tmp3, 0
|
%tobool5 = icmp ne i32 %tmp3, 0
|
||||||
%neg14 = and i32 %tmp3, -2
|
%neg14 = and i32 %tmp3, -2
|
||||||
|
@ -730,20 +572,21 @@ if.end29: ; preds = %entry
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: define void @PR26323(
|
||||||
|
; CHECK: %tobool5 = icmp ne i32 %tmp3, 0
|
||||||
|
; CHECK: %neg14 = and i32 %tmp3, -2
|
||||||
|
; CHECK: %cmp17 = icmp ne i32 %neg14, -1
|
||||||
|
; CHECK: %or.cond = and i1 %tobool5, %tobool23
|
||||||
|
; CHECK: %or.cond1 = and i1 %cmp17, %or.cond
|
||||||
|
; CHECK: br i1 %or.cond1, label %if.end29, label %if.then27
|
||||||
|
|
||||||
; Form a switch when and'ing a negated power of two
|
; Form a switch when and'ing a negated power of two
|
||||||
|
; CHECK-LABEL: define void @test19
|
||||||
|
; CHECK: switch i32 %arg, label %else [
|
||||||
|
; CHECK: i32 32, label %if
|
||||||
|
; CHECK: i32 13, label %if
|
||||||
|
; CHECK: i32 12, label %if
|
||||||
define void @test19(i32 %arg) {
|
define void @test19(i32 %arg) {
|
||||||
; CHECK-LABEL: @test19(
|
|
||||||
; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[ELSE:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 32, label [[IF:%.*]]
|
|
||||||
; CHECK-NEXT: i32 13, label [[IF]]
|
|
||||||
; CHECK-NEXT: i32 12, label [[IF]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: else:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = and i32 %arg, -2
|
%and = and i32 %arg, -2
|
||||||
%cmp1 = icmp eq i32 %and, 12
|
%cmp1 = icmp eq i32 %and, 12
|
||||||
%cmp2 = icmp eq i32 %arg, 32
|
%cmp2 = icmp eq i32 %arg, 32
|
||||||
|
@ -759,19 +602,10 @@ else:
|
||||||
}
|
}
|
||||||
|
|
||||||
; Since %cmp1 is always false, a switch is never formed
|
; Since %cmp1 is always false, a switch is never formed
|
||||||
|
; CHECK-LABEL: define void @test20
|
||||||
|
; CHECK-NOT: switch
|
||||||
|
; CHECK: ret void
|
||||||
define void @test20(i32 %arg) {
|
define void @test20(i32 %arg) {
|
||||||
; CHECK-LABEL: @test20(
|
|
||||||
; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARG:%.*]], -2
|
|
||||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND]], 13
|
|
||||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[ARG]], 32
|
|
||||||
; CHECK-NEXT: [[PRED:%.*]] = or i1 [[CMP1]], [[CMP2]]
|
|
||||||
; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]]
|
|
||||||
; CHECK: if:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: else:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = and i32 %arg, -2
|
%and = and i32 %arg, -2
|
||||||
%cmp1 = icmp eq i32 %and, 13
|
%cmp1 = icmp eq i32 %and, 13
|
||||||
%cmp2 = icmp eq i32 %arg, 32
|
%cmp2 = icmp eq i32 %arg, 32
|
||||||
|
@ -787,19 +621,11 @@ else:
|
||||||
}
|
}
|
||||||
|
|
||||||
; Form a switch when or'ing a power of two
|
; Form a switch when or'ing a power of two
|
||||||
|
; CHECK-LABEL: define void @test21
|
||||||
|
; CHECK: i32 32, label %else
|
||||||
|
; CHECK: i32 13, label %else
|
||||||
|
; CHECK: i32 12, label %else
|
||||||
define void @test21(i32 %arg) {
|
define void @test21(i32 %arg) {
|
||||||
; CHECK-LABEL: @test21(
|
|
||||||
; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[IF:%.*]] [
|
|
||||||
; CHECK-NEXT: i32 32, label [[ELSE:%.*]]
|
|
||||||
; CHECK-NEXT: i32 13, label [[ELSE]]
|
|
||||||
; CHECK-NEXT: i32 12, label [[ELSE]]
|
|
||||||
; CHECK-NEXT: ]
|
|
||||||
; CHECK: if:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: else:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = or i32 %arg, 1
|
%and = or i32 %arg, 1
|
||||||
%cmp1 = icmp ne i32 %and, 13
|
%cmp1 = icmp ne i32 %and, 13
|
||||||
%cmp2 = icmp ne i32 %arg, 32
|
%cmp2 = icmp ne i32 %arg, 32
|
||||||
|
@ -815,19 +641,10 @@ else:
|
||||||
}
|
}
|
||||||
|
|
||||||
; Since %cmp1 is always false, a switch is never formed
|
; Since %cmp1 is always false, a switch is never formed
|
||||||
|
; CHECK-LABEL: define void @test22
|
||||||
|
; CHECK-NOT: switch
|
||||||
|
; CHECK: ret void
|
||||||
define void @test22(i32 %arg) {
|
define void @test22(i32 %arg) {
|
||||||
; CHECK-LABEL: @test22(
|
|
||||||
; CHECK-NEXT: [[AND:%.*]] = or i32 [[ARG:%.*]], 1
|
|
||||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 12
|
|
||||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[ARG]], 32
|
|
||||||
; CHECK-NEXT: [[PRED:%.*]] = and i1 [[CMP1]], [[CMP2]]
|
|
||||||
; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]]
|
|
||||||
; CHECK: if:
|
|
||||||
; CHECK-NEXT: call void @foo1()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: else:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
%and = or i32 %arg, 1
|
%and = or i32 %arg, 1
|
||||||
%cmp1 = icmp ne i32 %and, 12
|
%cmp1 = icmp ne i32 %and, 12
|
||||||
%cmp2 = icmp ne i32 %arg, 32
|
%cmp2 = icmp ne i32 %arg, 32
|
||||||
|
|
Loading…
Reference in New Issue