1; RUN: llc -mtriple=aarch64-linux-gnu -o - %s | FileCheck %s --check-prefixes CHECK,CHECK-SDAG 2; RUN: llc -global-isel -mtriple=aarch64-linux-gnu -o - %s | FileCheck %s --check-prefixes CHECK,CHECK-GISEL 3%big = type i32 4 5@var = dso_local global %big 0 6 7; AAPCS: low 8 bits of %in (== w0) will be either 0 or 1. Need to extend to 8; 32-bits. 9define dso_local void @consume_i1_arg(i1 %in) { 10; CHECK-LABEL: consume_i1_arg: 11; CHECK: and [[BOOL32:w[0-9]+]], w0, #{{0x1|0xff}} 12; CHECK: str [[BOOL32]], [{{x[0-9]+}}, :lo12:var] 13 %val = zext i1 %in to %big 14 store %big %val, ptr @var 15 ret void 16} 17 18; AAPCS: low 8 bits of %val1 (== w0) will be either 0 or 1. Need to extend to 19; 32-bits (doesn't really matter if it's from 1 or 8 bits). 20define dso_local void @consume_i1_ret() { 21; CHECK-LABEL: consume_i1_ret: 22; CHECK: bl produce_i1_ret 23; CHECK: and [[BOOL32:w[0-9]+]], w0, #{{0x1|0xff}} 24; CHECK: str [[BOOL32]], [{{x[0-9]+}}, :lo12:var] 25 %val1 = call i1 @produce_i1_ret() 26 %val = zext i1 %val1 to %big 27 store %big %val, ptr @var 28 ret void 29} 30 31; AAPCS: low 8 bits of w0 must be either 0 or 1. Need to mask them off. 32define dso_local i1 @produce_i1_ret() { 33; CHECK-LABEL: produce_i1_ret: 34; CHECK: ldr [[VAR32:w[0-9]+]], [{{x[0-9]+}}, :lo12:var] 35; CHECK: and w0, [[VAR32]], #{{0x1|0xff}} 36 %val = load %big, ptr @var 37 %val1 = trunc %big %val to i1 38 ret i1 %val1 39} 40 41define dso_local void @produce_i1_arg() { 42; CHECK-LABEL: produce_i1_arg: 43; CHECK: ldr [[VAR32:w[0-9]+]], [{{x[0-9]+}}, :lo12:var] 44; CHECK: and w0, [[VAR32]], #{{0x1|0xff}} 45; CHECK: bl consume_i1_arg 46 %val = load %big, ptr @var 47 %val1 = trunc %big %val to i1 48 call void @consume_i1_arg(i1 %val1) 49 ret void 50} 51 52 53define dso_local void @forward_i1_arg1(i1 %in) { 54; CHECK-LABEL: forward_i1_arg1: 55; CHECK-NOT: and 56; CHECK: bl consume_i1_arg 57 call void @consume_i1_arg(i1 %in) 58 ret void 59} 60 61define dso_local void @forward_i1_arg2(i1 %in, i1 %cond) { 62; CHECK-LABEL: forward_i1_arg2: 63; 64; The optimization in SelectionDAG currently fails to recognize that 65; %in is already zero-extended to i8 if the call is not in the entry 66; block. 67; 68; CHECK-SDAG: and 69; CHECK-GISEL-NOT: and 70; 71; CHECK: bl consume_i1_arg 72 br i1 %cond, label %true, label %false 73true: 74 call void @consume_i1_arg(i1 %in) 75 ret void 76 77false: 78 ret void 79} 80 81;define zeroext i1 @foo(i8 %in) { 82; %val = trunc i8 %in to i1 83; ret i1 %val 84;} 85