1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -constraint-elimination -S %s | FileCheck %s 3 4define i1 @bitcast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) { 5; 6; CHECK-LABEL: @bitcast_and_cmp( 7; CHECK-NEXT: check.0.min: 8; CHECK-NEXT: [[SRC_C:%.*]] = bitcast i32* [[SRC:%.*]] to i8* 9; CHECK-NEXT: [[MIN_C:%.*]] = bitcast i32* [[MIN:%.*]] to i8* 10; CHECK-NEXT: [[MAX_C:%.*]] = bitcast i32* [[MAX:%.*]] to i16* 11; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3 12; CHECK-NEXT: [[GEP_3_C:%.*]] = bitcast i32* [[GEP_3]] to i16* 13; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult i8* [[SRC_C]], [[MIN_C]] 14; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt i16* [[GEP_3_C]], [[MAX_C]] 15; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]] 16; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]] 17; CHECK: trap: 18; CHECK-NEXT: ret i1 false 19; CHECK: checks: 20; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]] 21; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]] 22; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]] 23; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 24; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]] 25; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]] 26; CHECK-NEXT: [[RES_2:%.*]] = xor i1 false, true 27; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2 28; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]] 29; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]] 30; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true 31; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4 32; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]] 33; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]] 34; CHECK-NEXT: [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]] 35; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]] 36; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]] 37; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]] 38; CHECK-NEXT: ret i1 [[RES_7]] 39; 40check.0.min: 41 %src.c = bitcast i32* %src to i8* 42 %min.c = bitcast i32* %min to i8* 43 %max.c = bitcast i32* %max to i16* 44 45 %gep.3 = getelementptr inbounds i32, i32* %src, i64 3 46 %gep.3.c = bitcast i32* %gep.3 to i16* 47 %c.min.0 = icmp ult i8* %src.c, %min.c 48 %c.max.3 = icmp ugt i16* %gep.3.c, %max.c 49 50 %or = or i1 %c.min.0, %c.max.3 51 br i1 %or, label %trap, label %checks 52 53trap: 54 ret i1 0 55 56checks: 57 %c.3.min = icmp ult i32* %gep.3, %min 58 %c.3.max = icmp ult i32* %gep.3, %max 59 %res.1 = xor i1 %c.3.min, %c.3.max 60 61 %gep.1 = getelementptr inbounds i32, i32* %src, i64 1 62 %c.1.min = icmp ult i32* %gep.1, %min 63 %c.1.max = icmp ult i32* %gep.1, %max 64 %res.2 = xor i1 %c.1.min, %c.1.max 65 66 %gep.2 = getelementptr inbounds i32, i32* %src, i64 2 67 %c.2.min = icmp ult i32* %gep.2, %min 68 %c.2.max = icmp ult i32* %gep.2, %max 69 %res.3 = xor i1 %c.2.min, %c.2.max 70 71 %gep.4 = getelementptr inbounds i32, i32* %src, i64 4 72 %c.4.min = icmp ult i32* %gep.4, %min 73 %c.4.max = icmp ult i32* %gep.4, %max 74 %res.4 = xor i1 %c.4.min, %c.4.max 75 76 %res.5 = xor i1 %res.1, %res.2 77 %res.6 = xor i1 %res.5, %res.3 78 %res.7 = xor i1 %res.6, %res.4 79 80 ret i1 %res.7 81} 82