Skip to content

Commit 3793264

Browse files
committed
[SimplifyCFG] Deduce paths unreachable if they cause div/rem UB
Same we way mark a path unreachable if it may cause a nullptr dereference, div/rem by zero or signed div/rem of INT_MIN by -1 cause immediate UB. Closes #109008
1 parent f5d62d7 commit 3793264

File tree

2 files changed

+18
-17
lines changed

2 files changed

+18
-17
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7885,6 +7885,13 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
78857885
case Instruction::Call:
78867886
case Instruction::CallBr:
78877887
case Instruction::Invoke:
7888+
case Instruction::UDiv:
7889+
case Instruction::URem:
7890+
// Note: signed div/rem of INT_MIN / -1 is also immediate UB, not
7891+
// implemented to avoid code complexity as it is unclear how useful such
7892+
// logic is.
7893+
case Instruction::SDiv:
7894+
case Instruction::SRem:
78887895
return true;
78897896
}
78907897
});
@@ -7986,6 +7993,9 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
79867993
}
79877994
}
79887995
}
7996+
// Div/Rem by zero is immediate UB
7997+
if (match(Use, m_BinOp(m_Value(), m_Specific(I))) && Use->isIntDivRem())
7998+
return true;
79897999
}
79908000
return false;
79918001
}

llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -925,18 +925,15 @@ define i8 @udiv_by_zero(i8 %x, i8 %i, i8 %v) {
925925
; CHECK-LABEL: @udiv_by_zero(
926926
; CHECK-NEXT: entry:
927927
; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
928-
; CHECK-NEXT: i8 0, label [[RETURN:%.*]]
929-
; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]]
930928
; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]]
929+
; CHECK-NEXT: i8 2, label [[RETURN:%.*]]
931930
; CHECK-NEXT: ]
932-
; CHECK: sw.bb1:
933-
; CHECK-NEXT: br label [[RETURN]]
934931
; CHECK: sw.bb2:
935932
; CHECK-NEXT: br label [[RETURN]]
936933
; CHECK: sw.default:
937934
; CHECK-NEXT: br label [[RETURN]]
938935
; CHECK: return:
939-
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[SW_DEFAULT]] ], [ 0, [[ENTRY:%.*]] ]
936+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[SW_DEFAULT]] ], [ 2, [[ENTRY:%.*]] ]
940937
; CHECK-NEXT: [[R:%.*]] = udiv i8 [[X:%.*]], [[Y]]
941938
; CHECK-NEXT: ret i8 [[R]]
942939
;
@@ -976,9 +973,9 @@ define i8 @urem_by_zero(i8 %x, i8 %i, i8 %v) {
976973
; CHECK: sw.bb2:
977974
; CHECK-NEXT: br label [[RETURN]]
978975
; CHECK: sw.default:
979-
; CHECK-NEXT: br label [[RETURN]]
976+
; CHECK-NEXT: unreachable
980977
; CHECK: return:
981-
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ 0, [[SW_DEFAULT]] ], [ [[V:%.*]], [[ENTRY:%.*]] ]
978+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[ENTRY:%.*]] ]
982979
; CHECK-NEXT: [[R:%.*]] = urem i8 [[X:%.*]], [[Y]]
983980
; CHECK-NEXT: ret i8 [[R]]
984981
;
@@ -1054,13 +1051,10 @@ define i8 @srem_by_zero(i8 %x, i8 %i) {
10541051
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
10551052
; CHECK: if.then:
10561053
; CHECK-NEXT: call void @side.effect()
1057-
; CHECK-NEXT: br label [[IF_END:%.*]]
1054+
; CHECK-NEXT: unreachable
10581055
; CHECK: if.else:
10591056
; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8()
1060-
; CHECK-NEXT: br label [[IF_END]]
1061-
; CHECK: if.end:
1062-
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 0, [[IF_THEN]] ], [ [[V]], [[IF_ELSE]] ]
1063-
; CHECK-NEXT: [[R:%.*]] = srem i8 [[X:%.*]], [[Y]]
1057+
; CHECK-NEXT: [[R:%.*]] = srem i8 [[X:%.*]], [[V]]
10641058
; CHECK-NEXT: ret i8 [[R]]
10651059
;
10661060
entry:
@@ -1162,19 +1156,16 @@ define i8 @sdiv_overflow_ub_2x(i8 %i) {
11621156
; CHECK-LABEL: @sdiv_overflow_ub_2x(
11631157
; CHECK-NEXT: entry:
11641158
; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
1165-
; CHECK-NEXT: i8 0, label [[RETURN:%.*]]
1159+
; CHECK-NEXT: i8 9, label [[RETURN:%.*]]
11661160
; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]]
1167-
; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]]
11681161
; CHECK-NEXT: ]
11691162
; CHECK: sw.bb1:
11701163
; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8()
11711164
; CHECK-NEXT: br label [[RETURN]]
1172-
; CHECK: sw.bb2:
1173-
; CHECK-NEXT: br label [[RETURN]]
11741165
; CHECK: sw.default:
11751166
; CHECK-NEXT: unreachable
11761167
; CHECK: return:
1177-
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ [[V]], [[SW_BB1]] ], [ -1, [[SW_BB2]] ], [ 0, [[ENTRY:%.*]] ]
1168+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ [[V]], [[SW_BB1]] ], [ -1, [[ENTRY:%.*]] ]
11781169
; CHECK-NEXT: [[R:%.*]] = sdiv i8 -128, [[Y]]
11791170
; CHECK-NEXT: ret i8 [[R]]
11801171
;

0 commit comments

Comments
 (0)