@@ -1047,8 +1047,8 @@ define i32 @test78(i1 %flag, ptr %x, ptr %y, ptr %z) {
1047
1047
; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4
1048
1048
; CHECK-NEXT: store i32 0, ptr [[Y:%.*]], align 4
1049
1049
; CHECK-NEXT: store i32 42, ptr [[Z:%.*]], align 4
1050
- ; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
1051
- ; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y]], align 4
1050
+ ; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4, !freeze_bits [[META0:![0-9]+]]
1051
+ ; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y]], align 4, !freeze_bits [[META0]]
1052
1052
; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]]
1053
1053
; CHECK-NEXT: ret i32 [[V]]
1054
1054
;
@@ -1066,8 +1066,8 @@ entry:
1066
1066
; fold the load completely away.
1067
1067
define i32 @test78_deref (i1 %flag , ptr dereferenceable (4 ) align 4 %x , ptr dereferenceable (4 ) align 4 %y , ptr %z ) nofree nosync {
1068
1068
; CHECK-LABEL: @test78_deref(
1069
- ; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
1070
- ; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y:%.*]], align 4
1069
+ ; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X:%.*]], align 4, !freeze_bits [[META0]]
1070
+ ; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y:%.*]], align 4, !freeze_bits [[META0]]
1071
1071
; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]]
1072
1072
; CHECK-NEXT: ret i32 [[V]]
1073
1073
;
@@ -1116,8 +1116,8 @@ define float @test79(i1 %flag, ptr %x, ptr %y, ptr %z) {
1116
1116
; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4
1117
1117
; CHECK-NEXT: store i32 0, ptr [[Y:%.*]], align 4
1118
1118
; CHECK-NEXT: store i32 42, ptr [[Z:%.*]], align 4
1119
- ; CHECK-NEXT: [[X_VAL:%.*]] = load float, ptr [[X]], align 4
1120
- ; CHECK-NEXT: [[Y_VAL:%.*]] = load float, ptr [[Y]], align 4
1119
+ ; CHECK-NEXT: [[X_VAL:%.*]] = load float, ptr [[X]], align 4, !freeze_bits [[META0]]
1120
+ ; CHECK-NEXT: [[Y_VAL:%.*]] = load float, ptr [[Y]], align 4, !freeze_bits [[META0]]
1121
1121
; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], float [[X_VAL]], float [[Y_VAL]]
1122
1122
; CHECK-NEXT: ret float [[V]]
1123
1123
;
@@ -1138,7 +1138,7 @@ define i32 @test80(i1 %flag) {
1138
1138
; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
1139
1139
; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]])
1140
1140
; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]])
1141
- ; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[X]], align 4
1141
+ ; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[X]], align 4, !freeze_bits [[META0]]
1142
1142
; CHECK-NEXT: store i32 [[T]], ptr [[Y]], align 4
1143
1143
; CHECK-NEXT: ret i32 [[T]]
1144
1144
;
@@ -1161,7 +1161,7 @@ define float @test81(i1 %flag) {
1161
1161
; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
1162
1162
; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]])
1163
1163
; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]])
1164
- ; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[X]], align 4
1164
+ ; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[X]], align 4, !freeze_bits [[META0]]
1165
1165
; CHECK-NEXT: store i32 [[T]], ptr [[Y]], align 4
1166
1166
; CHECK-NEXT: [[V:%.*]] = bitcast i32 [[T]] to float
1167
1167
; CHECK-NEXT: ret float [[V]]
@@ -1185,7 +1185,7 @@ define i32 @test82(i1 %flag) {
1185
1185
; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
1186
1186
; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]])
1187
1187
; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]])
1188
- ; CHECK-NEXT: [[T:%.*]] = load float, ptr [[X]], align 4
1188
+ ; CHECK-NEXT: [[T:%.*]] = load float, ptr [[X]], align 4, !freeze_bits [[META0]]
1189
1189
; CHECK-NEXT: store float [[T]], ptr [[Y]], align 4
1190
1190
; CHECK-NEXT: [[V:%.*]] = bitcast float [[T]] to i32
1191
1191
; CHECK-NEXT: ret i32 [[V]]
@@ -1212,7 +1212,7 @@ define ptr @test83(i1 %flag) {
1212
1212
; CHECK-NEXT: [[Y:%.*]] = alloca i64, align 8
1213
1213
; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[X]])
1214
1214
; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[Y]])
1215
- ; CHECK-NEXT: [[T:%.*]] = load i64, ptr [[X]], align 4
1215
+ ; CHECK-NEXT: [[T:%.*]] = load i64, ptr [[X]], align 4, !freeze_bits [[META0]]
1216
1216
; CHECK-NEXT: store i64 [[T]], ptr [[Y]], align 4
1217
1217
; CHECK-NEXT: [[V:%.*]] = inttoptr i64 [[T]] to ptr
1218
1218
; CHECK-NEXT: ret ptr [[V]]
@@ -1236,7 +1236,7 @@ define i64 @test84(i1 %flag) {
1236
1236
; CHECK-NEXT: [[Y:%.*]] = alloca i64, align 8
1237
1237
; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[X]])
1238
1238
; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[Y]])
1239
- ; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[X]], align 8
1239
+ ; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[X]], align 8, !freeze_bits [[META0]]
1240
1240
; CHECK-NEXT: store ptr [[T]], ptr [[Y]], align 8
1241
1241
; CHECK-NEXT: [[V:%.*]] = ptrtoint ptr [[T]] to i64
1242
1242
; CHECK-NEXT: ret i64 [[V]]
@@ -1263,8 +1263,8 @@ define ptr @test85(i1 %flag) {
1263
1263
; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[Y]])
1264
1264
; CHECK-NEXT: [[T:%.*]] = load i128, ptr [[X]], align 4
1265
1265
; CHECK-NEXT: store i128 [[T]], ptr [[Y]], align 4
1266
- ; CHECK-NEXT: [[X_VAL:%.*]] = load ptr, ptr [[X]], align 8
1267
- ; CHECK-NEXT: [[Y_VAL:%.*]] = load ptr, ptr [[Y]], align 8
1266
+ ; CHECK-NEXT: [[X_VAL:%.*]] = load ptr, ptr [[X]], align 8, !freeze_bits [[META0]]
1267
+ ; CHECK-NEXT: [[Y_VAL:%.*]] = load ptr, ptr [[Y]], align 8, !freeze_bits [[META0]]
1268
1268
; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], ptr [[X_VAL]], ptr [[Y_VAL]]
1269
1269
; CHECK-NEXT: ret ptr [[V]]
1270
1270
;
@@ -1290,8 +1290,8 @@ define i128 @test86(i1 %flag) {
1290
1290
; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[Y]])
1291
1291
; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[X]], align 8
1292
1292
; CHECK-NEXT: store ptr [[T]], ptr [[Y]], align 8
1293
- ; CHECK-NEXT: [[X_VAL:%.*]] = load i128, ptr [[X]], align 4
1294
- ; CHECK-NEXT: [[Y_VAL:%.*]] = load i128, ptr [[Y]], align 4
1293
+ ; CHECK-NEXT: [[X_VAL:%.*]] = load i128, ptr [[X]], align 4, !freeze_bits [[META0]]
1294
+ ; CHECK-NEXT: [[Y_VAL:%.*]] = load i128, ptr [[Y]], align 4, !freeze_bits [[META0]]
1295
1295
; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i128 [[X_VAL]], i128 [[Y_VAL]]
1296
1296
; CHECK-NEXT: ret i128 [[V]]
1297
1297
;
@@ -4676,3 +4676,245 @@ define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {
4676
4676
%sel = select i1 %x , i8 0 , i8 %shl.fr
4677
4677
ret i8 %sel
4678
4678
}
4679
+
4680
+ define i8 @select_knownbits_simplify (i8 noundef %x ) {
4681
+ ; CHECK-LABEL: @select_knownbits_simplify(
4682
+ ; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4683
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4684
+ ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
4685
+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
4686
+ ; CHECK-NEXT: ret i8 [[RES]]
4687
+ ;
4688
+ %x.lo = and i8 %x , 1
4689
+ %cmp = icmp eq i8 %x.lo , 0
4690
+ %and = and i8 %x , -2
4691
+ %res = select i1 %cmp , i8 %and , i8 0
4692
+ ret i8 %res
4693
+ }
4694
+
4695
+ define i8 @select_knownbits_simplify_nested (i8 noundef %x ) {
4696
+ ; CHECK-LABEL: @select_knownbits_simplify_nested(
4697
+ ; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4698
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4699
+ ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
4700
+ ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[AND]], [[AND]]
4701
+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 0
4702
+ ; CHECK-NEXT: ret i8 [[RES]]
4703
+ ;
4704
+ %x.lo = and i8 %x , 1
4705
+ %cmp = icmp eq i8 %x.lo , 0
4706
+ %and = and i8 %x , -2
4707
+ %mul = mul i8 %and , %and
4708
+ %res = select i1 %cmp , i8 %mul , i8 0
4709
+ ret i8 %res
4710
+ }
4711
+
4712
+ define i8 @select_knownbits_simplify_missing_noundef (i8 %x ) {
4713
+ ; CHECK-LABEL: @select_knownbits_simplify_missing_noundef(
4714
+ ; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1
4715
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
4716
+ ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
4717
+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
4718
+ ; CHECK-NEXT: ret i8 [[RES]]
4719
+ ;
4720
+ %x.lo = and i8 %x , 1
4721
+ %cmp = icmp eq i8 %x.lo , 0
4722
+ %and = and i8 %x , -2
4723
+ %res = select i1 %cmp , i8 %and , i8 0
4724
+ ret i8 %res
4725
+ }
4726
+
4727
+ @g_ext = external global i8
4728
+
4729
+ ; Make sure we don't replace %ptr with @g_ext, which may cause the load to trigger UB.
4730
+ define i32 @pr99436 (ptr align 4 dereferenceable (4 ) %ptr ) {
4731
+ ; CHECK-LABEL: @pr99436(
4732
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[PTR:%.*]], @g_ext
4733
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr @g_ext, align 4
4734
+ ; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0
4735
+ ; CHECK-NEXT: ret i32 [[RET]]
4736
+ ;
4737
+ %cmp = icmp eq ptr %ptr , @g_ext
4738
+ %val = load i32 , ptr %ptr , align 4
4739
+ %ret = select i1 %cmp , i32 %val , i32 0
4740
+ ret i32 %ret
4741
+ }
4742
+
4743
+ define i8 @sel_trunc_simplify (i1 %c , i8 %x , i16 %y ) {
4744
+ ; CHECK-LABEL: @sel_trunc_simplify(
4745
+ ; CHECK-NEXT: [[X_EXT:%.*]] = zext i8 [[X:%.*]] to i16
4746
+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i16 [[X_EXT]], i16 [[Y:%.*]]
4747
+ ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[SEL]] to i8
4748
+ ; CHECK-NEXT: ret i8 [[TRUNC]]
4749
+ ;
4750
+ %x.ext = zext i8 %x to i16
4751
+ %sel = select i1 %c , i16 %x.ext , i16 %y
4752
+ %trunc = trunc i16 %sel to i8
4753
+ ret i8 %trunc
4754
+ }
4755
+
4756
+ define i32 @sel_umin_simplify (i1 %c , i32 %x , i16 %y ) {
4757
+ ; CHECK-LABEL: @sel_umin_simplify(
4758
+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 0
4759
+ ; CHECK-NEXT: [[Y_EXT:%.*]] = zext i16 [[Y:%.*]] to i32
4760
+ ; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.umin.i32(i32 [[SEL]], i32 [[Y_EXT]])
4761
+ ; CHECK-NEXT: ret i32 [[RES]]
4762
+ ;
4763
+ %sel = select i1 %c , i32 %x , i32 0
4764
+ %y.ext = zext i16 %y to i32
4765
+ %res = call i32 @llvm.umin.i32 (i32 %sel , i32 %y.ext )
4766
+ ret i32 %res
4767
+ }
4768
+
4769
+ define i32 @sel_extractvalue_simplify (i1 %c , { i32 , i32 } %agg1 , i32 %x , i32 %y ) {
4770
+ ; CHECK-LABEL: @sel_extractvalue_simplify(
4771
+ ; CHECK-NEXT: [[AGG2_0:%.*]] = insertvalue { i32, i32 } poison, i32 [[X:%.*]], 0
4772
+ ; CHECK-NEXT: [[AGG2_1:%.*]] = insertvalue { i32, i32 } [[AGG2_0]], i32 [[Y:%.*]], 1
4773
+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], { i32, i32 } [[AGG1:%.*]], { i32, i32 } [[AGG2_1]]
4774
+ ; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i32 } [[SEL]], 1
4775
+ ; CHECK-NEXT: ret i32 [[RES]]
4776
+ ;
4777
+ %agg2.0 = insertvalue { i32 , i32 } poison, i32 %x , 0
4778
+ %agg2.1 = insertvalue { i32 , i32 } %agg2.0 , i32 %y , 1
4779
+ %sel = select i1 %c , { i32 , i32 } %agg1 , { i32 , i32 } %agg2.1
4780
+ %res = extractvalue { i32 , i32 } %sel , 1
4781
+ ret i32 %res
4782
+ }
4783
+
4784
+ define i1 @replace_select_cond_true (i1 %cond , i32 %v1 , i32 %v2 , i32 %v3 ) {
4785
+ ; CHECK-LABEL: @replace_select_cond_true(
4786
+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[V1:%.*]], i32 [[V3:%.*]]
4787
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SEL]], [[V2:%.*]]
4788
+ ; CHECK-NEXT: [[AND:%.*]] = select i1 [[COND]], i1 [[CMP]], i1 false
4789
+ ; CHECK-NEXT: ret i1 [[AND]]
4790
+ ;
4791
+ %sel = select i1 %cond , i32 %v1 , i32 %v3
4792
+ %cmp = icmp eq i32 %sel , %v2
4793
+ %and = select i1 %cond , i1 %cmp , i1 false
4794
+ ret i1 %and
4795
+ }
4796
+
4797
+ define i1 @replace_select_cond_false (i1 %cond , i32 %v1 , i32 %v2 , i32 %v3 ) {
4798
+ ; CHECK-LABEL: @replace_select_cond_false(
4799
+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[V1:%.*]], i32 [[V3:%.*]]
4800
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SEL]], [[V2:%.*]]
4801
+ ; CHECK-NEXT: [[OR:%.*]] = select i1 [[COND]], i1 true, i1 [[CMP]]
4802
+ ; CHECK-NEXT: ret i1 [[OR]]
4803
+ ;
4804
+ %sel = select i1 %cond , i32 %v1 , i32 %v3
4805
+ %cmp = icmp eq i32 %sel , %v2
4806
+ %or = select i1 %cond , i1 true , i1 %cmp
4807
+ ret i1 %or
4808
+ }
4809
+
4810
+ define i32 @replace_and_cond (i1 %cond1 , i1 %cond2 ) {
4811
+ ; CHECK-LABEL: @replace_and_cond(
4812
+ ; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
4813
+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
4814
+ ; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
4815
+ ; CHECK-NEXT: ret i32 [[MUX]]
4816
+ ;
4817
+ %and = and i1 %cond1 , %cond2
4818
+ %sel = select i1 %and , i32 3 , i32 2
4819
+ %mux = select i1 %cond1 , i32 %sel , i32 1
4820
+ ret i32 %mux
4821
+ }
4822
+
4823
+ define <2 x i32 > @replace_and_cond_vec (<2 x i1 > %cond1 , <2 x i1 > %cond2 ) {
4824
+ ; CHECK-LABEL: @replace_and_cond_vec(
4825
+ ; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[COND1:%.*]], [[COND2:%.*]]
4826
+ ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[AND]], <2 x i32> <i32 3, i32 3>, <2 x i32> <i32 2, i32 2>
4827
+ ; CHECK-NEXT: [[MUX:%.*]] = select <2 x i1> [[COND1]], <2 x i32> [[SEL]], <2 x i32> <i32 1, i32 1>
4828
+ ; CHECK-NEXT: ret <2 x i32> [[MUX]]
4829
+ ;
4830
+ %and = and <2 x i1 > %cond1 , %cond2
4831
+ %sel = select <2 x i1 > %and , <2 x i32 > splat(i32 3 ), <2 x i32 > splat(i32 2 )
4832
+ %mux = select <2 x i1 > %cond1 , <2 x i32 > %sel , <2 x i32 > splat(i32 1 )
4833
+ ret <2 x i32 > %mux
4834
+ }
4835
+
4836
+ ; TODO: We can still replace the use of %and with %cond2
4837
+ define i32 @replace_and_cond_multiuse1 (i1 %cond1 , i1 %cond2 ) {
4838
+ ; CHECK-LABEL: @replace_and_cond_multiuse1(
4839
+ ; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
4840
+ ; CHECK-NEXT: call void @use(i1 [[AND]])
4841
+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
4842
+ ; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
4843
+ ; CHECK-NEXT: ret i32 [[MUX]]
4844
+ ;
4845
+ %and = and i1 %cond1 , %cond2
4846
+ call void @use (i1 %and )
4847
+ %sel = select i1 %and , i32 3 , i32 2
4848
+ %mux = select i1 %cond1 , i32 %sel , i32 1
4849
+ ret i32 %mux
4850
+ }
4851
+
4852
+ define i32 @replace_and_cond_multiuse2 (i1 %cond1 , i1 %cond2 ) {
4853
+ ; CHECK-LABEL: @replace_and_cond_multiuse2(
4854
+ ; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]]
4855
+ ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2
4856
+ ; CHECK-NEXT: call void @use32(i32 [[SEL]])
4857
+ ; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1
4858
+ ; CHECK-NEXT: ret i32 [[MUX]]
4859
+ ;
4860
+ %and = and i1 %cond1 , %cond2
4861
+ %sel = select i1 %and , i32 3 , i32 2
4862
+ call void @use32 (i32 %sel )
4863
+ %mux = select i1 %cond1 , i32 %sel , i32 1
4864
+ ret i32 %mux
4865
+ }
4866
+
4867
+ define i32 @src_simplify_2x_at_once_and (i32 %x , i32 %y ) {
4868
+ ; CHECK-LABEL: @src_simplify_2x_at_once_and(
4869
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
4870
+ ; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], -1
4871
+ ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]]
4872
+ ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]
4873
+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[SUB]], i32 [[XOR]]
4874
+ ; CHECK-NEXT: ret i32 [[COND]]
4875
+ ;
4876
+ %and = and i32 %x , %y
4877
+ %and0 = icmp eq i32 %and , -1
4878
+ %sub = sub i32 %x , %y
4879
+ %xor = xor i32 %x , %y
4880
+ %cond = select i1 %and0 , i32 %sub , i32 %xor
4881
+ ret i32 %cond
4882
+ }
4883
+
4884
+ define void @select_freeze_poison_parameter (ptr noundef %addr.src , ptr %addr.tgt , i1 %cond ) {
4885
+ ; CHECK-LABEL: @select_freeze_poison_parameter(
4886
+ ; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], ptr [[ADDR_SRC:%.*]], ptr null
4887
+ ; CHECK-NEXT: store ptr [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 8
4888
+ ; CHECK-NEXT: ret void
4889
+ ;
4890
+ %freeze = freeze ptr poison
4891
+ %select.addr = select i1 %cond , ptr %addr.src , ptr %freeze
4892
+ store ptr %select.addr , ptr %addr.tgt
4893
+ ret void
4894
+ }
4895
+
4896
+ @glb = global ptr null
4897
+
4898
+ define void @select_freeze_poison_global (ptr %addr.tgt , i1 %cond ) {
4899
+ ; CHECK-LABEL: @select_freeze_poison_global(
4900
+ ; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], ptr @glb, ptr null
4901
+ ; CHECK-NEXT: store ptr [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 8
4902
+ ; CHECK-NEXT: ret void
4903
+ ;
4904
+ %freeze = freeze ptr poison
4905
+ %select.addr = select i1 %cond , ptr @glb , ptr %freeze
4906
+ store ptr %select.addr , ptr %addr.tgt
4907
+ ret void
4908
+ }
4909
+
4910
+ define void @select_freeze_poison_constant (ptr %addr.tgt , i1 %cond ) {
4911
+ ; CHECK-LABEL: @select_freeze_poison_constant(
4912
+ ; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], i32 72, i32 0
4913
+ ; CHECK-NEXT: store i32 [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 4
4914
+ ; CHECK-NEXT: ret void
4915
+ ;
4916
+ %freeze = freeze i32 poison
4917
+ %select.addr = select i1 %cond , i32 72 , i32 %freeze
4918
+ store i32 %select.addr , ptr %addr.tgt
4919
+ ret void
4920
+ }
0 commit comments