315 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py2; RUN: llc -mtriple aarch64 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s3 4declare i32 @bar(...)5define void @or_cond(i32 %X, i32 %Y, i32 %Z) nounwind {6 ; CHECK-LABEL: name: or_cond7 ; CHECK: bb.1.entry:8 ; CHECK: successors: %bb.3(0x20000000), %bb.4(0x60000000)9 ; CHECK: liveins: $w0, $w1, $w210 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w011 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w112 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w213 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 014 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 515 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]16 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]17 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]18 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]19 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.320 ; CHECK: G_BR %bb.421 ; CHECK: bb.4.entry:22 ; CHECK: successors: %bb.3(0x2aaaaaab), %bb.2(0x55555555)23 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]24 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.325 ; CHECK: G_BR %bb.226 ; CHECK: bb.2.common.ret:27 ; CHECK: RET_ReallyLR28 ; CHECK: bb.3.cond_true:29 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp30entry:31 %tmp1 = icmp eq i32 %X, 032 %tmp3 = icmp slt i32 %Y, 533 %tmp4 = or i1 %tmp3, %tmp134 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock35 36cond_true:37 %tmp5 = tail call i32 (...) @bar( )38 ret void39 40UnifiedReturnBlock:41 ret void42}43 44define void @or_cond_select(i32 %X, i32 %Y, i32 %Z) nounwind {45 ; CHECK-LABEL: name: or_cond_select46 ; CHECK: bb.1.entry:47 ; CHECK: successors: %bb.3(0x20000000), %bb.4(0x60000000)48 ; CHECK: liveins: $w0, $w1, $w249 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w050 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w151 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w252 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 053 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 554 ; CHECK: [[C2:%[0-9]+]]:_(s1) = G_CONSTANT i1 true55 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]56 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]57 ; CHECK: [[SELECT:%[0-9]+]]:_(s1) = G_SELECT [[ICMP1]](s1), [[C2]], [[ICMP]]58 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]59 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.360 ; CHECK: G_BR %bb.461 ; CHECK: bb.4.entry:62 ; CHECK: successors: %bb.3(0x2aaaaaab), %bb.2(0x55555555)63 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]64 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.365 ; CHECK: G_BR %bb.266 ; CHECK: bb.2.common.ret:67 ; CHECK: RET_ReallyLR68 ; CHECK: bb.3.cond_true:69 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp70entry:71 %tmp1 = icmp eq i32 %X, 072 %tmp3 = icmp slt i32 %Y, 573 %tmp4 = select i1 %tmp3, i1 true, i1 %tmp174 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock75 76cond_true:77 %tmp5 = tail call i32 (...) @bar( )78 ret void79 80UnifiedReturnBlock:81 ret void82}83 84define void @and_cond(i32 %X, i32 %Y, i32 %Z) nounwind {85 ; CHECK-LABEL: name: and_cond86 ; CHECK: bb.1.entry:87 ; CHECK: successors: %bb.4(0x60000000), %bb.2(0x20000000)88 ; CHECK: liveins: $w0, $w1, $w289 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w090 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w191 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w292 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 093 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 594 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]95 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]96 ; CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[ICMP1]], [[ICMP]]97 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]98 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.499 ; CHECK: G_BR %bb.2100 ; CHECK: bb.4.entry:101 ; CHECK: successors: %bb.3(0x55555555), %bb.2(0x2aaaaaab)102 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]103 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.3104 ; CHECK: G_BR %bb.2105 ; CHECK: bb.2.common.ret:106 ; CHECK: RET_ReallyLR107 ; CHECK: bb.3.cond_true:108 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp109entry:110 %tmp1 = icmp eq i32 %X, 0111 %tmp3 = icmp slt i32 %Y, 5112 %tmp4 = and i1 %tmp3, %tmp1113 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock114 115cond_true:116 %tmp5 = tail call i32 (...) @bar( )117 ret void118 119UnifiedReturnBlock:120 ret void121}122 123define void @and_cond_select(i32 %X, i32 %Y, i32 %Z) nounwind {124 ; CHECK-LABEL: name: and_cond_select125 ; CHECK: bb.1.entry:126 ; CHECK: successors: %bb.4(0x60000000), %bb.2(0x20000000)127 ; CHECK: liveins: $w0, $w1, $w2128 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0129 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1130 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2131 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0132 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 5133 ; CHECK: [[C2:%[0-9]+]]:_(s1) = G_CONSTANT i1 false134 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]135 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]136 ; CHECK: [[SELECT:%[0-9]+]]:_(s1) = G_SELECT [[ICMP1]](s1), [[ICMP]], [[C2]]137 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]138 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.4139 ; CHECK: G_BR %bb.2140 ; CHECK: bb.4.entry:141 ; CHECK: successors: %bb.3(0x55555555), %bb.2(0x2aaaaaab)142 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]143 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.3144 ; CHECK: G_BR %bb.2145 ; CHECK: bb.2.common.ret:146 ; CHECK: RET_ReallyLR147 ; CHECK: bb.3.cond_true:148 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp149entry:150 %tmp1 = icmp eq i32 %X, 0151 %tmp3 = icmp slt i32 %Y, 5152 %tmp4 = select i1 %tmp3, i1 %tmp1, i1 false153 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock154 155cond_true:156 %tmp5 = tail call i32 (...) @bar( )157 ret void158 159UnifiedReturnBlock:160 ret void161}162 163; Don't emit two branches for same operands.164define void @or_cond_same_values_cmp(i32 %X, i32 %Y, i32 %Z) nounwind {165 ; CHECK-LABEL: name: or_cond_same_values_cmp166 ; CHECK: bb.1.entry:167 ; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)168 ; CHECK: liveins: $w0, $w1, $w2169 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0170 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1171 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2172 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5173 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]174 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY]](s32), [[C]]175 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]176 ; CHECK: G_BRCOND [[OR]](s1), %bb.3177 ; CHECK: G_BR %bb.2178 ; CHECK: bb.2.common.ret:179 ; CHECK: RET_ReallyLR180 ; CHECK: bb.3.cond_true:181 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp182entry:183 %tmp1 = icmp eq i32 %X, 5184 %tmp3 = icmp slt i32 %X, 5185 %tmp4 = or i1 %tmp3, %tmp1186 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock187 188cond_true:189 %tmp5 = tail call i32 (...) @bar( )190 ret void191 192UnifiedReturnBlock:193 ret void194}195 196; Emit multiple branches for more than 2 cases.197define void @or_cond_multiple_cases(i32 %X, i32 %Y, i32 %Z) nounwind {198 ; CHECK-LABEL: name: or_cond_multiple_cases199 ; CHECK: bb.1.entry:200 ; CHECK: successors: %bb.3(0x10000000), %bb.5(0x70000000)201 ; CHECK: liveins: $w0, $w1, $w2202 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0203 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1204 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2205 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5206 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]207 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY]](s32), [[C]]208 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY2]](s32), [[C]]209 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]210 ; CHECK: [[OR1:%[0-9]+]]:_(s1) = G_OR [[OR]], [[ICMP2]]211 ; CHECK: [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY]](s32), [[C]]212 ; CHECK: G_BRCOND [[ICMP3]](s1), %bb.3213 ; CHECK: G_BR %bb.5214 ; CHECK: bb.5.entry:215 ; CHECK: successors: %bb.3(0x12492492), %bb.4(0x6db6db6e)216 ; CHECK: [[ICMP4:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]217 ; CHECK: G_BRCOND [[ICMP4]](s1), %bb.3218 ; CHECK: G_BR %bb.4219 ; CHECK: bb.4.entry:220 ; CHECK: successors: %bb.3(0x2aaaaaab), %bb.2(0x55555555)221 ; CHECK: [[ICMP5:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY2]](s32), [[C]]222 ; CHECK: G_BRCOND [[ICMP5]](s1), %bb.3223 ; CHECK: G_BR %bb.2224 ; CHECK: bb.2.common.ret:225 ; CHECK: RET_ReallyLR226 ; CHECK: bb.3.cond_true:227 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp228entry:229 %tmp1 = icmp eq i32 %X, 5230 %tmp3 = icmp slt i32 %X, 5231 %tmpZ = icmp eq i32 %Z, 5232 %tmp4 = or i1 %tmp3, %tmp1233 %final = or i1 %tmp4, %tmpZ234 br i1 %final, label %cond_true, label %UnifiedReturnBlock235 236cond_true:237 %tmp5 = tail call i32 (...) @bar( )238 ret void239 240UnifiedReturnBlock:241 ret void242}243 244; (X != null) | (Y != null) --> (X|Y) != 0245; Don't emit two branches.246define void @or_cond_ne_null(i32 %X, i32 %Y, i32 %Z) nounwind {247 ; CHECK-LABEL: name: or_cond_ne_null248 ; CHECK: bb.1.entry:249 ; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)250 ; CHECK: liveins: $w0, $w1, $w2251 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0252 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1253 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2254 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0255 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[COPY]](s32), [[C]]256 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[COPY1]](s32), [[C]]257 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]258 ; CHECK: G_BRCOND [[OR]](s1), %bb.3259 ; CHECK: G_BR %bb.2260 ; CHECK: bb.2.common.ret:261 ; CHECK: RET_ReallyLR262 ; CHECK: bb.3.cond_true:263 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp264entry:265 %tmp1 = icmp ne i32 %X, 0266 %tmp3 = icmp ne i32 %Y, 0267 %tmp4 = or i1 %tmp3, %tmp1268 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock269 270cond_true:271 %tmp5 = tail call i32 (...) @bar( )272 ret void273 274UnifiedReturnBlock:275 ret void276}277 278; If the branch is unpredictable, don't add another branch279; regardless of whether they are expensive or not.280 281define void @unpredictable(i32 %X, i32 %Y, i32 %Z) nounwind {282 ; CHECK-LABEL: name: unpredictable283 ; CHECK: bb.1.entry:284 ; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)285 ; CHECK: liveins: $w0, $w1, $w2286 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0287 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1288 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2289 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0290 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 5291 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]292 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), [[COPY1]](s32), [[C1]]293 ; CHECK: [[OR:%[0-9]+]]:_(s1) = G_OR [[ICMP1]], [[ICMP]]294 ; CHECK: G_BRCOND [[OR]](s1), %bb.3295 ; CHECK: G_BR %bb.2296 ; CHECK: bb.2.common.ret:297 ; CHECK: RET_ReallyLR298 ; CHECK: bb.3.cond_true:299 ; CHECK: TCRETURNdi @bar, 0, csr_aarch64_aapcs, implicit $sp300entry:301 %tmp1 = icmp eq i32 %X, 0302 %tmp3 = icmp slt i32 %Y, 5303 %tmp4 = or i1 %tmp3, %tmp1304 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock, !unpredictable !0305 306cond_true:307 %tmp5 = tail call i32 (...) @bar( )308 ret void309 310UnifiedReturnBlock:311 ret void312}313 314!0 = !{}315