1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7define i1 @test1(i1 %a, i1 %b) { 8; CHECK-LABEL: @test1( 9; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 10; CHECK-NEXT: [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]] 11; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]] 12; CHECK-NEXT: ret i1 [[AND]] 13; 14 %wc = call i1 @llvm.experimental.widenable.condition() 15 %lhs = and i1 %b, %wc 16 %and = and i1 %lhs, %a 17 ret i1 %and 18} 19 20define i1 @test1_logical(i1 %a, i1 %b) { 21; CHECK-LABEL: @test1_logical( 22; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 23; CHECK-NEXT: [[LHS:%.*]] = select i1 [[B:%.*]], i1 [[WC]], i1 false 24; CHECK-NEXT: [[AND:%.*]] = select i1 [[LHS]], i1 [[A:%.*]], i1 false 25; CHECK-NEXT: ret i1 [[AND]] 26; 27 %wc = call i1 @llvm.experimental.widenable.condition() 28 %lhs = select i1 %b, i1 %wc, i1 false 29 %and = select i1 %lhs, i1 %a, i1 false 30 ret i1 %and 31} 32 33; Negative test - profitability of dropping WC from first use unclear 34define i1 @test1b(i1 %a, i1 %b) { 35; CHECK-LABEL: @test1b( 36; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 37; CHECK-NEXT: [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]] 38; CHECK-NEXT: call void @use(i1 [[LHS]]) 39; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]] 40; CHECK-NEXT: ret i1 [[AND]] 41; 42 %wc = call i1 @llvm.experimental.widenable.condition() 43 %lhs = and i1 %b, %wc 44 call void @use(i1 %lhs) 45 %and = and i1 %lhs, %a 46 ret i1 %and 47} 48 49define i1 @test1b_logical(i1 %a, i1 %b) { 50; CHECK-LABEL: @test1b_logical( 51; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 52; CHECK-NEXT: [[LHS:%.*]] = select i1 [[B:%.*]], i1 [[WC]], i1 false 53; CHECK-NEXT: call void @use(i1 [[LHS]]) 54; CHECK-NEXT: [[AND:%.*]] = select i1 [[LHS]], i1 [[A:%.*]], i1 false 55; CHECK-NEXT: ret i1 [[AND]] 56; 57 %wc = call i1 @llvm.experimental.widenable.condition() 58 %lhs = select i1 %b, i1 %wc, i1 false 59 call void @use(i1 %lhs) 60 %and = select i1 %lhs, i1 %a, i1 false 61 ret i1 %and 62} 63 64; multiple uses of A, B, WC doesn't change result 65define i1 @test1c(i1 %a, i1 %b) { 66; CHECK-LABEL: @test1c( 67; CHECK-NEXT: call void @use(i1 [[A:%.*]]) 68; CHECK-NEXT: call void @use(i1 [[B:%.*]]) 69; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 70; CHECK-NEXT: call void @use(i1 [[WC]]) 71; CHECK-NEXT: [[LHS:%.*]] = and i1 [[WC]], [[B]] 72; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[A]] 73; CHECK-NEXT: ret i1 [[AND]] 74; 75 call void @use(i1 %a) 76 call void @use(i1 %b) 77 %wc = call i1 @llvm.experimental.widenable.condition() 78 call void @use(i1 %wc) 79 %lhs = and i1 %b, %wc 80 %and = and i1 %lhs, %a 81 ret i1 %and 82} 83 84define i1 @test1c_logical(i1 %a, i1 %b) { 85; CHECK-LABEL: @test1c_logical( 86; CHECK-NEXT: call void @use(i1 [[A:%.*]]) 87; CHECK-NEXT: call void @use(i1 [[B:%.*]]) 88; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 89; CHECK-NEXT: call void @use(i1 [[WC]]) 90; CHECK-NEXT: [[LHS:%.*]] = select i1 [[B]], i1 [[WC]], i1 false 91; CHECK-NEXT: [[AND:%.*]] = select i1 [[LHS]], i1 [[A]], i1 false 92; CHECK-NEXT: ret i1 [[AND]] 93; 94 call void @use(i1 %a) 95 call void @use(i1 %b) 96 %wc = call i1 @llvm.experimental.widenable.condition() 97 call void @use(i1 %wc) 98 %lhs = select i1 %b, i1 %wc, i1 false 99 %and = select i1 %lhs, i1 %a, i1 false 100 ret i1 %and 101} 102 103define i1 @test2(i1 %a, i1 %b) { 104; CHECK-LABEL: @test2( 105; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 106; CHECK-NEXT: [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]] 107; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]] 108; CHECK-NEXT: ret i1 [[AND]] 109; 110 %wc = call i1 @llvm.experimental.widenable.condition() 111 %lhs = and i1 %wc, %b 112 %and = and i1 %lhs, %a 113 ret i1 %and 114} 115 116define i1 @test2_logical(i1 %a, i1 %b) { 117; CHECK-LABEL: @test2_logical( 118; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 119; CHECK-NEXT: [[LHS:%.*]] = select i1 [[WC]], i1 [[B:%.*]], i1 false 120; CHECK-NEXT: [[AND:%.*]] = select i1 [[LHS]], i1 [[A:%.*]], i1 false 121; CHECK-NEXT: ret i1 [[AND]] 122; 123 %wc = call i1 @llvm.experimental.widenable.condition() 124 %lhs = select i1 %wc, i1 %b, i1 false 125 %and = select i1 %lhs, i1 %a, i1 false 126 ret i1 %and 127} 128 129; To test the rhs side, an instruction on lhs to prevent complexity 130; canonicalization reducing to above. 131define i1 @test3(i1 %a, i1 %b, i1 %c) { 132; CHECK-LABEL: @test3( 133; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 134; CHECK-NEXT: [[LHS:%.*]] = and i1 [[A:%.*]], [[B:%.*]] 135; CHECK-NEXT: [[RHS:%.*]] = and i1 [[WC]], [[C:%.*]] 136; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[RHS]] 137; CHECK-NEXT: ret i1 [[AND]] 138; 139 %wc = call i1 @llvm.experimental.widenable.condition() 140 %lhs = and i1 %a, %b 141 %rhs = and i1 %c, %wc 142 %and = and i1 %lhs, %rhs 143 ret i1 %and 144} 145 146define i1 @test3_logical(i1 %a, i1 %b, i1 %c) { 147; CHECK-LABEL: @test3_logical( 148; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 149; CHECK-NEXT: [[LHS:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 150; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[LHS]], i1 [[C:%.*]], i1 false 151; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i1 [[WC]], i1 false 152; CHECK-NEXT: ret i1 [[AND]] 153; 154 %wc = call i1 @llvm.experimental.widenable.condition() 155 %lhs = select i1 %a, i1 %b, i1 false 156 %rhs = select i1 %c, i1 %wc, i1 false 157 %and = select i1 %lhs, i1 %rhs, i1 false 158 ret i1 %and 159} 160 161define i1 @test4(i1 %a, i1 %b, i1 %c) { 162; CHECK-LABEL: @test4( 163; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 164; CHECK-NEXT: [[LHS:%.*]] = and i1 [[A:%.*]], [[B:%.*]] 165; CHECK-NEXT: [[RHS:%.*]] = and i1 [[WC]], [[C:%.*]] 166; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[RHS]] 167; CHECK-NEXT: ret i1 [[AND]] 168; 169 %wc = call i1 @llvm.experimental.widenable.condition() 170 %lhs = and i1 %a, %b 171 %rhs = and i1 %wc, %c 172 %and = and i1 %lhs, %rhs 173 ret i1 %and 174} 175 176define i1 @test4_logical(i1 %a, i1 %b, i1 %c) { 177; CHECK-LABEL: @test4_logical( 178; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 179; CHECK-NEXT: [[LHS:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 180; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[LHS]], i1 [[WC]], i1 false 181; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i1 [[C:%.*]], i1 false 182; CHECK-NEXT: ret i1 [[AND]] 183; 184 %wc = call i1 @llvm.experimental.widenable.condition() 185 %lhs = select i1 %a, i1 %b, i1 false 186 %rhs = select i1 %wc, i1 %c, i1 false 187 %and = select i1 %lhs, i1 %rhs, i1 false 188 ret i1 %and 189} 190 191define i1 @test5(i1 %a, i1 %b) { 192; CHECK-LABEL: @test5( 193; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 194; CHECK-NEXT: ret i1 [[WC]] 195; 196 %wc = call i1 @llvm.experimental.widenable.condition() 197 %and = and i1 %wc, %wc 198 ret i1 %and 199} 200 201define i1 @test5_logical(i1 %a, i1 %b) { 202; CHECK-LABEL: @test5_logical( 203; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 204; CHECK-NEXT: ret i1 [[WC]] 205; 206 %wc = call i1 @llvm.experimental.widenable.condition() 207 %and = select i1 %wc, i1 %wc, i1 false 208 ret i1 %and 209} 210 211define i1 @test6(i1 %a, i1 %b) { 212; CHECK-LABEL: @test6( 213; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 214; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() 215; CHECK-NEXT: [[AND:%.*]] = and i1 [[WC]], [[WC2]] 216; CHECK-NEXT: ret i1 [[AND]] 217; 218 %wc = call i1 @llvm.experimental.widenable.condition() 219 %wc2 = call i1 @llvm.experimental.widenable.condition() 220 %and = and i1 %wc, %wc2 221 ret i1 %and 222} 223 224define i1 @test6_logical(i1 %a, i1 %b) { 225; CHECK-LABEL: @test6_logical( 226; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 227; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() 228; CHECK-NEXT: [[AND:%.*]] = select i1 [[WC]], i1 [[WC2]], i1 false 229; CHECK-NEXT: ret i1 [[AND]] 230; 231 %wc = call i1 @llvm.experimental.widenable.condition() 232 %wc2 = call i1 @llvm.experimental.widenable.condition() 233 %and = select i1 %wc, i1 %wc2, i1 false 234 ret i1 %and 235} 236 237define i1 @test7(i1 %a, i1 %b) { 238; CHECK-LABEL: @test7( 239; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 240; CHECK-NEXT: call void @use(i1 [[WC]]) 241; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() 242; CHECK-NEXT: [[AND:%.*]] = and i1 [[WC]], [[WC2]] 243; CHECK-NEXT: ret i1 [[AND]] 244; 245 %wc = call i1 @llvm.experimental.widenable.condition() 246 call void @use(i1 %wc) 247 %wc2 = call i1 @llvm.experimental.widenable.condition() 248 %and = and i1 %wc, %wc2 249 ret i1 %and 250} 251 252define i1 @test7_logical(i1 %a, i1 %b) { 253; CHECK-LABEL: @test7_logical( 254; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 255; CHECK-NEXT: call void @use(i1 [[WC]]) 256; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() 257; CHECK-NEXT: [[AND:%.*]] = select i1 [[WC]], i1 [[WC2]], i1 false 258; CHECK-NEXT: ret i1 [[AND]] 259; 260 %wc = call i1 @llvm.experimental.widenable.condition() 261 call void @use(i1 %wc) 262 %wc2 = call i1 @llvm.experimental.widenable.condition() 263 %and = select i1 %wc, i1 %wc2, i1 false 264 ret i1 %and 265} 266 267define i1 @test8(i1 %a, i1 %b) { 268; CHECK-LABEL: @test8( 269; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 270; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() 271; CHECK-NEXT: call void @use(i1 [[WC2]]) 272; CHECK-NEXT: [[AND:%.*]] = and i1 [[WC]], [[WC2]] 273; CHECK-NEXT: ret i1 [[AND]] 274; 275 %wc = call i1 @llvm.experimental.widenable.condition() 276 %wc2 = call i1 @llvm.experimental.widenable.condition() 277 call void @use(i1 %wc2) 278 %and = and i1 %wc, %wc2 279 ret i1 %and 280} 281 282define i1 @test8_logical(i1 %a, i1 %b) { 283; CHECK-LABEL: @test8_logical( 284; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 285; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() 286; CHECK-NEXT: call void @use(i1 [[WC2]]) 287; CHECK-NEXT: [[AND:%.*]] = select i1 [[WC]], i1 [[WC2]], i1 false 288; CHECK-NEXT: ret i1 [[AND]] 289; 290 %wc = call i1 @llvm.experimental.widenable.condition() 291 %wc2 = call i1 @llvm.experimental.widenable.condition() 292 call void @use(i1 %wc2) 293 %and = select i1 %wc, i1 %wc2, i1 false 294 ret i1 %and 295} 296 297 298declare void @use(i1) 299declare i1 @llvm.experimental.widenable.condition() 300