Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7603,7 +7603,9 @@ static bool simplifySwitchOfPowersOfTwo(SwitchInst *SI, IRBuilder<> &Builder,
auto *DefaultCaseBB = SI->getDefaultDest();
BasicBlock *SplitBB = SplitBlock(OrigBB, SI, DTU);
auto It = OrigBB->getTerminator()->getIterator();
BranchInst::Create(SplitBB, DefaultCaseBB, IsPow2, It);
auto *BI = BranchInst::Create(SplitBB, DefaultCaseBB, IsPow2, It);
// BI is handling the default case for SI, and so should share its DebugLoc.
BI->setDebugLoc(SI->getDebugLoc());
It->eraseFromParent();

addPredecessorToBlock(DefaultCaseBB, OrigBB, SplitBB);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --tool ./build/bin/opt --version 6
; RUN: opt -passes='simplifycfg<switch-to-lookup>' -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
;; As we replace the switch statement with a set of instructions that may more
;; efficiently perform the conditional check, the DILocation of the switch
;; should be propagated to all of its replacing instructions.

target triple = "x86_64-unknown-linux-gnu"

define i32 @switch_of_powers_two_default_reachable(i32 %arg) !dbg !5 {
; CHECK-LABEL: define i32 @switch_of_powers_two_default_reachable(
; CHECK-SAME: i32 [[ARG:%.*]]) !dbg [[DBG5:![0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[ARG]]), !dbg [[DBG8:![0-9]+]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 1, !dbg [[DBG8]]
; CHECK-NEXT: br i1 [[TMP1]], label %[[ENTRY_SPLIT:.*]], label %[[RETURN:.*]], !dbg [[DBG8]]
; CHECK: [[ENTRY_SPLIT]]:
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.cttz.i32(i32 [[ARG]], i1 true), !dbg [[DBG8]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 7, !dbg [[DBG8]]
; CHECK-NEXT: br i1 [[TMP3]], label %[[SWITCH_LOOKUP:.*]], label %[[RETURN]], !dbg [[DBG8]]
; CHECK: [[SWITCH_LOOKUP]]:
; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[TMP2]] to i64, !dbg [[DBG8]]
; CHECK-NEXT: [[SWITCH_GEP:%.*]] = getelementptr inbounds [7 x i32], ptr @switch.table.switch_of_powers_two_default_reachable, i64 0, i64 [[TMP4]], !dbg [[DBG8]]
; CHECK-NEXT: [[SWITCH_LOAD:%.*]] = load i32, ptr [[SWITCH_GEP]], align 4, !dbg [[DBG8]]
; CHECK-NEXT: br label %[[RETURN]], !dbg [[DBG8]]
; CHECK: [[RETURN]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 5, %[[ENTRY]] ], [ 5, %[[ENTRY_SPLIT]] ], [ [[SWITCH_LOAD]], %[[SWITCH_LOOKUP]] ]
; CHECK-NEXT: ret i32 [[PHI]]
;
entry:
switch i32 %arg, label %default_case [
i32 1, label %bb1
i32 8, label %bb2
i32 16, label %bb3
i32 32, label %bb4
i32 64, label %bb5
], !dbg !8

default_case: ; preds = %entry
br label %return

bb1: ; preds = %entry
br label %return

bb2: ; preds = %entry
br label %return

bb3: ; preds = %entry
br label %return

bb4: ; preds = %entry
br label %return

bb5: ; preds = %entry
br label %return

return: ; preds = %bb5, %bb4, %bb3, %bb2, %bb1, %default_case
%phi = phi i32 [ 3, %bb1 ], [ 2, %bb2 ], [ 1, %bb3 ], [ 0, %bb4 ], [ 42, %bb5 ], [ 5, %default_case ]
ret i32 %phi
}

!llvm.dbg.cu = !{!0}
!llvm.debugify = !{!2, !3}
!llvm.module.flags = !{!4}

!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
!1 = !DIFile(filename: "debugloc-switch-powers-of-two.ll", directory: "/")
!2 = !{i32 9}
!3 = !{i32 1}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = distinct !DISubprogram(name: "switch_of_powers_two_default_reachable", linkageName: "switch_of_powers_two_default_reachable", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !7)
!6 = !DISubroutineType(types: !7)
!7 = !{}
!8 = !DILocation(line: 1, column: 1, scope: !5)
;.
; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META1:![0-9]+]], producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
; CHECK: [[META1]] = !DIFile(filename: "{{.*}}debugloc-switch-powers-of-two.ll", directory: {{.*}})
; CHECK: [[DBG5]] = distinct !DISubprogram(name: "switch_of_powers_two_default_reachable", linkageName: "switch_of_powers_two_default_reachable", scope: null, file: [[META1]], line: 1, type: [[META6:![0-9]+]], scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META7:![0-9]+]])
; CHECK: [[META6]] = !DISubroutineType(types: [[META7]])
; CHECK: [[META7]] = !{}
; CHECK: [[DBG8]] = !DILocation(line: 1, column: 1, scope: [[DBG5]])
;.