Skip to content

Commit f5d62d7

Browse files
committed
[SimplifyCFG] Add tests for deducing paths unreachable if they cause div/rem UB; NFC
1 parent be187a6 commit f5d62d7

File tree

1 file changed

+283
-0
lines changed

1 file changed

+283
-0
lines changed

llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,289 @@ bb5: ; preds = %bb3, %bb
918918
ret i32 %i7
919919
}
920920

921+
declare void @side.effect()
922+
declare i8 @get.i8()
923+
924+
define i8 @udiv_by_zero(i8 %x, i8 %i, i8 %v) {
925+
; CHECK-LABEL: @udiv_by_zero(
926+
; CHECK-NEXT: entry:
927+
; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
928+
; CHECK-NEXT: i8 0, label [[RETURN:%.*]]
929+
; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]]
930+
; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]]
931+
; CHECK-NEXT: ]
932+
; CHECK: sw.bb1:
933+
; CHECK-NEXT: br label [[RETURN]]
934+
; CHECK: sw.bb2:
935+
; CHECK-NEXT: br label [[RETURN]]
936+
; CHECK: sw.default:
937+
; CHECK-NEXT: br label [[RETURN]]
938+
; CHECK: return:
939+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[SW_DEFAULT]] ], [ 0, [[ENTRY:%.*]] ]
940+
; CHECK-NEXT: [[R:%.*]] = udiv i8 [[X:%.*]], [[Y]]
941+
; CHECK-NEXT: ret i8 [[R]]
942+
;
943+
entry:
944+
switch i8 %i, label %sw.default [
945+
i8 0, label %sw.bb0
946+
i8 2, label %sw.bb1
947+
i8 9, label %sw.bb2
948+
]
949+
950+
sw.bb0:
951+
br label %return
952+
953+
sw.bb1:
954+
br label %return
955+
sw.bb2:
956+
br label %return
957+
sw.default:
958+
br label %return
959+
960+
return:
961+
%y = phi i8 [ 0, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ %v, %sw.default ]
962+
%r = udiv i8 %x, %y
963+
ret i8 %r
964+
}
965+
966+
define i8 @urem_by_zero(i8 %x, i8 %i, i8 %v) {
967+
; CHECK-LABEL: @urem_by_zero(
968+
; CHECK-NEXT: entry:
969+
; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
970+
; CHECK-NEXT: i8 0, label [[RETURN:%.*]]
971+
; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]]
972+
; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]]
973+
; CHECK-NEXT: ]
974+
; CHECK: sw.bb1:
975+
; CHECK-NEXT: br label [[RETURN]]
976+
; CHECK: sw.bb2:
977+
; CHECK-NEXT: br label [[RETURN]]
978+
; CHECK: sw.default:
979+
; CHECK-NEXT: br label [[RETURN]]
980+
; CHECK: return:
981+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ 0, [[SW_DEFAULT]] ], [ [[V:%.*]], [[ENTRY:%.*]] ]
982+
; CHECK-NEXT: [[R:%.*]] = urem i8 [[X:%.*]], [[Y]]
983+
; CHECK-NEXT: ret i8 [[R]]
984+
;
985+
entry:
986+
switch i8 %i, label %sw.default [
987+
i8 0, label %sw.bb0
988+
i8 2, label %sw.bb1
989+
i8 9, label %sw.bb2
990+
]
991+
992+
sw.bb0:
993+
br label %return
994+
995+
sw.bb1:
996+
br label %return
997+
sw.bb2:
998+
br label %return
999+
sw.default:
1000+
br label %return
1001+
1002+
return:
1003+
%y = phi i8 [ %v, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ 0, %sw.default ]
1004+
%r = urem i8 %x, %y
1005+
ret i8 %r
1006+
}
1007+
1008+
define i8 @udiv_of_zero_okay(i8 %x, i8 %i, i8 %v) {
1009+
; CHECK-LABEL: @udiv_of_zero_okay(
1010+
; CHECK-NEXT: entry:
1011+
; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
1012+
; CHECK-NEXT: i8 0, label [[RETURN:%.*]]
1013+
; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]]
1014+
; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]]
1015+
; CHECK-NEXT: ]
1016+
; CHECK: sw.bb1:
1017+
; CHECK-NEXT: br label [[RETURN]]
1018+
; CHECK: sw.bb2:
1019+
; CHECK-NEXT: br label [[RETURN]]
1020+
; CHECK: sw.default:
1021+
; CHECK-NEXT: br label [[RETURN]]
1022+
; CHECK: return:
1023+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[SW_DEFAULT]] ], [ 0, [[ENTRY:%.*]] ]
1024+
; CHECK-NEXT: [[R:%.*]] = udiv i8 [[Y]], [[X:%.*]]
1025+
; CHECK-NEXT: ret i8 [[R]]
1026+
;
1027+
entry:
1028+
switch i8 %i, label %sw.default [
1029+
i8 0, label %sw.bb0
1030+
i8 2, label %sw.bb1
1031+
i8 9, label %sw.bb2
1032+
]
1033+
1034+
sw.bb0:
1035+
br label %return
1036+
1037+
sw.bb1:
1038+
br label %return
1039+
sw.bb2:
1040+
br label %return
1041+
sw.default:
1042+
br label %return
1043+
1044+
return:
1045+
%y = phi i8 [ 0, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ %v, %sw.default ]
1046+
%r = udiv i8 %y, %x
1047+
ret i8 %r
1048+
}
1049+
1050+
define i8 @srem_by_zero(i8 %x, i8 %i) {
1051+
; CHECK-LABEL: @srem_by_zero(
1052+
; CHECK-NEXT: entry:
1053+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[I:%.*]], 9
1054+
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1055+
; CHECK: if.then:
1056+
; CHECK-NEXT: call void @side.effect()
1057+
; CHECK-NEXT: br label [[IF_END:%.*]]
1058+
; CHECK: if.else:
1059+
; 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]]
1064+
; CHECK-NEXT: ret i8 [[R]]
1065+
;
1066+
entry:
1067+
%cmp = icmp ult i8 %i, 9
1068+
br i1 %cmp, label %if.then, label %if.else
1069+
1070+
if.then:
1071+
call void @side.effect()
1072+
br label %if.end
1073+
1074+
if.else:
1075+
%v = call i8 @get.i8()
1076+
br label %if.end
1077+
1078+
if.end:
1079+
%y = phi i8 [ 0, %if.then ], [ %v, %if.else ]
1080+
%r = srem i8 %x, %y
1081+
ret i8 %r
1082+
}
1083+
1084+
define i8 @srem_no_overflow_okay(i8 %i) {
1085+
; CHECK-LABEL: @srem_no_overflow_okay(
1086+
; CHECK-NEXT: entry:
1087+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[I:%.*]], 9
1088+
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1089+
; CHECK: if.then:
1090+
; CHECK-NEXT: call void @side.effect()
1091+
; CHECK-NEXT: br label [[IF_END:%.*]]
1092+
; CHECK: if.else:
1093+
; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8()
1094+
; CHECK-NEXT: br label [[IF_END]]
1095+
; CHECK: if.end:
1096+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ -1, [[IF_THEN]] ], [ [[V]], [[IF_ELSE]] ]
1097+
; CHECK-NEXT: [[R:%.*]] = srem i8 [[Y]], -128
1098+
; CHECK-NEXT: ret i8 [[R]]
1099+
;
1100+
entry:
1101+
%cmp = icmp ult i8 %i, 9
1102+
br i1 %cmp, label %if.then, label %if.else
1103+
1104+
if.then:
1105+
call void @side.effect()
1106+
br label %if.end
1107+
1108+
if.else:
1109+
%v = call i8 @get.i8()
1110+
br label %if.end
1111+
1112+
if.end:
1113+
%y = phi i8 [ -1, %if.then ], [ %v, %if.else ]
1114+
%r = srem i8 %y, 128
1115+
ret i8 %r
1116+
}
1117+
1118+
define i8 @sdiv_overflow_ub(i8 %i) {
1119+
; CHECK-LABEL: @sdiv_overflow_ub(
1120+
; CHECK-NEXT: entry:
1121+
; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
1122+
; CHECK-NEXT: i8 0, label [[RETURN:%.*]]
1123+
; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]]
1124+
; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]]
1125+
; CHECK-NEXT: ]
1126+
; CHECK: sw.bb1:
1127+
; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8()
1128+
; CHECK-NEXT: br label [[RETURN]]
1129+
; CHECK: sw.bb2:
1130+
; CHECK-NEXT: br label [[RETURN]]
1131+
; CHECK: sw.default:
1132+
; CHECK-NEXT: unreachable
1133+
; CHECK: return:
1134+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ [[V]], [[SW_BB1]] ], [ -1, [[SW_BB2]] ], [ 4, [[ENTRY:%.*]] ]
1135+
; CHECK-NEXT: [[R:%.*]] = sdiv i8 -128, [[Y]]
1136+
; CHECK-NEXT: ret i8 [[R]]
1137+
;
1138+
entry:
1139+
switch i8 %i, label %sw.default [
1140+
i8 0, label %sw.bb0
1141+
i8 2, label %sw.bb1
1142+
i8 9, label %sw.bb2
1143+
]
1144+
1145+
sw.bb0:
1146+
br label %return
1147+
sw.bb1:
1148+
%v = call i8 @get.i8()
1149+
br label %return
1150+
sw.bb2:
1151+
br label %return
1152+
sw.default:
1153+
unreachable
1154+
1155+
return:
1156+
%y = phi i8 [ 4, %sw.bb0 ], [ %v, %sw.bb1 ], [ -1, %sw.bb2 ]
1157+
%r = sdiv i8 128, %y
1158+
ret i8 %r
1159+
}
1160+
1161+
define i8 @sdiv_overflow_ub_2x(i8 %i) {
1162+
; CHECK-LABEL: @sdiv_overflow_ub_2x(
1163+
; CHECK-NEXT: entry:
1164+
; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
1165+
; CHECK-NEXT: i8 0, label [[RETURN:%.*]]
1166+
; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]]
1167+
; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]]
1168+
; CHECK-NEXT: ]
1169+
; CHECK: sw.bb1:
1170+
; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8()
1171+
; CHECK-NEXT: br label [[RETURN]]
1172+
; CHECK: sw.bb2:
1173+
; CHECK-NEXT: br label [[RETURN]]
1174+
; CHECK: sw.default:
1175+
; CHECK-NEXT: unreachable
1176+
; CHECK: return:
1177+
; CHECK-NEXT: [[Y:%.*]] = phi i8 [ [[V]], [[SW_BB1]] ], [ -1, [[SW_BB2]] ], [ 0, [[ENTRY:%.*]] ]
1178+
; CHECK-NEXT: [[R:%.*]] = sdiv i8 -128, [[Y]]
1179+
; CHECK-NEXT: ret i8 [[R]]
1180+
;
1181+
entry:
1182+
switch i8 %i, label %sw.default [
1183+
i8 0, label %sw.bb0
1184+
i8 2, label %sw.bb1
1185+
i8 9, label %sw.bb2
1186+
]
1187+
1188+
sw.bb0:
1189+
br label %return
1190+
sw.bb1:
1191+
%v = call i8 @get.i8()
1192+
br label %return
1193+
sw.bb2:
1194+
br label %return
1195+
sw.default:
1196+
unreachable
1197+
1198+
return:
1199+
%y = phi i8 [ 0, %sw.bb0 ], [ %v, %sw.bb1 ], [ -1, %sw.bb2 ]
1200+
%r = sdiv i8 128, %y
1201+
ret i8 %r
1202+
}
1203+
9211204
attributes #0 = { null_pointer_is_valid }
9221205
;.
9231206
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }

0 commit comments

Comments
 (0)